| Index: tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
|
| diff --git a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
|
| index 4a7c784bed3d6981bfc53d863aa0e3a813cdc28a..98c71992da0ab64a04e8c670bd431acda27b628c 100644
|
| --- a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
|
| +++ b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
|
| @@ -6,291 +6,10 @@
|
|
|
| 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.ownerDocument);
|
| - 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.ownerDocument.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.
|
| *
|
|
|