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

Side by Side Diff: pkg/mdv/lib/src/template_iterator.dart

Issue 19663011: Custom Syntax's are now enabled via template.bindingDelegate = (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: restore @Experimental Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/mdv/lib/src/template.dart ('k') | pkg/mdv/test/binding_syntax_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 mdv; 5 part of mdv;
6 6
7 // This code is a port of Model-Driven-Views: 7 // This code is a port of Model-Driven-Views:
8 // https://github.com/polymer-project/mdv 8 // https://github.com/polymer-project/mdv
9 // The code mostly comes from src/template_element.js 9 // The code mostly comes from src/template_element.js
10 10
11 // TODO(jmesserly): not sure what kind of boolean conversion rules to 11 // TODO(jmesserly): not sure what kind of boolean conversion rules to
12 // apply for template data-binding. HTML attributes are true if they're 12 // apply for template data-binding. HTML attributes are true if they're
13 // present. However Dart only treats "true" as true. Since this is HTML we'll 13 // present. However Dart only treats "true" as true. Since this is HTML we'll
14 // use something closer to the HTML rules: null (missing) and false are false, 14 // use something closer to the HTML rules: null (missing) and false are false,
15 // everything else is true. See: https://github.com/polymer-project/mdv/issues/5 9 15 // everything else is true. See: https://github.com/polymer-project/mdv/issues/5 9
16 bool _toBoolean(value) => null != value && false != value; 16 bool _toBoolean(value) => null != value && false != value;
17 17
18 Node _createDeepCloneAndDecorateTemplates(Node node, String syntax) { 18 Node _createDeepCloneAndDecorateTemplates(Node node, BindingDelegate delegate) {
19 var clone = node.clone(false); // Shallow clone. 19 var clone = node.clone(false); // Shallow clone.
20 if (clone is Element && clone.isTemplate) { 20 if (clone is Element && clone.isTemplate) {
21 TemplateElement.decorate(clone, node); 21 TemplateElement.decorate(clone, node);
22 if (syntax != null) { 22 if (delegate != null) {
23 clone.attributes.putIfAbsent('syntax', () => syntax); 23 _mdv(clone)._bindingDelegate = delegate;
24 } 24 }
25 } 25 }
26 26
27 for (var c = node.firstChild; c != null; c = c.nextNode) { 27 for (var c = node.firstChild; c != null; c = c.nextNode) {
28 clone.append(_createDeepCloneAndDecorateTemplates(c, syntax)); 28 clone.append(_createDeepCloneAndDecorateTemplates(c, delegate));
29 } 29 }
30 return clone; 30 return clone;
31 } 31 }
32 32
33 void _addBindings(Node node, model, [CustomBindingSyntax delegate]) { 33 void _addBindings(Node node, model, [BindingDelegate delegate]) {
34 if (node is Element) { 34 if (node is Element) {
35 _addAttributeBindings(node, model, delegate); 35 _addAttributeBindings(node, model, delegate);
36 } else if (node is Text) { 36 } else if (node is Text) {
37 _parseAndBind(node, 'text', node.text, model, delegate); 37 _parseAndBind(node, 'text', node.text, model, delegate);
38 } 38 }
39 39
40 for (var c = node.firstChild; c != null; c = c.nextNode) { 40 for (var c = node.firstChild; c != null; c = c.nextNode) {
41 _addBindings(c, model, delegate); 41 _addBindings(c, model, delegate);
42 } 42 }
43 } 43 }
44 44
45 void _addAttributeBindings(Element element, model, delegate) { 45 void _addAttributeBindings(Element element, model, delegate) {
46 element.attributes.forEach((name, value) { 46 element.attributes.forEach((name, value) {
47 if (value == '' && (name == 'bind' || name == 'repeat')) { 47 if (value == '' && (name == 'bind' || name == 'repeat')) {
48 value = '{{}}'; 48 value = '{{}}';
49 } 49 }
50 _parseAndBind(element, name, value, model, delegate); 50 _parseAndBind(element, name, value, model, delegate);
51 }); 51 });
52 } 52 }
53 53
54 void _parseAndBind(Node node, String name, String text, model, 54 void _parseAndBind(Node node, String name, String text, model,
55 CustomBindingSyntax delegate) { 55 BindingDelegate delegate) {
56 56
57 var tokens = _parseMustacheTokens(text); 57 var tokens = _parseMustacheTokens(text);
58 if (tokens.length == 0 || (tokens.length == 1 && tokens[0].isText)) { 58 if (tokens.length == 0 || (tokens.length == 1 && tokens[0].isText)) {
59 return; 59 return;
60 } 60 }
61 61
62 // If this is a custom element, give the .xtag a change to bind. 62 // If this is a custom element, give the .xtag a change to bind.
63 node = _nodeOrCustom(node); 63 node = _nodeOrCustom(node);
64 64
65 if (tokens.length == 1 && tokens[0].isBinding) { 65 if (tokens.length == 1 && tokens[0].isBinding) {
(...skipping 24 matching lines...) Expand all
90 } 90 }
91 } 91 }
92 92
93 return newValue.toString(); 93 return newValue.toString();
94 }; 94 };
95 95
96 node.bind(name, replacementBinding, 'value'); 96 node.bind(name, replacementBinding, 'value');
97 } 97 }
98 98
99 void _bindOrDelegate(node, name, model, String path, 99 void _bindOrDelegate(node, name, model, String path,
100 CustomBindingSyntax delegate) { 100 BindingDelegate delegate) {
101 101
102 if (delegate != null) { 102 if (delegate != null) {
103 var delegateBinding = delegate.getBinding(model, path, name, node); 103 var delegateBinding = delegate.getBinding(model, path, name, node);
104 if (delegateBinding != null) { 104 if (delegateBinding != null) {
105 model = delegateBinding; 105 model = delegateBinding;
106 path = 'value'; 106 path = 'value';
107 } 107 }
108 } 108 }
109 109
110 node.bind(name, model, path); 110 node.bind(name, model, path);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 var parent = _templateElement.parentNode; 263 var parent = _templateElement.parentNode;
264 while (terminator != previousTerminator) { 264 while (terminator != previousTerminator) {
265 var node = previousTerminator.nextNode; 265 var node = previousTerminator.nextNode;
266 if (node == terminator) terminator = previousTerminator; 266 if (node == terminator) terminator = previousTerminator;
267 node.remove(); 267 node.remove();
268 instanceNodes.add(node); 268 instanceNodes.add(node);
269 } 269 }
270 return instanceNodes; 270 return instanceNodes;
271 } 271 }
272 272
273 getInstanceModel(model, String syntax) { 273 getInstanceModel(model, BindingDelegate delegate) {
274 var delegate = TemplateElement.syntax[syntax];
275 if (delegate != null) { 274 if (delegate != null) {
276 return delegate.getInstanceModel(_templateElement, model); 275 return delegate.getInstanceModel(_templateElement, model);
277 } 276 }
278 return model; 277 return model;
279 } 278 }
280 279
281 List<Node> getInstanceNodes(model, String syntax, IdentityMap instanceCache) { 280 List<Node> getInstanceNodes(model, BindingDelegate delegate,
281 IdentityMap instanceCache) {
282
282 var instanceNodes = instanceCache.remove(model); 283 var instanceNodes = instanceCache.remove(model);
283 if (instanceNodes != null) return instanceNodes; 284 if (instanceNodes != null) return instanceNodes;
284 285
285 var fragment = _templateElement.createInstance(model, syntax); 286 var fragment = _templateElement.createInstance(model, delegate);
286 instanceNodes = fragment.nodes.toList(); 287 instanceNodes = fragment.nodes.toList();
287 fragment.nodes.clear(); 288 fragment.nodes.clear();
288 return instanceNodes; 289 return instanceNodes;
289 } 290 }
290 291
291 void _handleChanges(Iterable<ChangeRecord> splices) { 292 void _handleChanges(Iterable<ChangeRecord> splices) {
292 if (closed) return; 293 if (closed) return;
293 294
294 splices = splices.where((s) => s is ListChangeRecord); 295 splices = splices.where((s) => s is ListChangeRecord);
295 296
296 var template = _templateElement; 297 var template = _templateElement;
297 var syntax = template.attributes['syntax']; 298 var delegate = template.bindingDelegate;
298 299
299 if (template.parentNode == null || template.document.window == null) { 300 if (template.parentNode == null || template.document.window == null) {
300 close(); 301 close();
301 // TODO(jmesserly): MDV calls templateIteratorTable.delete(this) here, 302 // TODO(jmesserly): MDV calls templateIteratorTable.delete(this) here,
302 // but I think that's a no-op because only nodes are used as keys. 303 // but I think that's a no-op because only nodes are used as keys.
303 // See https://github.com/Polymer/mdv/pull/114. 304 // See https://github.com/Polymer/mdv/pull/114.
304 return; 305 return;
305 } 306 }
306 307
307 // TODO(jmesserly): IdentityMap matches JS semantics, but it's O(N) right 308 // TODO(jmesserly): IdentityMap matches JS semantics, but it's O(N) right
308 // now. See http://dartbug.com/4161. 309 // now. See http://dartbug.com/4161.
309 var instanceCache = new IdentityMap(); 310 var instanceCache = new IdentityMap();
310 var removeDelta = 0; 311 var removeDelta = 0;
311 for (var splice in splices) { 312 for (var splice in splices) {
312 for (int i = 0; i < splice.removedCount; i++) { 313 for (int i = 0; i < splice.removedCount; i++) {
313 var instanceNodes = extractInstanceAt(splice.index + removeDelta); 314 var instanceNodes = extractInstanceAt(splice.index + removeDelta);
314 if (instanceNodes.length == 0) continue; 315 if (instanceNodes.length == 0) continue;
315 var model = _mdv(instanceNodes.first)._templateInstance.model; 316 var model = _mdv(instanceNodes.first)._templateInstance.model;
316 instanceCache[model] = instanceNodes; 317 instanceCache[model] = instanceNodes;
317 } 318 }
318 319
319 removeDelta -= splice.addedCount; 320 removeDelta -= splice.addedCount;
320 } 321 }
321 322
322 for (var splice in splices) { 323 for (var splice in splices) {
323 for (var addIndex = splice.index; 324 for (var addIndex = splice.index;
324 addIndex < splice.index + splice.addedCount; 325 addIndex < splice.index + splice.addedCount;
325 addIndex++) { 326 addIndex++) {
326 327
327 var model = getInstanceModel(iteratedValue[addIndex], syntax); 328 var model = getInstanceModel(iteratedValue[addIndex], delegate);
328 329
329 var instanceNodes = getInstanceNodes(model, syntax, instanceCache); 330 var instanceNodes = getInstanceNodes(model, delegate, instanceCache);
330 insertInstanceAt(addIndex, instanceNodes); 331 insertInstanceAt(addIndex, instanceNodes);
331 } 332 }
332 } 333 }
333 334
334 for (var instanceNodes in instanceCache.values) { 335 for (var instanceNodes in instanceCache.values) {
335 instanceNodes.forEach(_unbindAllRecursively); 336 instanceNodes.forEach(_unbindAllRecursively);
336 } 337 }
337 } 338 }
338 339
339 void unobserve() { 340 void unobserve() {
(...skipping 22 matching lines...) Expand all
362 nodeExt._templateIterator = null; 363 nodeExt._templateIterator = null;
363 } 364 }
364 } 365 }
365 366
366 _nodeOrCustom(node).unbindAll(); 367 _nodeOrCustom(node).unbindAll();
367 for (var c = node.firstChild; c != null; c = c.nextNode) { 368 for (var c = node.firstChild; c != null; c = c.nextNode) {
368 _unbindAllRecursively(c); 369 _unbindAllRecursively(c);
369 } 370 }
370 } 371 }
371 } 372 }
OLDNEW
« no previous file with comments | « pkg/mdv/lib/src/template.dart ('k') | pkg/mdv/test/binding_syntax_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698