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

Side by Side Diff: pkg/template_binding/lib/src/template.dart

Issue 105783003: restore 30868 and 30873 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of template_binding; 5 part of template_binding;
6 6
7 /** Extensions to [Element]s that behave as templates. */ 7 /** Extensions to [Element]s that behave as templates. */
8 class TemplateBindExtension extends _ElementExtension { 8 class TemplateBindExtension extends _ElementExtension {
9 var _model; 9 var _model;
10 BindingDelegate _bindingDelegate; 10 BindingDelegate _bindingDelegate;
11 _TemplateIterator _iterator; 11 _TemplateIterator _iterator;
12 bool _scheduled = false; 12 bool _scheduled = false;
13 13
14 Element _templateInstanceRef; 14 Element _templateInstanceRef;
15 15
16 // Note: only used if `this is! TemplateElement` 16 // Note: only used if `this is! TemplateElement`
17 DocumentFragment _content; 17 DocumentFragment _content;
18 bool _templateIsDecorated; 18 bool _templateIsDecorated;
19 19
20 HtmlDocument _stagingDocument;
21
20 var _bindingMap; 22 var _bindingMap;
21 23
22 TemplateBindExtension._(Element node) : super(node); 24 TemplateBindExtension._(Element node) : super(node);
23 25
24 Element get _node => super._node; 26 Element get _node => super._node;
25 27
26 TemplateBindExtension get _self => super._node is TemplateBindExtension 28 TemplateBindExtension get _self => super._node is TemplateBindExtension
27 ? _node : this; 29 ? _node : this;
28 30
29 NodeBinding bind(String name, model, [String path]) { 31 NodeBinding bind(String name, model, [String path]) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // Dart note: we store _bindingMap on the TemplateBindExtension instead of 113 // Dart note: we store _bindingMap on the TemplateBindExtension instead of
112 // the "content" because we already have an expando for it. 114 // the "content" because we already have an expando for it.
113 var map = ref._bindingMap; 115 var map = ref._bindingMap;
114 if (map == null) { 116 if (map == null) {
115 // TODO(rafaelw): Setup a MutationObserver on content to detect 117 // TODO(rafaelw): Setup a MutationObserver on content to detect
116 // when the instanceMap is invalid. 118 // when the instanceMap is invalid.
117 map = new _InstanceBindingMap(content, delegate); 119 map = new _InstanceBindingMap(content, delegate);
118 ref._bindingMap = map; 120 ref._bindingMap = map;
119 } 121 }
120 122
121 var instance = map.hasSubTemplate 123 var staging = _getTemplateStagingDocument();
122 ? _deepCloneIgnoreTemplateContent(content) 124 var instance = _deepCloneIgnoreTemplateContent(content, staging);
123 : content.clone(true);
124 125
125 _addMapBindings(instance, map, model, delegate, bound); 126 _addMapBindings(instance, map, model, delegate, bound);
126 // TODO(rafaelw): We can do this more lazily, but setting a sentinel 127 // TODO(rafaelw): We can do this more lazily, but setting a sentinel
127 // in the parent of the template element, and creating it when it's 128 // in the parent of the template element, and creating it when it's
128 // asked for by walking back to find the iterating template. 129 // asked for by walking back to find the iterating template.
129 _addTemplateInstanceRecord(instance, model); 130 _addTemplateInstanceRecord(instance, model);
130 return instance; 131 return instance;
131 } 132 }
132 133
133 /** The data model which is inherited through the tree. */ 134 /** The data model which is inherited through the tree. */
134 get model => _model; 135 get model => _model;
135 136
136 void set model(value) { 137 void set model(value) {
137 _model = value; 138 _model = value;
138 _ensureSetModelScheduled(); 139 _ensureSetModelScheduled();
139 } 140 }
140 141
141 static Node _deepCloneIgnoreTemplateContent(Node node) { 142 static Node _deepCloneIgnoreTemplateContent(Node node, stagingDocument) {
142 var clone = node.clone(false); // Shallow clone. 143 var clone = stagingDocument.importNode(node, false);
143 if (isSemanticTemplate(clone)) return clone; 144 if (isSemanticTemplate(clone)) return clone;
144 145
145 for (var c = node.firstChild; c != null; c = c.nextNode) { 146 for (var c = node.firstChild; c != null; c = c.nextNode) {
146 clone.append(_deepCloneIgnoreTemplateContent(c)); 147 clone.append(_deepCloneIgnoreTemplateContent(c, stagingDocument));
147 } 148 }
148 return clone; 149 return clone;
149 } 150 }
150 151
151 /** 152 /**
152 * The binding delegate which is inherited through the tree. It can be used 153 * The binding delegate which is inherited through the tree. It can be used
153 * to configure custom syntax for `{{bindings}}` inside this template. 154 * to configure custom syntax for `{{bindings}}` inside this template.
154 */ 155 */
155 BindingDelegate get bindingDelegate => _bindingDelegate; 156 BindingDelegate get bindingDelegate => _bindingDelegate;
156 157
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 'attribute templates.'); 235 'attribute templates.');
235 } 236 }
236 templateElementExt = templateBind( 237 templateElementExt = templateBind(
237 _extractTemplateFromAttributeTemplate(_node)); 238 _extractTemplateFromAttributeTemplate(_node));
238 templateElementExt._templateIsDecorated = true; 239 templateElementExt._templateIsDecorated = true;
239 isNative = templateElementExt._node is TemplateElement; 240 isNative = templateElementExt._node is TemplateElement;
240 liftRoot = true; 241 liftRoot = true;
241 } 242 }
242 243
243 if (!isNative) { 244 if (!isNative) {
244 var doc = _getTemplateContentsOwner( 245 var doc = _getOrCreateTemplateContentsOwner(templateElementExt._node);
245 templateElementExt._node.ownerDocument);
246 templateElementExt._content = doc.createDocumentFragment(); 246 templateElementExt._content = doc.createDocumentFragment();
247 } 247 }
248 248
249 if (instanceRef != null) { 249 if (instanceRef != null) {
250 // template is contained within an instance, its direct content must be 250 // template is contained within an instance, its direct content must be
251 // empty 251 // empty
252 templateElementExt._templateInstanceRef = instanceRef; 252 templateElementExt._templateInstanceRef = instanceRef;
253 } else if (liftContents) { 253 } else if (liftContents) {
254 _liftNonNativeChildrenIntoContent(templateElementExt, _node, liftRoot); 254 _liftNonNativeChildrenIntoContent(templateElementExt, _node, liftRoot);
255 } else if (bootstrapContents) { 255 } else if (bootstrapContents) {
256 bootstrap(templateElementExt.content); 256 bootstrap(templateElementExt.content);
257 } 257 }
258 258
259 return true; 259 return true;
260 } 260 }
261 261
262 static final _contentsOwner = new Expando(); 262 static final _contentsOwner = new Expando();
263 static final _ownerStagingDocument = new Expando();
263 264
264 // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html# dfn-template-contents-owner 265 // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html# dfn-template-contents-owner
265 static Document _getTemplateContentsOwner(HtmlDocument doc) { 266 static HtmlDocument _getOrCreateTemplateContentsOwner(Element template) {
266 if (doc.window == null) { 267 var doc = template.ownerDocument;
267 return doc; 268 if (doc.window == null) return doc;
268 } 269
269 var d = _contentsOwner[doc]; 270 var d = _contentsOwner[doc];
270 if (d == null) { 271 if (d == null) {
271 // TODO(arv): This should either be a Document or HTMLDocument depending 272 // TODO(arv): This should either be a Document or HTMLDocument depending
272 // on doc. 273 // on doc.
273 d = doc.implementation.createHtmlDocument(''); 274 d = doc.implementation.createHtmlDocument('');
274 while (d.lastChild != null) { 275 while (d.lastChild != null) {
275 d.lastChild.remove(); 276 d.lastChild.remove();
276 } 277 }
277 _contentsOwner[doc] = d; 278 _contentsOwner[doc] = d;
278 } 279 }
279 return d; 280 return d;
280 } 281 }
281 282
283 HtmlDocument _getTemplateStagingDocument() {
284 if (_stagingDocument == null) {
285 var owner = _node.ownerDocument;
286 var doc = _ownerStagingDocument[owner];
287 if (doc == null) {
288 doc = owner.implementation.createHtmlDocument('');
289 _ownerStagingDocument[owner] = doc;
290 }
291 _stagingDocument = doc;
292 }
293 return _stagingDocument;
294 }
295
282 // For non-template browsers, the parser will disallow <template> in certain 296 // For non-template browsers, the parser will disallow <template> in certain
283 // locations, so we allow "attribute templates" which combine the template 297 // locations, so we allow "attribute templates" which combine the template
284 // element with the top-level container node of the content, e.g. 298 // element with the top-level container node of the content, e.g.
285 // 299 //
286 // <tr template repeat="{{ foo }}"" class="bar"><td>Bar</td></tr> 300 // <tr template repeat="{{ foo }}"" class="bar"><td>Bar</td></tr>
287 // 301 //
288 // becomes 302 // becomes
289 // 303 //
290 // <template repeat="{{ foo }}"> 304 // <template repeat="{{ foo }}">
291 // + #document-fragment 305 // + #document-fragment
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 node = node.parentNode; 440 node = node.parentNode;
427 } 441 }
428 442
429 // Note: JS code tests that getElementById is present. We can't do that 443 // Note: JS code tests that getElementById is present. We can't do that
430 // easily, so instead check for the types known to implement it. 444 // easily, so instead check for the types known to implement it.
431 if (node is Document || node is ShadowRoot || node is SvgSvgElement) { 445 if (node is Document || node is ShadowRoot || node is SvgSvgElement) {
432 return node; 446 return node;
433 } 447 }
434 return null; 448 return null;
435 } 449 }
OLDNEW
« no previous file with comments | « pkg/template_binding/lib/src/instance_binding_map.dart ('k') | pkg/template_binding/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698