| 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 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 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 !identical(terminator, _templateElement)) { | 239 !identical(terminator, _templateElement)) { |
| 240 var subIterator = _mdv(terminator)._templateIterator; | 240 var subIterator = _mdv(terminator)._templateIterator; |
| 241 if (subIterator != null) { | 241 if (subIterator != null) { |
| 242 return subIterator.getTerminatorAt(subIterator.terminators.length - 1); | 242 return subIterator.getTerminatorAt(subIterator.terminators.length - 1); |
| 243 } | 243 } |
| 244 } | 244 } |
| 245 | 245 |
| 246 return terminator; | 246 return terminator; |
| 247 } | 247 } |
| 248 | 248 |
| 249 void insertInstanceAt(int index, List<Node> instanceNodes) { | 249 void insertInstanceAt(int index, DocumentFragment fragment, |
| 250 List<Node> instanceNodes) { |
| 251 |
| 250 var previousTerminator = getTerminatorAt(index - 1); | 252 var previousTerminator = getTerminatorAt(index - 1); |
| 251 var terminator = instanceNodes.length > 0 ? instanceNodes.last | 253 var terminator = null; |
| 252 : previousTerminator; | 254 if (fragment != null) { |
| 255 terminator = fragment.lastChild; |
| 256 } else if (instanceNodes.length > 0) { |
| 257 terminator = instanceNodes.last; |
| 258 } |
| 259 if (terminator == null) terminator = previousTerminator; |
| 253 | 260 |
| 254 terminators.insert(index, terminator); | 261 terminators.insert(index, terminator); |
| 255 | 262 |
| 256 var parent = _templateElement.parentNode; | 263 var parent = _templateElement.parentNode; |
| 257 var insertBeforeNode = previousTerminator.nextNode; | 264 var insertBeforeNode = previousTerminator.nextNode; |
| 265 |
| 266 if (fragment != null) { |
| 267 parent.insertBefore(fragment, insertBeforeNode); |
| 268 return; |
| 269 } |
| 270 |
| 258 for (var node in instanceNodes) { | 271 for (var node in instanceNodes) { |
| 259 parent.insertBefore(node, insertBeforeNode); | 272 parent.insertBefore(node, insertBeforeNode); |
| 260 } | 273 } |
| 261 } | 274 } |
| 262 | 275 |
| 263 List<Node> extractInstanceAt(int index) { | 276 List<Node> extractInstanceAt(int index) { |
| 264 var instanceNodes = <Node>[]; | 277 var instanceNodes = <Node>[]; |
| 265 var previousTerminator = getTerminatorAt(index - 1); | 278 var previousTerminator = getTerminatorAt(index - 1); |
| 266 var terminator = getTerminatorAt(index); | 279 var terminator = getTerminatorAt(index); |
| 267 terminators.removeAt(index); | 280 terminators.removeAt(index); |
| 268 | 281 |
| 269 var parent = _templateElement.parentNode; | 282 var parent = _templateElement.parentNode; |
| 270 while (terminator != previousTerminator) { | 283 while (terminator != previousTerminator) { |
| 271 var node = previousTerminator.nextNode; | 284 var node = previousTerminator.nextNode; |
| 272 if (node == terminator) terminator = previousTerminator; | 285 if (node == terminator) terminator = previousTerminator; |
| 273 node.remove(); | 286 node.remove(); |
| 274 instanceNodes.add(node); | 287 instanceNodes.add(node); |
| 275 } | 288 } |
| 276 return instanceNodes; | 289 return instanceNodes; |
| 277 } | 290 } |
| 278 | 291 |
| 279 getInstanceModel(model, BindingDelegate delegate) { | 292 getInstanceModel(model, BindingDelegate delegate) { |
| 280 if (delegate != null) { | 293 if (delegate != null) { |
| 281 return delegate.getInstanceModel(_templateElement, model); | 294 return delegate.getInstanceModel(_templateElement, model); |
| 282 } | 295 } |
| 283 return model; | 296 return model; |
| 284 } | 297 } |
| 285 | 298 |
| 286 List<Node> getInstanceNodes(model, BindingDelegate delegate, | 299 DocumentFragment getInstanceFragment(model, BindingDelegate delegate) { |
| 287 IdentityMap instanceCache) { | 300 return _templateElement.createInstance(model, delegate); |
| 288 | |
| 289 var instanceNodes = instanceCache.remove(model); | |
| 290 if (instanceNodes != null) return instanceNodes; | |
| 291 | |
| 292 var fragment = _templateElement.createInstance(model, delegate); | |
| 293 instanceNodes = fragment.nodes.toList(); | |
| 294 fragment.nodes.clear(); | |
| 295 return instanceNodes; | |
| 296 } | 301 } |
| 297 | 302 |
| 298 void _handleChanges(Iterable<ChangeRecord> splices) { | 303 void _handleChanges(Iterable<ChangeRecord> splices) { |
| 299 splices = splices.where((s) => s is ListChangeRecord); | 304 splices = splices.where((s) => s is ListChangeRecord); |
| 300 | 305 |
| 301 var template = _templateElement; | 306 var template = _templateElement; |
| 302 var delegate = template.bindingDelegate; | 307 var delegate = template.bindingDelegate; |
| 303 | 308 |
| 304 if (template.parentNode == null || template.document.window == null) { | 309 if (template.parentNode == null || template.document.window == null) { |
| 305 abandon(); | 310 abandon(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 322 } | 327 } |
| 323 | 328 |
| 324 removeDelta -= splice.addedCount; | 329 removeDelta -= splice.addedCount; |
| 325 } | 330 } |
| 326 | 331 |
| 327 for (var splice in splices) { | 332 for (var splice in splices) { |
| 328 for (var addIndex = splice.index; | 333 for (var addIndex = splice.index; |
| 329 addIndex < splice.index + splice.addedCount; | 334 addIndex < splice.index + splice.addedCount; |
| 330 addIndex++) { | 335 addIndex++) { |
| 331 | 336 |
| 332 var model = getInstanceModel(iteratedValue[addIndex], delegate); | 337 var model = iteratedValue[addIndex]; |
| 338 var fragment = null; |
| 339 var instanceNodes = instanceCache.remove(model); |
| 340 if (instanceNodes == null) { |
| 341 var actualModel = getInstanceModel(model, delegate); |
| 342 fragment = getInstanceFragment(actualModel, delegate); |
| 343 } |
| 333 | 344 |
| 334 var instanceNodes = getInstanceNodes(model, delegate, instanceCache); | 345 insertInstanceAt(addIndex, fragment, instanceNodes); |
| 335 insertInstanceAt(addIndex, instanceNodes); | |
| 336 } | 346 } |
| 337 } | 347 } |
| 338 | 348 |
| 339 for (var instanceNodes in instanceCache.values) { | 349 for (var instanceNodes in instanceCache.values) { |
| 340 instanceNodes.forEach(_unbindAllRecursively); | 350 instanceNodes.forEach(_unbindAllRecursively); |
| 341 } | 351 } |
| 342 } | 352 } |
| 343 | 353 |
| 344 void unobserve() { | 354 void unobserve() { |
| 345 if (_sub == null) return; | 355 if (_sub == null) return; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 365 nodeExt._templateIterator = null; | 375 nodeExt._templateIterator = null; |
| 366 } | 376 } |
| 367 } | 377 } |
| 368 | 378 |
| 369 _nodeOrCustom(node).unbindAll(); | 379 _nodeOrCustom(node).unbindAll(); |
| 370 for (var c = node.firstChild; c != null; c = c.nextNode) { | 380 for (var c = node.firstChild; c != null; c = c.nextNode) { |
| 371 _unbindAllRecursively(c); | 381 _unbindAllRecursively(c); |
| 372 } | 382 } |
| 373 } | 383 } |
| 374 } | 384 } |
| OLD | NEW |