Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Unified Diff: template_binding/lib/src/template.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « template_binding/lib/src/node.dart ('k') | template_binding/lib/src/template_iterator.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: template_binding/lib/src/template.dart
diff --git a/template_binding/lib/src/template.dart b/template_binding/lib/src/template.dart
deleted file mode 100644
index 2dc7ac5613075f119c77feec0344f2e923027764..0000000000000000000000000000000000000000
--- a/template_binding/lib/src/template.dart
+++ /dev/null
@@ -1,536 +0,0 @@
-// 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.
-
-part of template_binding;
-
-/** Extensions to [Element]s that behave as templates. */
-class TemplateBindExtension extends NodeBindExtension {
- var _model;
- BindingDelegate _bindingDelegate;
- _TemplateIterator _iterator;
- bool _setModelScheduled = false;
-
- Element _templateInstanceRef;
-
- // Note: only used if `this is! TemplateElement`
- DocumentFragment _content;
- bool _templateIsDecorated;
-
- HtmlDocument _stagingDocument;
-
- _InstanceBindingMap _bindingMap;
-
- Node _refContent;
-
- TemplateBindExtension._(Element node) : super._(node);
-
- Element get _node => super._node;
-
- TemplateBindExtension get _self => _node is TemplateBindExtension
- ? _node : this;
-
- Bindable bind(String name, value, {bool oneTime: false}) {
- if (name != 'ref') return super.bind(name, value, oneTime: oneTime);
-
- var ref = oneTime ? value : value.open((ref) {
- _node.attributes['ref'] = ref;
- _refChanged();
- });
-
- _node.attributes['ref'] = ref;
- _refChanged();
- if (oneTime) return null;
-
- if (bindings == null) bindings = {};
- return bindings['ref'] = value;
- }
-
- _TemplateIterator _processBindingDirectives(_TemplateBindingMap directives) {
- if (_iterator != null) _iterator._closeDependencies();
-
- if (directives._if == null &&
- directives._bind == null &&
- directives._repeat == null) {
-
- if (_iterator != null) {
- _iterator.close();
- _iterator = null;
- }
- return null;
- }
-
- if (_iterator == null) {
- _iterator = new _TemplateIterator(this);
- }
-
- _iterator._updateDependencies(directives, model);
-
- _templateObserver.observe(_node,
- attributes: true, attributeFilter: ['ref']);
-
- return _iterator;
- }
-
- /**
- * Creates an instance of the template, using the provided [model] and
- * optional binding [delegate].
- *
- * If [instanceBindings] is supplied, each [Bindable] in the returned
- * instance will be added to the list. This makes it easy to close all of the
- * bindings without walking the tree. This is not normally necessary, but is
- * used internally by the system.
- */
- DocumentFragment createInstance([model, BindingDelegate delegate]) {
- if (delegate == null) delegate = _bindingDelegate;
- if (_refContent == null) _refContent = templateBind(_ref).content;
-
- var content = _refContent;
- if (content.firstChild == null) return _emptyInstance;
-
- final map = _getInstanceBindingMap(content, delegate);
- final staging = _getTemplateStagingDocument();
- final instance = _stagingDocument.createDocumentFragment();
-
- final instanceExt = new _InstanceExtension();
- _instanceExtension[instance] = instanceExt
- .._templateCreator = _node
- .._protoContent = content;
-
- final instanceRecord = new TemplateInstance(model);
- nodeBindFallback(instance)._templateInstance = instanceRecord;
-
- var i = 0;
- bool collectTerminator = false;
- for (var c = content.firstChild; c != null; c = c.nextNode, i++) {
- // The terminator of the instance is the clone of the last child of the
- // content. If the last child is an active template, it may produce
- // instances as a result of production, so simply collecting the last
- // child of the instance after it has finished producing may be wrong.
- if (c.nextNode == null) collectTerminator = true;
-
- final childMap = map != null ? map.getChild(i) : null;
- var clone = _cloneAndBindInstance(c, instance, _stagingDocument,
- childMap, model, delegate, instanceExt._bindings);
-
- nodeBindFallback(clone)._templateInstance = instanceRecord;
- if (collectTerminator) instanceExt._terminator = clone;
- }
-
- instanceRecord._firstNode = instance.firstChild;
- instanceRecord._lastNode = instance.lastChild;
-
- instanceExt._protoContent = null;
- instanceExt._templateCreator = null;
- return instance;
- }
-
- /** The data model which is inherited through the tree. */
- get model => _model;
-
- void set model(value) {
- _model = value;
- _ensureSetModelScheduled();
- }
-
- static Node _deepCloneIgnoreTemplateContent(Node node, stagingDocument) {
- var clone = stagingDocument.importNode(node, false);
- if (isSemanticTemplate(clone)) return clone;
-
- for (var c = node.firstChild; c != null; c = c.nextNode) {
- clone.append(_deepCloneIgnoreTemplateContent(c, stagingDocument));
- }
- return clone;
- }
-
- /**
- * The binding delegate which is inherited through the tree. It can be used
- * to configure custom syntax for `{{bindings}}` inside this template.
- */
- BindingDelegate get bindingDelegate => _bindingDelegate;
-
-
- void set bindingDelegate(BindingDelegate value) {
- if (_bindingDelegate != null) {
- throw new StateError('Template must be cleared before a new '
- 'bindingDelegate can be assigned');
- }
- _bindingDelegate = value;
-
- // Clear cached state based on the binding delegate.
- _bindingMap = null;
- if (_iterator != null) {
- _iterator._initPrepareFunctions = false;
- _iterator._instanceModelFn = null;
- _iterator._instancePositionChangedFn = null;
- }
- }
-
- _ensureSetModelScheduled() {
- if (_setModelScheduled) return;
- _decorate();
- _setModelScheduled = true;
- scheduleMicrotask(_setModel);
- }
-
- void _setModel() {
- _setModelScheduled = false;
- var map = _getBindings(_node, _bindingDelegate);
- _processBindings(_node, map, _model);
- }
-
- _refChanged() {
- if (_iterator == null || _refContent == templateBind(_ref).content) return;
-
- _refContent = null;
- _iterator._valueChanged(null);
- _iterator._updateIteratedValue(this._iterator._getUpdatedValue());
- }
-
- void clear() {
- _model = null;
- _bindingDelegate = null;
- if (bindings != null) {
- var ref = bindings.remove('ref');
- if (ref != null) ref.close();
- }
- _refContent = null;
- if (_iterator == null) return;
- _iterator._valueChanged(null);
- _iterator.close();
- _iterator = null;
- }
-
- /** Gets the template this node refers to. */
- Element get _ref {
- _decorate();
-
- var ref = _searchRefId(_node, _node.attributes['ref']);
- if (ref == null) {
- ref = _templateInstanceRef;
- if (ref == null) return _node;
- }
-
- var nextRef = templateBindFallback(ref)._ref;
- return nextRef != null ? nextRef : ref;
- }
-
- /**
- * Gets the content of this template.
- */
- DocumentFragment get content {
- _decorate();
- return _content != null ? _content : (_node as TemplateElement).content;
- }
-
- /**
- * 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.
- */
- static bool decorate(Element template, [Element instanceRef]) =>
- templateBindFallback(template)._decorate(instanceRef);
-
- bool _decorate([Element instanceRef]) {
- // == true check because it starts as a null field.
- if (_templateIsDecorated == true) return false;
-
- _injectStylesheet();
- _globalBaseUriWorkaround();
-
- var templateElementExt = this;
- _templateIsDecorated = true;
- var isNativeHtmlTemplate = _node is TemplateElement;
- final bootstrapContents = isNativeHtmlTemplate;
- final liftContents = !isNativeHtmlTemplate;
- var liftRoot = false;
-
- if (!isNativeHtmlTemplate) {
- if (_isAttributeTemplate(_node)) {
- if (instanceRef != null) {
- // Dart note: this is just an assert in JS.
- throw new ArgumentError('instanceRef should not be supplied for '
- 'attribute templates.');
- }
- templateElementExt = templateBind(
- _extractTemplateFromAttributeTemplate(_node));
- templateElementExt._templateIsDecorated = true;
- isNativeHtmlTemplate = templateElementExt._node is TemplateElement;
- liftRoot = true;
- } else if (_isSvgTemplate(_node)) {
- templateElementExt = templateBind(
- _extractTemplateFromSvgTemplate(_node));
- templateElementExt._templateIsDecorated = true;
- isNativeHtmlTemplate = templateElementExt._node is TemplateElement;
- }
- }
-
- if (!isNativeHtmlTemplate) {
- var doc = _getOrCreateTemplateContentsOwner(templateElementExt._node);
- templateElementExt._content = doc.createDocumentFragment();
- }
-
- if (instanceRef != null) {
- // template is contained within an instance, its direct content must be
- // empty
- templateElementExt._templateInstanceRef = instanceRef;
- } else if (liftContents) {
- _liftNonNativeChildrenIntoContent(templateElementExt, _node, liftRoot);
- } else if (bootstrapContents) {
- bootstrap(templateElementExt.content);
- }
-
- return true;
- }
-
- static final _contentsOwner = new Expando();
- static final _ownerStagingDocument = new Expando();
-
- // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner
- static HtmlDocument _getOrCreateTemplateContentsOwner(Element template) {
- var doc = template.ownerDocument;
- if (doc.window == null) return doc;
-
- var d = _contentsOwner[doc];
- 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();
- }
- _contentsOwner[doc] = d;
- }
- return d;
- }
-
- HtmlDocument _getTemplateStagingDocument() {
- if (_stagingDocument == null) {
- var owner = _node.ownerDocument;
- var doc = _ownerStagingDocument[owner];
- if (doc == null) {
- doc = owner.implementation.createHtmlDocument('');
- _isStagingDocument[doc] = true;
- _baseUriWorkaround(doc);
- _ownerStagingDocument[owner] = doc;
- }
- _stagingDocument = doc;
- }
- return _stagingDocument;
- }
-
- // 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 Element _extractTemplateFromSvgTemplate(Element el) {
- var template = el.ownerDocument.createElement('template');
- el.parentNode.insertBefore(template, el);
- template.attributes.addAll(el.attributes);
-
- el.attributes.clear();
- el.remove();
- return template;
- }
-
- static void _liftNonNativeChildrenIntoContent(TemplateBindExtension 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.
- static void bootstrap(Node content) {
- void _bootstrap(template) {
- if (!TemplateBindExtension.decorate(template)) {
- bootstrap(templateBind(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 (isSemanticTemplate(content)) {
- _bootstrap(content);
- }
-
- descendents.forEach(_bootstrap);
- }
-
- static final String _allTemplatesSelectors =
- 'template, ' +
- _SEMANTIC_TEMPLATE_TAGS.keys.map((k) => "$k[template]").join(", ");
-
- static bool _initStyles;
-
- // This is to replicate template_element.css
- // TODO(jmesserly): move this to an opt-in CSS file?
- static void _injectStylesheet() {
- if (_initStyles == true) return;
- _initStyles = true;
-
- var style = new StyleElement()
- ..text = '$_allTemplatesSelectors { display: none; }';
- document.head.append(style);
- }
-
- static bool _initBaseUriWorkaround;
-
- static void _globalBaseUriWorkaround() {
- if (_initBaseUriWorkaround == true) return;
- _initBaseUriWorkaround = true;
-
- var t = document.createElement('template');
- if (t is TemplateElement) {
- var d = t.content.ownerDocument;
- if (d.documentElement == null) {
- d.append(d.createElement('html')).append(d.createElement('head'));
- }
- // don't patch this if TemplateBinding.js already has.
- if (d.head.querySelector('base') == null) {
- _baseUriWorkaround(d);
- }
- }
- }
-
- // TODO(rafaelw): Remove when fix for
- // https://codereview.chromium.org/164803002/
- // makes it to Chrome release.
- static void _baseUriWorkaround(HtmlDocument doc) {
- BaseElement base = doc.createElement('base');
- base.href = document.baseUri;
- doc.head.append(base);
- }
-
- static final _templateObserver = new MutationObserver((records, _) {
- for (MutationRecord record in records) {
- templateBindFallback(record.target)._refChanged();
- }
- });
-
-}
-
-final DocumentFragment _emptyInstance = () {
- var empty = new DocumentFragment();
- _instanceExtension[empty] = new _InstanceExtension();
- return empty;
-}();
-
-// TODO(jmesserly): if we merged with wtih TemplateInstance, it seems like it
-// would speed up some operations (e.g. _getInstanceRoot wouldn't need to walk
-// the parent chain).
-class _InstanceExtension {
- final List _bindings = [];
- Node _terminator;
- Element _templateCreator;
- DocumentFragment _protoContent;
-}
-
-// TODO(jmesserly): this is private in JS but public for us because pkg:polymer
-// uses it.
-List getTemplateInstanceBindings(DocumentFragment fragment) {
- var ext = _instanceExtension[fragment];
- return ext != null ? ext._bindings : ext;
-}
-
-/// Gets the root of the current node's parent chain
-_getFragmentRoot(Node node) {
- var p;
- while ((p = node.parentNode) != null) {
- node = p;
- }
- return node;
-}
-
-Node _searchRefId(Node node, String id) {
- if (id == null || id == '') return null;
-
- final selector = '#$id';
- while (true) {
- node = _getFragmentRoot(node);
-
- Node ref = null;
-
- _InstanceExtension instance = _instanceExtension[node];
- if (instance != null && instance._protoContent != null) {
- ref = instance._protoContent.querySelector(selector);
- } else if (_hasGetElementById(node)) {
- ref = (node as dynamic).getElementById(id);
- }
-
- if (ref != null) return ref;
-
- if (instance == null) return null;
- node = instance._templateCreator;
- if (node == null) return null;
- }
-}
-
-_getInstanceRoot(node) {
- while (node.parentNode != null) {
- node = node.parentNode;
- }
- _InstanceExtension instance = _instanceExtension[node];
- return instance != null && instance._templateCreator != null ? node : null;
-}
-
-// Note: JS code tests that getElementById is present. We can't do that
-// easily, so instead check for the types known to implement it.
-bool _hasGetElementById(Node node) =>
- node is Document || node is ShadowRoot || node is SvgSvgElement;
-
-final Expando<_InstanceExtension> _instanceExtension = new Expando();
-
-final _isStagingDocument = new Expando();
« no previous file with comments | « template_binding/lib/src/node.dart ('k') | template_binding/lib/src/template_iterator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698