// Copyright (c) 2013, 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;

/**
 * Model-Driven Views (MDV)'s native features enables a wide-range of use cases,
 * but (by design) don't attempt to implement a wide array of specialized
 * behaviors.
 *
 * Enabling these features in MDV is a matter of implementing and registering an
 * MDV Custom Syntax. A Custom Syntax is an object which contains one or more
 * delegation functions which implement specialized behavior. This object is
 * registered with MDV via [Element.bindingDelegate]:
 *
 *
 * HTML:
 *     <template bind>
 *       {{ What!Ever('crazy')->thing^^^I+Want(data) }}
 *     </template>
 *
 * Dart:
 *     class MySyntax extends BindingDelegate {
 *       getBinding(model, path, name, node) {
 *         // The magic happens here!
 *       }
 *     }
 *     ...
 *     query('template').bindingDelegate = new MySyntax();
 *     query('template').model = new MyModel();
 *
 * See <https://github.com/polymer-project/mdv/blob/master/docs/syntax.md> for
 * more information about Custom Syntax.
 */
// TODO(jmesserly): move this type to the MDV package? Two issues: we'd lose
// type annotation on [Element.bindingDelegate], and "mdv" is normally imported
// with a prefix.
@Experimental()
abstract class BindingDelegate {
  /**
   * This syntax method allows for a custom interpretation of the contents of
   * mustaches (`{{` ... `}}`).
   *
   * When a template is inserting an instance, it will invoke this method for
   * each mustache which is encountered. The function is invoked with four
   * arguments:
   *
   * - [model]: The data context for which this instance is being created.
   * - [path]: The text contents (trimmed of outer whitespace) of the mustache.
   * - [name]: The context in which the mustache occurs. Within element
   *   attributes, this will be the name of the attribute. Within text,
   *   this will be 'text'.
   * - [node]: A reference to the node to which this binding will be created.
   *
   * If the method wishes to handle binding, it is required to return an object
   * which has at least a `value` property that can be observed. If it does,
   * then MDV will call [Node.bind on the node:
   *
   *     node.bind(name, retval, 'value');
   *
   * If the 'getBinding' does not wish to override the binding, it should return
   * null.
   */
  // TODO(jmesserly): I had to remove type annotations from "name" and "node"
  // Normally they are String and Node respectively. But sometimes it will pass
  // (int name, CompoundBinding node). That seems very confusing; we may want
  // to change this API.
  getBinding(model, String path, name, node) => null;

  /**
   * This syntax method allows a syntax to provide an alterate model than the
   * one the template would otherwise use when producing an instance.
   *
   * When a template is about to create an instance, it will invoke this method
   * The function is invoked with two arguments:
   *
   * - [template]: The template element which is about to create and insert an
   *   instance.
   * - [model]: The data context for which this instance is being created.
   *
   * The template element will always use the return value of `getInstanceModel`
   * as the model for the new instance. If the syntax does not wish to override
   * the value, it should simply return the `model` value it was passed.
   */
  getInstanceModel(Element template, model) => model;
}

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

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


  /**
   * The MDV package, if available.
   *
   * This can be used to initialize MDV support via:
   *
   *     import 'dart:html';
   *     import 'package:mdv/mdv.dart' as mdv;
   *     main() {
   *       mdv.initialize();
   *     }
   */
  static Function mdvPackage = (node) {
    throw new UnsupportedError("The MDV package is not available. "
        "You can enable it with `import 'package:mdv/mdv.dart' as mdv;` and "
        "`mdv.initialize()`");
  };

  /**
   * 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;

    _injectStylesheet();

    var templateElement = template;
    templateElement._templateIsDecorated = true;
    var isNative = templateElement is TemplateElement;
    var bootstrapContents = isNative;
    var liftContents = !isNative;
    var liftRoot = false;

    if (!isNative && templateElement._isAttributeTemplate) {
      if (instanceRef != null) {
        // TODO(jmesserly): this is just an assert in MDV.
        throw new ArgumentError('instanceRef should not be supplied for '
            'attribute templates.');
      }
      templateElement = _extractTemplateFromAttributeTemplate(template);
      templateElement._templateIsDecorated = true;
      isNative = templateElement is TemplateElement;
      liftRoot = true;
     }

    if (!isNative) {
      var doc = _getTemplateContentsOwner(templateElement.document);
      templateElement._templateContent = doc.createDocumentFragment();
    }

    if (instanceRef != null) {
      // template is contained within an instance, its direct content must be
      // empty
      templateElement._templateInstanceRef = instanceRef;
    } else if (liftContents) {
      _liftNonNativeChildrenIntoContent(templateElement, template, liftRoot);
    } else if (bootstrapContents) {
      bootstrap(templateElement.content);
    }

    return true;
  }

  // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner
  static Document _getTemplateContentsOwner(HtmlDocument doc) {
    if (doc.window == null) {
      return doc;
    }
    var d = doc._templateContentsOwner;
    if (d == null) {
      // TODO(arv): This should either be a Document or HTMLDocument depending
      // on doc.
      d = doc.implementation.createHtmlDocument('');
      while (d.lastChild != null) {
        d.lastChild.remove();
      }
      doc._templateContentsOwner = d;
    }
    return d;
  }

  // For non-template browsers, the parser will disallow <template> in certain
  // locations, so we allow "attribute templates" which combine the template
  // element with the top-level container node of the content, e.g.
  //
  //   <tr template repeat="{{ foo }}"" class="bar"><td>Bar</td></tr>
  //
  // becomes
  //
  //   <template repeat="{{ foo }}">
  //   + #document-fragment
  //     + <tr class="bar">
  //       + <td>Bar</td>
  //
  static Element _extractTemplateFromAttributeTemplate(Element el) {
    var template = el.document.createElement('template');
    el.parentNode.insertBefore(template, el);

    for (var name in el.attributes.keys.toList()) {
      switch (name) {
        case 'template':
          el.attributes.remove(name);
          break;
        case 'repeat':
        case 'bind':
        case 'ref':
          template.attributes[name] = el.attributes.remove(name);
          break;
      }
    }

    return template;
  }

  static void _liftNonNativeChildrenIntoContent(Element template, Element el,
      bool useRoot) {

    var content = template.content;
    if (useRoot) {
      content.append(el);
      return;
    }

    var child;
    while ((child = el.firstChild) != null) {
      content.append(child);
    }
  }

  /**
   * 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) {
    void _bootstrap(template) {
      if (!TemplateElement.decorate(template)) {
        bootstrap(template.content);
      }
    }

    // Need to do this first as the contents may get lifted if |node| is
    // template.
    // TODO(jmesserly): content is DocumentFragment or Element
    var descendents = 
        (content as dynamic).querySelectorAll(_allTemplatesSelectors);
    if (content is Element && (content as Element).isTemplate) {
      _bootstrap(content);
    }

    descendents.forEach(_bootstrap);
  }

  static final String _allTemplatesSelectors =
      'template, option[template], optgroup[template], ' +
      Element._TABLE_TAGS.keys.map((k) => "$k[template]").join(", ");

  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);
  }

  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
