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 /** | |
6 * Lazy implementation of the child nodes of an element that does not request | |
7 * the actual child nodes of an element until strictly necessary greatly | |
8 * improving performance for the typical cases where it is not required. | |
9 */ | |
10 class _ChildNodeListLazy implements NodeList { | |
11 final _NodeImpl _this; | |
12 | |
13 _ChildNodeListLazy(this._this); | |
14 | |
15 | |
16 $if FROG | |
17 _NodeImpl get first() native "return this._this.firstChild;"; | |
18 _NodeImpl last() native "return this._this.lastChild;"; | |
19 $else | |
20 _NodeImpl get first() => _this.$dom_firstChild; | |
21 _NodeImpl last() => _this.$dom_lastChild; | |
22 $endif | |
23 | |
24 void add(_NodeImpl value) { | |
25 _this.$dom_appendChild(value); | |
26 } | |
27 | |
28 void addLast(_NodeImpl value) { | |
29 _this.$dom_appendChild(value); | |
30 } | |
31 | |
32 | |
33 void addAll(Collection<_NodeImpl> collection) { | |
34 for (_NodeImpl node in collection) { | |
35 _this.$dom_appendChild(node); | |
36 } | |
37 } | |
38 | |
39 _NodeImpl removeLast() { | |
40 final last = last(); | |
41 if (last != null) { | |
42 _this.$dom_removeChild(last); | |
43 } | |
44 return last; | |
45 } | |
46 | |
47 void clear() { | |
48 _this.text = ''; | |
49 } | |
50 | |
51 void operator []=(int index, _NodeImpl value) { | |
52 _this.$dom_replaceChild(value, this[index]); | |
53 } | |
54 | |
55 Iterator<Node> iterator() => _this.$dom_childNodes.iterator(); | |
56 | |
57 // TODO(jacobr): We can implement these methods much more efficiently by | |
58 // looking up the nodeList only once instead of once per iteration. | |
59 void forEach(void f(Node element)) => _Collections.forEach(this, f); | |
60 | |
61 Collection map(f(Node element)) => _Collections.map(this, [], f); | |
62 | |
63 Collection<Node> filter(bool f(Node element)) => | |
64 new _NodeListWrapper(_Collections.filter(this, <Node>[], f)); | |
65 | |
66 bool every(bool f(Node element)) => _Collections.every(this, f); | |
67 | |
68 bool some(bool f(Node element)) => _Collections.some(this, f); | |
69 | |
70 bool isEmpty() => this.length == 0; | |
arv (Not doing code reviews)
2012/03/28 22:37:48
This should be this.$dom_firstChild != null
lengt
| |
71 | |
72 // From List<Node>: | |
73 | |
74 // TODO(jacobr): this could be implemented for child node lists. | |
75 // The exception we throw here is misleading. | |
76 void sort(int compare(Node a, Node b)) { | |
77 throw new UnsupportedOperationException("Cannot sort immutable List."); | |
78 } | |
79 | |
80 int indexOf(Node element, [int start = 0]) => | |
81 _Lists.indexOf(this, element, start, this.length); | |
82 | |
83 int lastIndexOf(Node element, [int start = 0]) => | |
84 _Lists.lastIndexOf(this, element, start); | |
85 | |
86 // FIXME: implement thesee. | |
87 void setRange(int start, int length, List<Node> from, [int startFrom]) { | |
88 throw new UnsupportedOperationException( | |
89 "Cannot setRange on immutable List."); | |
90 } | |
91 void removeRange(int start, int length) { | |
92 throw new UnsupportedOperationException( | |
93 "Cannot removeRange on immutable List."); | |
94 } | |
95 void insertRange(int start, int length, [Node initialValue]) { | |
96 throw new UnsupportedOperationException( | |
97 "Cannot insertRange on immutable List."); | |
98 } | |
99 NodeList getRange(int start, int length) => | |
100 new _NodeListWrapper(_Lists.getRange(this, start, length, <Node>[])); | |
101 | |
102 // -- end List<Node> mixins. | |
103 | |
104 // TODO(jacobr): benchmark whether this is more efficient or whether caching | |
105 // a local copy of $dom_childNodes is more efficient. | |
106 int get length() => _this.$dom_childNodes.length; | |
107 | |
108 _NodeImpl operator[](int index) => _this.$dom_childNodes[index]; | |
109 } | |
110 | |
5 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { | 111 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { |
6 _NodeListImpl get nodes() { | 112 _ChildNodeListLazy get nodes() { |
7 final list = _childNodes; | 113 return new _ChildNodeListLazy(this); |
8 list._parent = this; | |
9 return list; | |
10 } | 114 } |
11 | 115 |
12 void set nodes(Collection<Node> value) { | 116 void set nodes(Collection<Node> value) { |
13 // Copy list first since we don't want liveness during iteration. | 117 // Copy list first since we don't want liveness during iteration. |
14 // TODO(jacobr): there is a better way to do this. | 118 // TODO(jacobr): there is a better way to do this. |
15 List copy = new List.from(value); | 119 List copy = new List.from(value); |
16 text = ''; | 120 text = ''; |
17 for (Node node in copy) { | 121 for (Node node in copy) { |
18 _appendChild(node); | 122 $dom_appendChild(node); |
19 } | 123 } |
20 } | 124 } |
21 | 125 |
22 // TODO(jacobr): should we throw an exception if parent is already null? | 126 // TODO(jacobr): should we throw an exception if parent is already null? |
23 _NodeImpl remove() { | 127 _NodeImpl remove() { |
24 if (this.parent != null) { | 128 if (this.parent != null) { |
25 final _NodeImpl parent = this.parent; | 129 final _NodeImpl parent = this.parent; |
26 parent._removeChild(this); | 130 parent.$dom_removeChild(this); |
27 } | 131 } |
28 return this; | 132 return this; |
29 } | 133 } |
30 | 134 |
31 _NodeImpl replaceWith(Node otherNode) { | 135 _NodeImpl replaceWith(Node otherNode) { |
32 try { | 136 try { |
33 final _NodeImpl parent = this.parent; | 137 final _NodeImpl parent = this.parent; |
34 parent._replaceChild(otherNode, this); | 138 parent.$dom_replaceChild(otherNode, this); |
35 } catch(var e) { | 139 } catch(var e) { |
36 | 140 |
37 }; | 141 }; |
38 return this; | 142 return this; |
39 } | 143 } |
40 | 144 |
41 $!MEMBERS | 145 $!MEMBERS |
42 } | 146 } |
OLD | NEW |