| OLD | NEW |
| 1 /// The Dart HTML library. | 1 /// The Dart HTML library. |
| 2 library dart.dom.html; | 2 library dart.dom.html; |
| 3 | 3 |
| 4 import 'dart:async'; | 4 import 'dart:async'; |
| 5 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 import 'dart:_collection-dev' hide Symbol; | 6 import 'dart:_collection-dev' hide Symbol; |
| 7 import 'dart:html_common'; | 7 import 'dart:html_common'; |
| 8 import 'dart:indexed_db'; | 8 import 'dart:indexed_db'; |
| 9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
| 10 import 'dart:json' as json; | 10 import 'dart:json' as json; |
| (...skipping 7981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7992 * | 7992 * |
| 7993 * Currently this does not support propagation through Shadow DOMs. | 7993 * Currently this does not support propagation through Shadow DOMs. |
| 7994 */ | 7994 */ |
| 7995 @Experimental | 7995 @Experimental |
| 7996 get model => _model; | 7996 get model => _model; |
| 7997 | 7997 |
| 7998 @Experimental | 7998 @Experimental |
| 7999 void set model(value) { | 7999 void set model(value) { |
| 8000 _ensureTemplate(); | 8000 _ensureTemplate(); |
| 8001 | 8001 |
| 8002 var syntax = TemplateElement.syntax[attributes['syntax']]; |
| 8002 _model = value; | 8003 _model = value; |
| 8003 _addBindings(this, model); | 8004 _addBindings(this, model, syntax); |
| 8004 } | 8005 } |
| 8005 | 8006 |
| 8006 // TODO(jmesserly): const set would be better | 8007 // TODO(jmesserly): const set would be better |
| 8007 static const _TABLE_TAGS = const { | 8008 static const _TABLE_TAGS = const { |
| 8008 'caption': null, | 8009 'caption': null, |
| 8009 'col': null, | 8010 'col': null, |
| 8010 'colgroup': null, | 8011 'colgroup': null, |
| 8011 'tbody': null, | 8012 'tbody': null, |
| 8012 'td': null, | 8013 'td': null, |
| 8013 'tfoot': null, | 8014 'tfoot': null, |
| (...skipping 7702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15716 /** Unbinds the attribute [name]. */ | 15717 /** Unbinds the attribute [name]. */ |
| 15717 @Experimental | 15718 @Experimental |
| 15718 void unbind(String name) {} | 15719 void unbind(String name) {} |
| 15719 | 15720 |
| 15720 /** Unbinds all bound attributes. */ | 15721 /** Unbinds all bound attributes. */ |
| 15721 @Experimental | 15722 @Experimental |
| 15722 void unbindAll() {} | 15723 void unbindAll() {} |
| 15723 | 15724 |
| 15724 TemplateInstance _templateInstance; | 15725 TemplateInstance _templateInstance; |
| 15725 | 15726 |
| 15726 // TODO(arv): Consider storing all "NodeRareData" on a single object? | |
| 15727 int __instanceTerminatorCount; | |
| 15728 int get _instanceTerminatorCount { | |
| 15729 if (__instanceTerminatorCount == null) return 0; | |
| 15730 return __instanceTerminatorCount; | |
| 15731 } | |
| 15732 set _instanceTerminatorCount(int value) { | |
| 15733 if (value == 0) value = null; | |
| 15734 __instanceTerminatorCount = value; | |
| 15735 } | |
| 15736 | |
| 15737 /** Gets the template instance that instantiated this node, if any. */ | 15727 /** Gets the template instance that instantiated this node, if any. */ |
| 15738 @Experimental | 15728 @Experimental |
| 15739 TemplateInstance get templateInstance => | 15729 TemplateInstance get templateInstance => |
| 15740 _templateInstance != null ? _templateInstance : | 15730 _templateInstance != null ? _templateInstance : |
| 15741 (parent != null ? parent.templateInstance : null); | 15731 (parent != null ? parent.templateInstance : null); |
| 15742 | 15732 |
| 15743 Node.internal() : super.internal(); | 15733 Node.internal() : super.internal(); |
| 15744 | 15734 |
| 15745 static const int ATTRIBUTE_NODE = 2; | 15735 static const int ATTRIBUTE_NODE = 2; |
| 15746 | 15736 |
| (...skipping 10923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 26670 * | 26660 * |
| 26671 * TemplateElement.syntax['MySyntax'] = new MySyntax(); | 26661 * TemplateElement.syntax['MySyntax'] = new MySyntax(); |
| 26672 * | 26662 * |
| 26673 * See <https://github.com/toolkitchen/mdv/blob/master/docs/syntax.md> for more | 26663 * See <https://github.com/toolkitchen/mdv/blob/master/docs/syntax.md> for more |
| 26674 * information about Custom Syntax. | 26664 * information about Custom Syntax. |
| 26675 */ | 26665 */ |
| 26676 // TODO(jmesserly): if this is just one method, a function type would make it | 26666 // TODO(jmesserly): if this is just one method, a function type would make it |
| 26677 // more Dart-friendly. | 26667 // more Dart-friendly. |
| 26678 @Experimental | 26668 @Experimental |
| 26679 abstract class CustomBindingSyntax { | 26669 abstract class CustomBindingSyntax { |
| 26670 /** |
| 26671 * This syntax method allows for a custom interpretation of the contents of |
| 26672 * mustaches (`{{` ... `}}`). |
| 26673 * |
| 26674 * When a template is inserting an instance, it will invoke this method for |
| 26675 * each mustache which is encountered. The function is invoked with four |
| 26676 * arguments: |
| 26677 * |
| 26678 * - [model]: The data context for which this instance is being created. |
| 26679 * - [path]: The text contents (trimmed of outer whitespace) of the mustache. |
| 26680 * - [name]: The context in which the mustache occurs. Within element |
| 26681 * attributes, this will be the name of the attribute. Within text, |
| 26682 * this will be 'text'. |
| 26683 * - [node]: A reference to the node to which this binding will be created. |
| 26684 * |
| 26685 * If the method wishes to handle binding, it is required to return an object |
| 26686 * which has at least a `value` property that can be observed. If it does, |
| 26687 * then MDV will call [Node.bind on the node: |
| 26688 * |
| 26689 * node.bind(name, retval, 'value'); |
| 26690 * |
| 26691 * If the 'getBinding' does not wish to override the binding, it should return |
| 26692 * null. |
| 26693 */ |
| 26680 // TODO(jmesserly): I had to remove type annotations from "name" and "node" | 26694 // TODO(jmesserly): I had to remove type annotations from "name" and "node" |
| 26681 // Normally they are String and Node respectively. But sometimes it will pass | 26695 // Normally they are String and Node respectively. But sometimes it will pass |
| 26682 // (int name, CompoundBinding node). That seems very confusing; we may want | 26696 // (int name, CompoundBinding node). That seems very confusing; we may want |
| 26683 // to change this API. | 26697 // to change this API. |
| 26684 getBinding(model, String path, name, node); | 26698 getBinding(model, String path, name, node) => null; |
| 26699 |
| 26700 /** |
| 26701 * This syntax method allows a syntax to provide an alterate model than the |
| 26702 * one the template would otherwise use when producing an instance. |
| 26703 * |
| 26704 * When a template is about to create an instance, it will invoke this method |
| 26705 * The function is invoked with two arguments: |
| 26706 * |
| 26707 * - [template]: The template element which is about to create and insert an |
| 26708 * instance. |
| 26709 * - [model]: The data context for which this instance is being created. |
| 26710 * |
| 26711 * The template element will always use the return value of `getInstanceModel` |
| 26712 * as the model for the new instance. If the syntax does not wish to override |
| 26713 * the value, it should simply return the `model` value it was passed. |
| 26714 */ |
| 26715 getInstanceModel(Element template, model) => model; |
| 26716 |
| 26717 /** |
| 26718 * This syntax method allows a syntax to provide an alterate expansion of |
| 26719 * the [template] contents. When the template wants to create an instance, |
| 26720 * it will call this method with the template element. |
| 26721 * |
| 26722 * By default this will call `template.createInstance()`. |
| 26723 */ |
| 26724 getInstanceFragment(Element template) => template.createInstance(); |
| 26685 } | 26725 } |
| 26686 | 26726 |
| 26687 /** The callback used in the [CompoundBinding.combinator] field. */ | 26727 /** The callback used in the [CompoundBinding.combinator] field. */ |
| 26688 @Experimental | 26728 @Experimental |
| 26689 typedef Object CompoundBindingCombinator(Map objects); | 26729 typedef Object CompoundBindingCombinator(Map objects); |
| 26690 | 26730 |
| 26691 /** Information about the instantiated template. */ | 26731 /** Information about the instantiated template. */ |
| 26692 @Experimental | 26732 @Experimental |
| 26693 class TemplateInstance { | 26733 class TemplateInstance { |
| 26694 // TODO(rafaelw): firstNode & lastNode should be read-synchronous | 26734 // TODO(rafaelw): firstNode & lastNode should be read-synchronous |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 27042 templateDescendents.forEach(bootstrap); | 27082 templateDescendents.forEach(bootstrap); |
| 27043 } | 27083 } |
| 27044 | 27084 |
| 27045 final String _allTemplatesSelectors = 'template, option[template], ' + | 27085 final String _allTemplatesSelectors = 'template, option[template], ' + |
| 27046 Element._TABLE_TAGS.keys.map((k) => "$k[template]").join(", "); | 27086 Element._TABLE_TAGS.keys.map((k) => "$k[template]").join(", "); |
| 27047 | 27087 |
| 27048 void _addBindings(Node node, model, [CustomBindingSyntax syntax]) { | 27088 void _addBindings(Node node, model, [CustomBindingSyntax syntax]) { |
| 27049 if (node is Element) { | 27089 if (node is Element) { |
| 27050 _addAttributeBindings(node, model, syntax); | 27090 _addAttributeBindings(node, model, syntax); |
| 27051 } else if (node is Text) { | 27091 } else if (node is Text) { |
| 27052 _parseAndBind(node, node.text, 'text', model, syntax); | 27092 _parseAndBind(node, 'text', node.text, model, syntax); |
| 27053 } | 27093 } |
| 27054 | 27094 |
| 27055 for (var c = node.$dom_firstChild; c != null; c = c.nextNode) { | 27095 for (var c = node.$dom_firstChild; c != null; c = c.nextNode) { |
| 27056 _addBindings(c, model, syntax); | 27096 _addBindings(c, model, syntax); |
| 27057 } | 27097 } |
| 27058 } | 27098 } |
| 27059 | 27099 |
| 27060 | 27100 |
| 27061 void _addAttributeBindings(Element element, model, syntax) { | 27101 void _addAttributeBindings(Element element, model, syntax) { |
| 27062 element.attributes.forEach((name, value) { | 27102 element.attributes.forEach((name, value) { |
| 27063 if (value == '' && (name == 'bind' || name == 'repeat')) { | 27103 if (value == '' && (name == 'bind' || name == 'repeat')) { |
| 27064 value = '{{}}'; | 27104 value = '{{}}'; |
| 27065 } | 27105 } |
| 27066 _parseAndBind(element, value, name, model, syntax); | 27106 _parseAndBind(element, name, value, model, syntax); |
| 27067 }); | 27107 }); |
| 27068 } | 27108 } |
| 27069 | 27109 |
| 27070 void _parseAndBind(Node node, String text, String name, model, | 27110 void _parseAndBind(Node node, String name, String text, model, |
| 27071 CustomBindingSyntax syntax) { | 27111 CustomBindingSyntax syntax) { |
| 27072 | 27112 |
| 27073 var tokens = _parseMustacheTokens(text); | 27113 var tokens = _parseMustacheTokens(text); |
| 27074 if (tokens.length == 0 || (tokens.length == 1 && tokens[0].isText)) { | 27114 if (tokens.length == 0 || (tokens.length == 1 && tokens[0].isText)) { |
| 27075 return; | 27115 return; |
| 27076 } | 27116 } |
| 27077 | 27117 |
| 27078 if (tokens.length == 1 && tokens[0].isBinding) { | 27118 if (tokens.length == 1 && tokens[0].isBinding) { |
| 27079 _bindOrDelegate(node, name, model, tokens[0].value, syntax); | 27119 _bindOrDelegate(node, name, model, tokens[0].value, syntax); |
| 27080 return; | 27120 return; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 27195 var templateIterator = child._templateIterator; | 27235 var templateIterator = child._templateIterator; |
| 27196 if (templateIterator != null) { | 27236 if (templateIterator != null) { |
| 27197 templateIterator.abandon(); | 27237 templateIterator.abandon(); |
| 27198 child._templateIterator = null; | 27238 child._templateIterator = null; |
| 27199 } | 27239 } |
| 27200 } | 27240 } |
| 27201 child.remove(); | 27241 child.remove(); |
| 27202 _removeAllBindingsRecursively(child); | 27242 _removeAllBindingsRecursively(child); |
| 27203 } | 27243 } |
| 27204 | 27244 |
| 27205 class _InstanceCursor { | |
| 27206 final Element _template; | |
| 27207 Node _terminator; | |
| 27208 Node _previousTerminator; | |
| 27209 int _previousIndex = -1; | |
| 27210 int _index = 0; | |
| 27211 | |
| 27212 _InstanceCursor(this._template, [index]) { | |
| 27213 _terminator = _template; | |
| 27214 if (index != null) { | |
| 27215 while (index-- > 0) { | |
| 27216 next(); | |
| 27217 } | |
| 27218 } | |
| 27219 } | |
| 27220 | |
| 27221 void next() { | |
| 27222 _previousTerminator = _terminator; | |
| 27223 _previousIndex = _index; | |
| 27224 _index++; | |
| 27225 | |
| 27226 while (_index > _terminator._instanceTerminatorCount) { | |
| 27227 _index -= _terminator._instanceTerminatorCount; | |
| 27228 _terminator = _terminator.nextNode; | |
| 27229 if (_terminator is Element && _terminator.tagName == 'TEMPLATE') { | |
| 27230 _index += _instanceCount(_terminator); | |
| 27231 } | |
| 27232 } | |
| 27233 } | |
| 27234 | |
| 27235 void abandon() { | |
| 27236 assert(_instanceCount(_template) > 0); | |
| 27237 assert(_terminator._instanceTerminatorCount > 0); | |
| 27238 assert(_index > 0); | |
| 27239 | |
| 27240 _terminator._instanceTerminatorCount--; | |
| 27241 _index--; | |
| 27242 } | |
| 27243 | |
| 27244 void insert(fragment) { | |
| 27245 assert(_template.parentNode != null); | |
| 27246 | |
| 27247 _previousTerminator = _terminator; | |
| 27248 _previousIndex = _index; | |
| 27249 _index++; | |
| 27250 | |
| 27251 _terminator = fragment.$dom_lastChild; | |
| 27252 if (_terminator == null) _terminator = _previousTerminator; | |
| 27253 _template.parentNode.insertBefore(fragment, _previousTerminator.nextNode); | |
| 27254 | |
| 27255 _terminator._instanceTerminatorCount++; | |
| 27256 if (_terminator != _previousTerminator) { | |
| 27257 while (_previousTerminator._instanceTerminatorCount > | |
| 27258 _previousIndex) { | |
| 27259 _previousTerminator._instanceTerminatorCount--; | |
| 27260 _terminator._instanceTerminatorCount++; | |
| 27261 } | |
| 27262 } | |
| 27263 } | |
| 27264 | |
| 27265 void remove() { | |
| 27266 assert(_previousIndex != -1); | |
| 27267 assert(_previousTerminator != null && | |
| 27268 (_previousIndex > 0 || _previousTerminator == _template)); | |
| 27269 assert(_terminator != null && _index > 0); | |
| 27270 assert(_template.parentNode != null); | |
| 27271 assert(_instanceCount(_template) > 0); | |
| 27272 | |
| 27273 if (_previousTerminator == _terminator) { | |
| 27274 assert(_index == _previousIndex + 1); | |
| 27275 _terminator._instanceTerminatorCount--; | |
| 27276 _terminator = _template; | |
| 27277 _previousTerminator = null; | |
| 27278 _previousIndex = -1; | |
| 27279 return; | |
| 27280 } | |
| 27281 | |
| 27282 _terminator._instanceTerminatorCount--; | |
| 27283 | |
| 27284 var parent = _template.parentNode; | |
| 27285 while (_previousTerminator.nextNode != _terminator) { | |
| 27286 _removeTemplateChild(parent, _previousTerminator.nextNode); | |
| 27287 } | |
| 27288 _removeTemplateChild(parent, _terminator); | |
| 27289 | |
| 27290 _terminator = _previousTerminator; | |
| 27291 _index = _previousIndex; | |
| 27292 _previousTerminator = null; | |
| 27293 _previousIndex = -1; // 0? | |
| 27294 } | |
| 27295 } | |
| 27296 | |
| 27297 | 27245 |
| 27298 class _TemplateIterator { | 27246 class _TemplateIterator { |
| 27299 final Element _templateElement; | 27247 final Element _templateElement; |
| 27300 int instanceCount = 0; | 27248 final List<Node> terminators = []; |
| 27249 final CompoundBinding inputs; |
| 27301 List iteratedValue; | 27250 List iteratedValue; |
| 27302 bool observing = false; | |
| 27303 final CompoundBinding inputs; | |
| 27304 | 27251 |
| 27305 StreamSubscription _sub; | 27252 StreamSubscription _sub; |
| 27306 StreamSubscription _valueBinding; | 27253 StreamSubscription _valueBinding; |
| 27307 | 27254 |
| 27308 _TemplateIterator(this._templateElement) | 27255 _TemplateIterator(this._templateElement) |
| 27309 : inputs = new CompoundBinding(resolveInputs) { | 27256 : inputs = new CompoundBinding(resolveInputs) { |
| 27310 | 27257 |
| 27311 _valueBinding = new PathObserver(inputs, 'value').bindSync(valueChanged); | 27258 _valueBinding = new PathObserver(inputs, 'value').bindSync(valueChanged); |
| 27312 } | 27259 } |
| 27313 | 27260 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 27336 if (value is Observable) { | 27283 if (value is Observable) { |
| 27337 _sub = value.changes.listen(_handleChanges); | 27284 _sub = value.changes.listen(_handleChanges); |
| 27338 } | 27285 } |
| 27339 | 27286 |
| 27340 int len = iteratedValue.length; | 27287 int len = iteratedValue.length; |
| 27341 if (len > 0) { | 27288 if (len > 0) { |
| 27342 _handleChanges([new ListChangeRecord(0, addedCount: len)]); | 27289 _handleChanges([new ListChangeRecord(0, addedCount: len)]); |
| 27343 } | 27290 } |
| 27344 } | 27291 } |
| 27345 | 27292 |
| 27346 // TODO(jmesserly): port MDV v3. | 27293 Node getTerminatorAt(int index) { |
| 27347 getInstanceModel(model, syntax) => model; | 27294 if (index == -1) return _templateElement; |
| 27348 getInstanceFragment(syntax) => _templateElement.createInstance(); | 27295 var terminator = terminators[index]; |
| 27296 if (terminator is! Element) return terminator; |
| 27297 |
| 27298 var subIterator = terminator._templateIterator; |
| 27299 if (subIterator == null) return terminator; |
| 27300 |
| 27301 return subIterator.getTerminatorAt(subIterator.terminators.length - 1); |
| 27302 } |
| 27303 |
| 27304 void insertInstanceAt(int index, Node fragment) { |
| 27305 var previousTerminator = getTerminatorAt(index - 1); |
| 27306 var terminator = fragment.$dom_lastChild; |
| 27307 if (terminator == null) terminator = previousTerminator; |
| 27308 |
| 27309 terminators.insert(index, terminator); |
| 27310 var parent = _templateElement.parentNode; |
| 27311 parent.insertBefore(fragment, previousTerminator.nextNode); |
| 27312 } |
| 27313 |
| 27314 void removeInstanceAt(int index) { |
| 27315 var previousTerminator = getTerminatorAt(index - 1); |
| 27316 var terminator = getTerminatorAt(index); |
| 27317 terminators.removeAt(index); |
| 27318 |
| 27319 var parent = _templateElement.parentNode; |
| 27320 while (terminator != previousTerminator) { |
| 27321 var node = terminator; |
| 27322 terminator = node.previousNode; |
| 27323 _removeTemplateChild(parent, node); |
| 27324 } |
| 27325 } |
| 27326 |
| 27327 void removeAllInstances() { |
| 27328 if (terminators.length == 0) return; |
| 27329 |
| 27330 var previousTerminator = _templateElement; |
| 27331 var terminator = getTerminatorAt(terminators.length - 1); |
| 27332 terminators.length = 0; |
| 27333 |
| 27334 var parent = _templateElement.parentNode; |
| 27335 while (terminator != previousTerminator) { |
| 27336 var node = terminator; |
| 27337 terminator = node.previousNode; |
| 27338 _removeTemplateChild(parent, node); |
| 27339 } |
| 27340 } |
| 27341 |
| 27342 void clear() { |
| 27343 unobserve(); |
| 27344 removeAllInstances(); |
| 27345 iteratedValue = null; |
| 27346 } |
| 27347 |
| 27348 getInstanceModel(model, syntax) { |
| 27349 if (syntax != null) { |
| 27350 return syntax.getInstanceModel(_templateElement, model); |
| 27351 } |
| 27352 return model; |
| 27353 } |
| 27354 |
| 27355 getInstanceFragment(syntax) { |
| 27356 if (syntax != null) { |
| 27357 return syntax.getInstanceFragment(_templateElement); |
| 27358 } |
| 27359 return _templateElement.createInstance(); |
| 27360 } |
| 27349 | 27361 |
| 27350 void _handleChanges(List<ListChangeRecord> splices) { | 27362 void _handleChanges(List<ListChangeRecord> splices) { |
| 27351 var syntax = TemplateElement.syntax[_templateElement.attributes['syntax']]; | 27363 var syntax = TemplateElement.syntax[_templateElement.attributes['syntax']]; |
| 27352 | 27364 |
| 27353 for (var splice in splices) { | 27365 for (var splice in splices) { |
| 27354 if (splice is! ListChangeRecord) continue; | 27366 if (splice is! ListChangeRecord) continue; |
| 27355 | 27367 |
| 27356 for (int i = 0; i < splice.removedCount; i++) { | 27368 for (int i = 0; i < splice.removedCount; i++) { |
| 27357 var cursor = new _InstanceCursor(_templateElement, splice.index + 1); | 27369 removeInstanceAt(splice.index); |
| 27358 cursor.remove(); | |
| 27359 instanceCount--; | |
| 27360 } | 27370 } |
| 27361 | 27371 |
| 27362 for (var addIndex = splice.index; | 27372 for (var addIndex = splice.index; |
| 27363 addIndex < splice.index + splice.addedCount; | 27373 addIndex < splice.index + splice.addedCount; |
| 27364 addIndex++) { | 27374 addIndex++) { |
| 27365 | 27375 |
| 27366 var model = getInstanceModel(iteratedValue[addIndex], syntax); | 27376 var model = getInstanceModel(iteratedValue[addIndex], syntax); |
| 27377 |
| 27367 var fragment = getInstanceFragment(syntax); | 27378 var fragment = getInstanceFragment(syntax); |
| 27368 | 27379 |
| 27369 _addBindings(fragment, model, syntax); | 27380 _addBindings(fragment, model, syntax); |
| 27370 _addTemplateInstanceRecord(fragment, model); | 27381 _addTemplateInstanceRecord(fragment, model); |
| 27371 | 27382 |
| 27372 var cursor = new _InstanceCursor(_templateElement, addIndex); | 27383 insertInstanceAt(addIndex, fragment); |
| 27373 cursor.insert(fragment); | |
| 27374 instanceCount++; | |
| 27375 } | 27384 } |
| 27376 } | 27385 } |
| 27377 } | 27386 } |
| 27378 | 27387 |
| 27379 void unobserve() { | 27388 void unobserve() { |
| 27380 if (_sub == null) return; | 27389 if (_sub == null) return; |
| 27381 _sub.cancel(); | 27390 _sub.cancel(); |
| 27382 _sub = null; | 27391 _sub = null; |
| 27383 } | 27392 } |
| 27384 | 27393 |
| 27385 void clear() { | |
| 27386 unobserve(); | |
| 27387 | |
| 27388 iteratedValue = null; | |
| 27389 if (instanceCount == 0) return; | |
| 27390 | |
| 27391 for (var i = 0; i < instanceCount; i++) { | |
| 27392 var cursor = new _InstanceCursor(_templateElement, 1); | |
| 27393 cursor.remove(); | |
| 27394 } | |
| 27395 | |
| 27396 instanceCount = 0; | |
| 27397 } | |
| 27398 | |
| 27399 void abandon() { | 27394 void abandon() { |
| 27400 unobserve(); | 27395 unobserve(); |
| 27401 _valueBinding.cancel(); | 27396 _valueBinding.cancel(); |
| 27402 inputs.dispose(); | 27397 inputs.dispose(); |
| 27403 } | 27398 } |
| 27404 } | 27399 } |
| 27405 | |
| 27406 int _instanceCount(Element element) { | |
| 27407 var templateIterator = element._templateIterator; | |
| 27408 return templateIterator != null ? templateIterator.instanceCount : 0; | |
| 27409 } | |
| 27410 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 27400 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 27411 // for details. All rights reserved. Use of this source code is governed by a | 27401 // for details. All rights reserved. Use of this source code is governed by a |
| 27412 // BSD-style license that can be found in the LICENSE file. | 27402 // BSD-style license that can be found in the LICENSE file. |
| 27413 | 27403 |
| 27414 | 27404 |
| 27415 /** | 27405 /** |
| 27416 * Helper class to implement custom events which wrap DOM events. | 27406 * Helper class to implement custom events which wrap DOM events. |
| 27417 */ | 27407 */ |
| 27418 class _WrappedEvent implements Event { | 27408 class _WrappedEvent implements Event { |
| 27419 final Event wrapped; | 27409 final Event wrapped; |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 28650 } | 28640 } |
| 28651 | 28641 |
| 28652 _send(msg) { | 28642 _send(msg) { |
| 28653 _sendToHelperIsolate(msg, _sendPort); | 28643 _sendToHelperIsolate(msg, _sendPort); |
| 28654 } | 28644 } |
| 28655 } | 28645 } |
| 28656 | 28646 |
| 28657 get _pureIsolateTimerFactoryClosure => | 28647 get _pureIsolateTimerFactoryClosure => |
| 28658 ((int milliSeconds, void callback(Timer time), bool repeating) => | 28648 ((int milliSeconds, void callback(Timer time), bool repeating) => |
| 28659 new _PureIsolateTimer(milliSeconds, callback, repeating)); | 28649 new _PureIsolateTimer(milliSeconds, callback, repeating)); |
| OLD | NEW |