| OLD | NEW |
| 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 _templateIterator; | 11 _TemplateIterator _templateIterator; |
| 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 TemplateBindExtension._(Element node) : super(node); | 20 TemplateBindExtension._(Element node) : super(node); |
| 21 | 21 |
| 22 Element get _node => super._node; | 22 Element get _node => super._node; |
| 23 | 23 |
| 24 NodeBinding createBinding(String name, model, String path) { | 24 NodeBinding bind(String name, model, [String path]) { |
| 25 switch (name) { | 25 switch (name) { |
| 26 case 'bind': | 26 case 'bind': |
| 27 case 'repeat': | 27 case 'repeat': |
| 28 case 'if': | 28 case 'if': |
| 29 _self.unbind(name); |
| 29 if (_templateIterator == null) { | 30 if (_templateIterator == null) { |
| 30 _templateIterator = new _TemplateIterator(_node); | 31 _templateIterator = new _TemplateIterator(_node); |
| 31 } | 32 } |
| 32 // TODO(jmesserly): why do we do this here and nowhere else? | 33 return bindings[name] = new _TemplateBinding(this, name, model, path); |
| 33 if (path == null) path = ''; | |
| 34 return new _TemplateBinding(this, name, model, path); | |
| 35 default: | 34 default: |
| 36 return super.createBinding(name, model, path); | 35 return super.bind(name, model, path); |
| 37 } | 36 } |
| 38 } | 37 } |
| 39 | 38 |
| 40 /** | 39 /** |
| 41 * Creates an instance of the template, using the provided model and optional | 40 * Creates an instance of the template, using the provided model and optional |
| 42 * binding delegate. | 41 * binding delegate. |
| 43 */ | 42 */ |
| 44 DocumentFragment createInstance([model, BindingDelegate delegate]) { | 43 DocumentFragment createInstance([model, BindingDelegate delegate]) { |
| 45 var instance = _createDeepCloneAndDecorateTemplates( | 44 var instance = _createDeepCloneAndDecorateTemplates( |
| 46 templateBind(ref).content, delegate); | 45 templateBind(ref).content, delegate); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 _addBindings(_node, _model, _bindingDelegate); | 80 _addBindings(_node, _model, _bindingDelegate); |
| 82 } | 81 } |
| 83 | 82 |
| 84 /** Gets the template this node refers to. */ | 83 /** Gets the template this node refers to. */ |
| 85 Element get ref { | 84 Element get ref { |
| 86 _decorate(); | 85 _decorate(); |
| 87 | 86 |
| 88 Element result = null; | 87 Element result = null; |
| 89 var refId = _node.attributes['ref']; | 88 var refId = _node.attributes['ref']; |
| 90 if (refId != null) { | 89 if (refId != null) { |
| 91 var treeScope = _node; | 90 var treeScope = _getTreeScope(_node); |
| 92 while (treeScope.parentNode != null) { | 91 if (treeScope != null) { |
| 93 treeScope = treeScope.parentNode; | |
| 94 } | |
| 95 | |
| 96 // Note: JS code tests that getElementById is present. We can't do that | |
| 97 // easily, so instead check for the types known to implement it. | |
| 98 if (treeScope is Document || | |
| 99 treeScope is ShadowRoot || | |
| 100 treeScope is SvgSvgElement) { | |
| 101 | |
| 102 result = treeScope.getElementById(refId); | 92 result = treeScope.getElementById(refId); |
| 103 } | 93 } |
| 104 } | 94 } |
| 105 | 95 |
| 106 if (result == null) { | 96 if (result == null) { |
| 107 result = _templateInstanceRef; | 97 result = _templateInstanceRef; |
| 108 if (result == null) return _node; | 98 if (result == null) return _node; |
| 109 } | 99 } |
| 110 | 100 |
| 111 var nextRef = templateBind(result).ref; | 101 var nextRef = templateBind(result).ref; |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 } | 292 } |
| 303 } | 293 } |
| 304 | 294 |
| 305 class _TemplateBinding extends NodeBinding { | 295 class _TemplateBinding extends NodeBinding { |
| 306 TemplateBindExtension _ext; | 296 TemplateBindExtension _ext; |
| 307 | 297 |
| 308 // TODO(jmesserly): MDV uses TemplateIterator as the node, see: | 298 // TODO(jmesserly): MDV uses TemplateIterator as the node, see: |
| 309 // https://github.com/Polymer/mdv/issues/127 | 299 // https://github.com/Polymer/mdv/issues/127 |
| 310 _TemplateBinding(ext, name, model, path) | 300 _TemplateBinding(ext, name, model, path) |
| 311 : _ext = ext, super(ext._node, name, model, path) { | 301 : _ext = ext, super(ext._node, name, model, path) { |
| 312 _ext._templateIterator.inputs.bind(property, model, path); | 302 _ext._templateIterator.inputs.bind(property, model, this.path); |
| 313 } | 303 } |
| 314 | 304 |
| 315 // These are no-ops because we don't use the underlying PathObserver. | 305 // These are no-ops because we don't use the underlying PathObserver. |
| 316 void _observePath() {} | 306 void _observePath() {} |
| 317 void boundValueChanged(newValue) {} | 307 void valueChanged(newValue) {} |
| 318 | 308 |
| 319 void close() { | 309 void close() { |
| 320 if (closed) return; | 310 if (closed) return; |
| 321 var templateIterator = _ext._templateIterator; | 311 var templateIterator = _ext._templateIterator; |
| 322 if (templateIterator != null) templateIterator.inputs.unbind(property); | 312 if (templateIterator != null) templateIterator.inputs.unbind(property); |
| 323 super.close(); | 313 super.close(); |
| 324 } | 314 } |
| 325 } | 315 } |
| 316 |
| 317 _getTreeScope(Node node) { |
| 318 while (node.parentNode != null) { |
| 319 node = node.parentNode; |
| 320 } |
| 321 |
| 322 // Note: JS code tests that getElementById is present. We can't do that |
| 323 // easily, so instead check for the types known to implement it. |
| 324 if (node is Document || node is ShadowRoot || node is SvgSvgElement) { |
| 325 return node; |
| 326 } |
| 327 return null; |
| 328 } |
| OLD | NEW |