| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 part of mdv; | |
| 6 | |
| 7 /** Extensions to [Element]s that behave as templates. */ | |
| 8 class _TemplateExtension extends _ElementExtension { | |
| 9 var _model; | |
| 10 BindingDelegate _bindingDelegate; | |
| 11 _TemplateIterator _templateIterator; | |
| 12 bool _scheduled = false; | |
| 13 | |
| 14 _TemplateExtension(Element node) : super(node); | |
| 15 | |
| 16 Element get node => super.node; | |
| 17 | |
| 18 NodeBinding createBinding(String name, model, String path) { | |
| 19 switch (name) { | |
| 20 case 'bind': | |
| 21 case 'repeat': | |
| 22 case 'if': | |
| 23 if (_templateIterator == null) { | |
| 24 _templateIterator = new _TemplateIterator(node); | |
| 25 } | |
| 26 // TODO(jmesserly): why do we do this here and nowhere else? | |
| 27 if (path == null) path = ''; | |
| 28 return new _TemplateBinding(node, name, model, path); | |
| 29 default: | |
| 30 return super.createBinding(name, model, path); | |
| 31 } | |
| 32 } | |
| 33 | |
| 34 /** | |
| 35 * Creates an instance of the template. | |
| 36 */ | |
| 37 DocumentFragment createInstance(model, BindingDelegate delegate) { | |
| 38 var template = node.ref; | |
| 39 if (template == null) template = node; | |
| 40 | |
| 41 var instance = _createDeepCloneAndDecorateTemplates( | |
| 42 template.ref.content, delegate); | |
| 43 | |
| 44 if (_instanceCreated != null) { | |
| 45 for (var callback in _instanceCreated) callback(instance); | |
| 46 } | |
| 47 | |
| 48 _addBindings(instance, model, delegate); | |
| 49 _addTemplateInstanceRecord(instance, model); | |
| 50 return instance; | |
| 51 } | |
| 52 | |
| 53 /** | |
| 54 * The data model which is inherited through the tree. | |
| 55 */ | |
| 56 get model => _model; | |
| 57 | |
| 58 void set model(value) { | |
| 59 _model = value; | |
| 60 _ensureSetModelScheduled(); | |
| 61 } | |
| 62 | |
| 63 /** | |
| 64 * The binding delegate which is inherited through the tree. It can be used | |
| 65 * to configure custom syntax for `{{bindings}}` inside this template. | |
| 66 */ | |
| 67 BindingDelegate get bindingDelegate => _bindingDelegate; | |
| 68 | |
| 69 void set bindingDelegate(BindingDelegate value) { | |
| 70 _bindingDelegate = value; | |
| 71 _ensureSetModelScheduled(); | |
| 72 } | |
| 73 | |
| 74 _ensureSetModelScheduled() { | |
| 75 if (_scheduled) return; | |
| 76 _scheduled = true; | |
| 77 scheduleMicrotask(_setModel); | |
| 78 } | |
| 79 | |
| 80 void _setModel() { | |
| 81 _scheduled = false; | |
| 82 _addBindings(node, _model, _bindingDelegate); | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 class _TemplateBinding extends NodeBinding { | |
| 87 // TODO(jmesserly): MDV uses TemplateIterator as the node, see: | |
| 88 // https://github.com/Polymer/mdv/issues/127 | |
| 89 _TemplateBinding(node, name, model, path) | |
| 90 : super(node, name, model, path) { | |
| 91 _mdv(node)._templateIterator.inputs.bind(property, model, path); | |
| 92 } | |
| 93 | |
| 94 // These are no-ops because we don't use the underlying PathObserver. | |
| 95 void _observePath() {} | |
| 96 void boundValueChanged(newValue) {} | |
| 97 | |
| 98 void close() { | |
| 99 if (closed) return; | |
| 100 var templateIterator = _mdv(node)._templateIterator; | |
| 101 if (templateIterator != null) templateIterator.inputs.unbind(property); | |
| 102 super.close(); | |
| 103 } | |
| 104 } | |
| OLD | NEW |