// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

part of $LIBRARYNAME;

@Experimental
$(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
$!MEMBERS

  // For real TemplateElement use the actual DOM .content field instead of
  // our polyfilled expando.
  @Experimental
  DocumentFragment get content => $dom_content;

  static StreamController<DocumentFragment> _instanceCreated;

  /**
   * *Warning*: This is an implementation helper for Model-Driven Views and
   * should not be used in your code.
   *
   * This event is fired whenever a template is instantiated via
   * [createInstance].
   */
  // TODO(rafaelw): This is a hack, and is neccesary for the polyfill
  // because custom elements are not upgraded during clone()
  @Experimental
  static Stream<DocumentFragment> get instanceCreated {
    if (_instanceCreated == null) {
      _instanceCreated = new StreamController<DocumentFragment>(sync: true);
    }
    return _instanceCreated.stream;
  }

  /**
   * Ensures proper API and content model for template elements.
   *
   * [instanceRef] can be used to set the [Element.ref] property of [template],
   * and use the ref's content will be used as source when createInstance() is
   * invoked.
   *
   * Returns true if this template was just decorated, or false if it was
   * already decorated.
   */
  @Experimental
  static bool decorate(Element template, [Element instanceRef]) {
    // == true check because it starts as a null field.
    if (template._templateIsDecorated == true) return false;

    template._templateIsDecorated = true;

    _injectStylesheet();

    // Create content
    if (template is! TemplateElement) {
      var doc = _Bindings._getTemplateContentsOwner(template.document);
      template._templateContent = doc.createDocumentFragment();
    }

    if (instanceRef != null) {
      template._templateInstanceRef = instanceRef;
      return true; // content is empty.
    }

    if (template is TemplateElement) {
      bootstrap(template.content);
    } else {
      _Bindings._liftNonNativeChildrenIntoContent(template);
    }

    return true;
  }

  /**
   * This used to decorate recursively all templates from a given node.
   *
   * By default [decorate] will be called on templates lazily when certain
   * properties such as [model] are accessed, but it can be run eagerly to
   * decorate an entire tree recursively.
   */
  // TODO(rafaelw): Review whether this is the right public API.
  @Experimental
  static void bootstrap(Node content) {
    _Bindings._bootstrapTemplatesRecursivelyFrom(content);
  }

  /**
   * Binds all mustaches recursively starting from the [root] node.
   *
   * Note: this is not an official Model-Driven-Views API; it is intended to
   * support binding the [ShadowRoot]'s content to a model.
   */
  // TODO(jmesserly): this is needed to avoid two <template> nodes when using
  // bindings in a custom element's template. See also:
  // https://github.com/polymer-project/polymer/blob/master/src/bindMDV.js#L68
  // Called from:
  // https://github.com/polymer-project/polymer/blob/master/src/register.js#L99
  @Experimental
  static void bindModel(Node root, model, [CustomBindingSyntax syntax]) {
    _Bindings._addBindings(root, model, syntax);
  }

  static bool _initStyles;

  static void _injectStylesheet() {
    if (_initStyles == true) return;
    _initStyles = true;

    var style = new StyleElement();
    style.text = r'''
template,
thead[template],
tbody[template],
tfoot[template],
th[template],
tr[template],
td[template],
caption[template],
colgroup[template],
col[template],
option[template] {
  display: none;
}''';
    document.head.append(style);
  }

  /**
   * A mapping of names to Custom Syntax objects. See [CustomBindingSyntax] for
   * more information.
   */
  @Experimental
  static Map<String, CustomBindingSyntax> syntax = {};
}
