| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 $LIBRARYNAME; | 5 part of $LIBRARYNAME; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Lazy implementation of the child nodes of an element that does not request | 8 * Lazy implementation of the child nodes of an element that does not request |
| 9 * the actual child nodes of an element until strictly necessary greatly | 9 * the actual child nodes of an element until strictly necessary greatly |
| 10 * improving performance for the typical cases where it is not required. | 10 * improving performance for the typical cases where it is not required. |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 * nodes. | 292 * nodes. |
| 293 * | 293 * |
| 294 * Currently this does not support propagation through Shadow DOMs. | 294 * Currently this does not support propagation through Shadow DOMs. |
| 295 * | 295 * |
| 296 * [clearModel] must be used to remove the model property from this node | 296 * [clearModel] must be used to remove the model property from this node |
| 297 * and have the model inherit from ancestor nodes. | 297 * and have the model inherit from ancestor nodes. |
| 298 */ | 298 */ |
| 299 @Experimental | 299 @Experimental |
| 300 get model { | 300 get model { |
| 301 // If we have a change handler then we've cached the model locally. | 301 // If we have a change handler then we've cached the model locally. |
| 302 if (!_modelChangedStreams.isEmpty) { | 302 if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) { |
| 303 return _model; | 303 return _model; |
| 304 } | 304 } |
| 305 // Otherwise start looking up the tree. | 305 // Otherwise start looking up the tree. |
| 306 for (var node = this; node != null; node = node.parentNode) { | 306 for (var node = this; node != null; node = node.parentNode) { |
| 307 if (node._hasLocalModel == true) { | 307 if (node._hasLocalModel == true) { |
| 308 return node._model; | 308 return node._model; |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 return null; | 311 return null; |
| 312 } | 312 } |
| 313 | 313 |
| 314 @Experimental | 314 @Experimental |
| 315 void set model(value) { | 315 void set model(value) { |
| 316 var changed = model != value; | 316 var changed = model != value; |
| 317 _model = value; | 317 _model = value; |
| 318 _hasLocalModel = true; | 318 _hasLocalModel = true; |
| 319 _ModelTreeObserver.initialize(); | 319 _ModelTreeObserver.initialize(); |
| 320 | 320 |
| 321 if (changed) { | 321 if (changed) { |
| 322 if (!_modelChangedStreams.isEmpty) { | 322 if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) { |
| 323 _modelChangedStreams.toList().forEach((stream) => stream.add(this)); | 323 _modelChangedStreams.toList().forEach((stream) => stream.add(this)); |
| 324 } | 324 } |
| 325 // Propagate new model to all descendants. | 325 // Propagate new model to all descendants. |
| 326 _ModelTreeObserver.propagateModel(this, value, false); | 326 _ModelTreeObserver.propagateModel(this, value, false); |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 | 329 |
| 330 /** | 330 /** |
| 331 * Clears the locally set model and makes this model be inherited from parent | 331 * Clears the locally set model and makes this model be inherited from parent |
| 332 * nodes. | 332 * nodes. |
| 333 */ | 333 */ |
| 334 @Experimental | 334 @Experimental |
| 335 void clearModel() { | 335 void clearModel() { |
| 336 if (_hasLocalModel == true) { | 336 if (_hasLocalModel == true) { |
| 337 _hasLocalModel = false; | 337 _hasLocalModel = false; |
| 338 | 338 |
| 339 // Propagate new model to all descendants. | 339 // Propagate new model to all descendants. |
| 340 if (parentNode != null) { | 340 if (parentNode != null) { |
| 341 _ModelTreeObserver.propagateModel(this, parentNode.model, false); | 341 _ModelTreeObserver.propagateModel(this, parentNode.model, false); |
| 342 } else { | 342 } else { |
| 343 _ModelTreeObserver.propagateModel(this, null, false); | 343 _ModelTreeObserver.propagateModel(this, null, false); |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 } | 346 } |
| 347 | 347 |
| 348 /** | 348 /** |
| 349 * Get a stream of models, whenever the model changes. | 349 * Get a stream of models, whenever the model changes. |
| 350 */ | 350 */ |
| 351 Stream<Node> get onModelChanged { | 351 Stream<Node> get onModelChanged { |
| 352 var result; | 352 if (_modelChangedStreams == null) { |
| 353 result = new StreamController( | 353 _modelChangedStreams = new Set<StreamController<Node>>(); |
| 354 onListen: () { _modelChangedStreams.add(result); }, | 354 } |
| 355 onCancel: () { _modelChangedStreams.remove(result); }); | 355 var controller; |
| 356 return result; | 356 controller = new StreamController( |
| 357 onListen: () { _modelChangedStreams.add(controller); }, |
| 358 onCancel: () { _modelChangedStreams.remove(controller); }); |
| 359 return controller.stream; |
| 357 } | 360 } |
| 358 | 361 |
| 359 /** | 362 /** |
| 360 * Print out a String representation of this Node. | 363 * Print out a String representation of this Node. |
| 361 */ | 364 */ |
| 362 String toString() => localName == null ? | 365 String toString() => localName == null ? |
| 363 (nodeValue == null ? super.toString() : nodeValue) : localName; | 366 (nodeValue == null ? super.toString() : nodeValue) : localName; |
| 364 | 367 |
| 365 $!MEMBERS | 368 $!MEMBERS |
| 366 } | 369 } |
| OLD | NEW |