Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(520)

Side by Side Diff: pkg/third_party/html5lib/lib/dom.dart

Issue 224733003: Fix how document fragments are added on NodeList operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/third_party/html5lib/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /// A simple tree API that results from parsing html. Intended to be compatible 1 /// A simple tree API that results from parsing html. Intended to be compatible
2 /// with dart:html, but right now it resembles the classic JS DOM. 2 /// with dart:html, but right now it resembles the classic JS DOM.
3 library dom; 3 library dom;
4 4
5 import 'dart:collection'; 5 import 'dart:collection';
6 import 'package:source_maps/span.dart' show FileSpan; 6 import 'package:source_maps/span.dart' show FileSpan;
7 7
8 import 'src/constants.dart'; 8 import 'src/constants.dart';
9 import 'src/list_proxy.dart'; 9 import 'src/list_proxy.dart';
10 import 'src/token.dart'; 10 import 'src/token.dart';
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 644
645 Node _setParent(Node node) { 645 Node _setParent(Node node) {
646 // Note: we need to remove the node from its previous parent node, if any, 646 // Note: we need to remove the node from its previous parent node, if any,
647 // before updating its parent pointer to point at our parent. 647 // before updating its parent pointer to point at our parent.
648 node.remove(); 648 node.remove();
649 node.parent = _parent; 649 node.parent = _parent;
650 return node; 650 return node;
651 } 651 }
652 652
653 void add(Node value) { 653 void add(Node value) {
654 super.add(_setParent(value)); 654 if (value is DocumentFragment) {
655 addAll(value.nodes);
656 } else {
657 super.add(_setParent(value));
658 }
655 } 659 }
656 660
657 void addLast(Node value) => add(value); 661 void addLast(Node value) => add(value);
658 662
659 void addAll(Iterable<Node> collection) { 663 void addAll(Iterable<Node> collection) {
660 // Note: we need to be careful if collection is another NodeList. 664 // Note: we need to be careful if collection is another NodeList.
661 // In particular: 665 // In particular:
662 // 1. we need to copy the items before updating their parent pointers, 666 // 1. we need to copy the items before updating their parent pointers,
663 // 2. we should update parent pointers in reverse order. That way they 667 // 2. we should update parent pointers in reverse order. That way they
664 // are removed from the original NodeList (if any) from the end, which 668 // are removed from the original NodeList (if any) from the end, which
665 // is faster. 669 // is faster.
666 var list = (collection is NodeList || collection is! List) 670 var list = (collection is NodeList || collection is! List)
667 ? collection.toList() : collection as List; 671 ? collection.toList() : collection as List;
668 for (var node in list.reversed) _setParent(node); 672 for (var node in list.reversed) _setParent(node);
669 super.addAll(list); 673
674 for (var node in list) {
675 if (node is DocumentFragment) {
676 addAll(node.nodes);
677 } else {
678 super.add(node);
679 }
680 }
670 } 681 }
671 682
672 void insert(int index, Node value) { 683 void insert(int index, Node value) {
673 super.insert(index, _setParent(value)); 684 if (value is DocumentFragment) {
685 insertAll(index, value.nodes);
686 } else {
687 super.insert(index, _setParent(value));
688 }
674 } 689 }
675 690
676 Node removeLast() => super.removeLast()..parent = null; 691 Node removeLast() => super.removeLast()..parent = null;
677 692
678 Node removeAt(int i) => super.removeAt(i)..parent = null; 693 Node removeAt(int i) => super.removeAt(i)..parent = null;
679 694
680 void clear() { 695 void clear() {
681 for (var node in this) node.parent = null; 696 for (var node in this) node.parent = null;
682 super.clear(); 697 super.clear();
683 } 698 }
684 699
685 void operator []=(int index, Node value) { 700 void operator []=(int index, Node value) {
686 this[index].parent = null; 701 if (value is DocumentFragment) {
687 super[index] = _setParent(value); 702 removeAt(index);
703 insertAll(index, value.nodes);
704 } else {
705 this[index].parent = null;
706 super[index] = _setParent(value);
707 }
688 } 708 }
689 709
690 // TODO(jmesserly): These aren't implemented in DOM _NodeListImpl, see 710 // TODO(jmesserly): These aren't implemented in DOM _NodeListImpl, see
691 // http://code.google.com/p/dart/issues/detail?id=5371 711 // http://code.google.com/p/dart/issues/detail?id=5371
692 void setRange(int start, int rangeLength, List<Node> from, 712 void setRange(int start, int rangeLength, List<Node> from,
693 [int startFrom = 0]) { 713 [int startFrom = 0]) {
694 if (from is NodeList) { 714 if (from is NodeList) {
695 // Note: this is presumed to make a copy 715 // Note: this is presumed to make a copy
696 from = from.sublist(startFrom, startFrom + rangeLength); 716 from = from.sublist(startFrom, startFrom + rangeLength);
697 } 717 }
698 // Note: see comment in [addAll]. We need to be careful about the order of 718 // Note: see comment in [addAll]. We need to be careful about the order of
699 // operations if [from] is also a NodeList. 719 // operations if [from] is also a NodeList.
700 for (int i = rangeLength - 1; i >= 0; i--) { 720 for (int i = rangeLength - 1; i >= 0; i--) {
701 this[start + i].parent = null; 721 this[start + i] = from[startFrom + i];
702 super[start + i] = _setParent(from[startFrom + i]);
703 } 722 }
704 } 723 }
705 724
706 void replaceRange(int start, int end, Iterable<Node> newContents) { 725 void replaceRange(int start, int end, Iterable<Node> newContents) {
707 removeRange(start, end); 726 removeRange(start, end);
708 insertAll(start, newContents); 727 insertAll(start, newContents);
709 } 728 }
710 729
711 void removeRange(int start, int rangeLength) { 730 void removeRange(int start, int rangeLength) {
712 for (int i = start; i < rangeLength; i++) this[i].parent = null; 731 for (int i = start; i < rangeLength; i++) this[i].parent = null;
713 super.removeRange(start, rangeLength); 732 super.removeRange(start, rangeLength);
714 } 733 }
715 734
716 void removeWhere(bool test(Element e)) { 735 void removeWhere(bool test(Element e)) {
717 for (var node in where(test)) { 736 for (var node in where(test)) {
718 node.parent = null; 737 node.parent = null;
719 } 738 }
720 super.removeWhere(test); 739 super.removeWhere(test);
721 } 740 }
722 741
723 void retainWhere(bool test(Element e)) { 742 void retainWhere(bool test(Element e)) {
724 for (var node in where((n) => !test(n))) { 743 for (var node in where((n) => !test(n))) {
725 node.parent = null; 744 node.parent = null;
726 } 745 }
727 super.retainWhere(test); 746 super.retainWhere(test);
728 } 747 }
729 748
730 void insertAll(int index, List<Node> nodes) { 749 void insertAll(int index, Iterable<Node> collection) {
731 for (var node in nodes) _setParent(node); 750 var list = (collection is NodeList || collection is! List)
732 super.insertAll(index, nodes); 751 ? collection.toList() : collection as List;
752 for (var node in list) {
753 insert(index++, node);
Jennifer Messerly 2014/04/04 18:24:55 this is O(N^2) right? would something like this wo
Siggi Cherem (dart-lang) 2014/04/04 19:31:56 Good catch. Made the change, also updated addAll t
754 }
733 } 755 }
734 } 756 }
735 757
736 758
737 /// An indexable collection of a node's descendants in the document tree, 759 /// An indexable collection of a node's descendants in the document tree,
738 /// filtered so that only elements are in the collection. 760 /// filtered so that only elements are in the collection.
739 // TODO(jmesserly): this was copied from dart:html 761 // TODO(jmesserly): this was copied from dart:html
740 // TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug. 762 // TODO(jmesserly): "implements List<Element>" is a workaround for analyzer bug.
741 class FilteredElementList extends IterableBase<Element> with ListMixin<Element> 763 class FilteredElementList extends IterableBase<Element> with ListMixin<Element>
742 implements List<Element> { 764 implements List<Element> {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 949
928 class _ConcatTextVisitor extends TreeVisitor { 950 class _ConcatTextVisitor extends TreeVisitor {
929 final _str = new StringBuffer(); 951 final _str = new StringBuffer();
930 952
931 String toString() => _str.toString(); 953 String toString() => _str.toString();
932 954
933 visitText(Text node) { 955 visitText(Text node) {
934 _str.write(node.data); 956 _str.write(node.data);
935 } 957 }
936 } 958 }
OLDNEW
« no previous file with comments | « no previous file | pkg/third_party/html5lib/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698