OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 class _ChildrenNodeList implements NodeList { | |
6 // Raw node. | |
7 final _node; | |
8 final _childNodes; | |
9 | |
10 _ChildrenNodeList._wrap(var node) | |
11 : _childNodes = node.childNodes, | |
12 _node = node; | |
13 | |
14 List<Node> _toList() { | |
15 final output = new List(_childNodes.length); | |
16 for (int i = 0, len = _childNodes.length; i < len; i++) { | |
17 output[i] = LevelDom.wrapNode(_childNodes[i]); | |
18 } | |
19 return output; | |
20 } | |
21 | |
22 Node get first() { | |
23 return LevelDom.wrapNode(_node.firstChild); | |
24 } | |
25 | |
26 void forEach(void f(Node element)) => _toList().forEach(f); | |
27 | |
28 Collection map(f(Node element)) => _toList().map(f); | |
29 | |
30 NodeList filter(bool f(Node element)) => new _NodeList(_toList().filter(f)); | |
31 | |
32 bool every(bool f(Node element)) { | |
33 for(Node element in this) { | |
34 if (!f(element)) { | |
35 return false; | |
36 } | |
37 }; | |
38 return true; | |
39 } | |
40 | |
41 bool some(bool f(Node element)) { | |
42 for(Node element in this) { | |
43 if (f(element)) { | |
44 return true; | |
45 } | |
46 }; | |
47 return false; | |
48 } | |
49 | |
50 /** @domName Node.hasChildNodes */ | |
51 bool isEmpty() { | |
52 return !_node.hasChildNodes(); | |
53 } | |
54 | |
55 int get length() { | |
56 return _childNodes.length; | |
57 } | |
58 | |
59 Node operator [](int index) { | |
60 return LevelDom.wrapNode(_childNodes[index]); | |
61 } | |
62 | |
63 void operator []=(int index, Node value) { | |
64 _node.replaceChild(LevelDom.unwrap(value), _childNodes[index]); | |
65 } | |
66 | |
67 void set length(int newLength) { | |
68 throw new UnsupportedOperationException(''); | |
69 } | |
70 | |
71 /** @domName Node.appendChild */ | |
72 Node add(Node value) { | |
73 _node.appendChild(LevelDom.unwrap(value)); | |
74 return value; | |
75 } | |
76 | |
77 Node addLast(Node value) { | |
78 _node.appendChild(LevelDom.unwrap(value)); | |
79 return value; | |
80 } | |
81 | |
82 Iterator<Node> iterator() { | |
83 return _toList().iterator(); | |
84 } | |
85 | |
86 void addAll(Collection<Node> collection) { | |
87 for (Node node in collection) { | |
88 _node.appendChild(LevelDom.unwrap(node)); | |
89 } | |
90 } | |
91 | |
92 void sort(int compare(Node a, Node b)) { | |
93 throw const UnsupportedOperationException('TODO(jacobr): should we impl?'); | |
94 } | |
95 | |
96 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) { | |
97 throw 'Not impl yet. todo(jacobr)'; | |
98 } | |
99 | |
100 void setRange(int start, int length, List from, [int startFrom = 0]) => | |
101 Lists.setRange(this, start, length, from, startFrom); | |
102 | |
103 void removeRange(int start, int length) => | |
104 Lists.removeRange(this, start, length, (i) => this[i].remove()); | |
105 | |
106 void insertRange(int start, int length, [initialValue = null]) { | |
107 throw const NotImplementedException(); | |
108 } | |
109 | |
110 NodeList getRange(int start, int length) => | |
111 new _NodeList(Lists.getRange(this, start, length)); | |
112 | |
113 int indexOf(Node element, [int start = 0]) { | |
114 return Lists.indexOf(this, element, start, this.length); | |
115 } | |
116 | |
117 int lastIndexOf(Node element, [int start = null]) { | |
118 if (start === null) start = length - 1; | |
119 return Lists.lastIndexOf(this, element, start); | |
120 } | |
121 | |
122 void clear() { | |
123 _node.textContent = ''; | |
124 } | |
125 | |
126 Node removeLast() { | |
127 final last = this.last(); | |
128 if (last != null) { | |
129 _node.removeChild(LevelDom.unwrap(last)); | |
130 } | |
131 return last; | |
132 } | |
133 | |
134 Node last() { | |
135 return LevelDom.wrapNode(_node.lastChild); | |
136 } | |
137 } | |
138 | |
139 // TODO(nweiz): when all implementations we target have the same name for the | |
140 // coreimpl implementation of List<E>, extend that rather than wrapping. | |
141 class _ListWrapper<E> implements List<E> { | |
142 List<E> _list; | |
143 | |
144 _ListWrapper(List<E> this._list); | |
145 | |
146 Iterator<E> iterator() => _list.iterator(); | |
147 | |
148 void forEach(void f(E element)) => _list.forEach(f); | |
149 | |
150 Collection map(f(E element)) => _list.map(f); | |
151 | |
152 List<E> filter(bool f(E element)) => _list.filter(f); | |
153 | |
154 bool every(bool f(E element)) => _list.every(f); | |
155 | |
156 bool some(bool f(E element)) => _list.some(f); | |
157 | |
158 bool isEmpty() => _list.isEmpty(); | |
159 | |
160 int get length() => _list.length; | |
161 | |
162 E operator [](int index) => _list[index]; | |
163 | |
164 void operator []=(int index, E value) { _list[index] = value; } | |
165 | |
166 void set length(int newLength) { _list.length = newLength; } | |
167 | |
168 void add(E value) => _list.add(value); | |
169 | |
170 void addLast(E value) => _list.addLast(value); | |
171 | |
172 void addAll(Collection<E> collection) => _list.addAll(collection); | |
173 | |
174 void sort(int compare(E a, E b)) => _list.sort(compare); | |
175 | |
176 int indexOf(E element, [int start = 0]) => _list.indexOf(element, start); | |
177 | |
178 int lastIndexOf(E element, [int start = 0]) => | |
179 _list.lastIndexOf(element, start); | |
180 | |
181 void clear() => _list.clear(); | |
182 | |
183 E removeLast() => _list.removeLast(); | |
184 | |
185 E last() => _list.last(); | |
186 | |
187 List<E> getRange(int start, int length) => _list.getRange(start, length); | |
188 | |
189 void setRange(int start, int length, List<E> from, [int startFrom = 0]) => | |
190 _list.setRange(start, length, from, startFrom); | |
191 | |
192 void removeRange(int start, int length) => _list.removeRange(start, length); | |
193 | |
194 void insertRange(int start, int length, [E initialValue = null]) => | |
195 _list.insertRange(start, length, initialValue); | |
196 | |
197 E get first() => _list[0]; | |
198 } | |
199 | |
200 class _NodeList extends _ListWrapper<Node> implements NodeList { | |
201 _NodeList(List<Node> list) : super(list); | |
202 | |
203 NodeList filter(bool f(Node element)) => new _NodeList(super.filter(f)); | |
204 | |
205 NodeList getRange(int start, int length) => | |
206 new _NodeList(super.getRange(start, length)); | |
207 } | |
208 | |
209 class NodeWrappingImplementation extends EventTargetWrappingImplementation imple
ments Node { | |
210 NodeList _nodes; | |
211 | |
212 NodeWrappingImplementation._wrap(ptr) : super._wrap(ptr); | |
213 | |
214 void set nodes(Collection<Node> value) { | |
215 // Copy list first since we don't want liveness during iteration. | |
216 List copy = new List.from(value); | |
217 nodes.clear(); | |
218 nodes.addAll(copy); | |
219 } | |
220 | |
221 NodeList get nodes() { | |
222 if (_nodes === null) { | |
223 _nodes = new _ChildrenNodeList._wrap(_ptr); | |
224 } | |
225 return _nodes; | |
226 } | |
227 | |
228 Node get nextNode() => LevelDom.wrapNode(_ptr.nextSibling); | |
229 | |
230 Document get document() => LevelDom.wrapDocument(_ptr.ownerDocument); | |
231 | |
232 Node get parent() => LevelDom.wrapNode(_ptr.parentNode); | |
233 | |
234 Node get previousNode() => LevelDom.wrapNode(_ptr.previousSibling); | |
235 | |
236 String get text() => _ptr.textContent; | |
237 | |
238 void set text(String value) { _ptr.textContent = value; } | |
239 | |
240 // New methods implemented. | |
241 Node replaceWith(Node otherNode) { | |
242 try { | |
243 _ptr.parentNode.replaceChild(LevelDom.unwrap(otherNode), _ptr); | |
244 } catch(var e) { | |
245 // TODO(jacobr): what should we return on failure? | |
246 } | |
247 return this; | |
248 } | |
249 | |
250 Node remove() { | |
251 // TODO(jacobr): should we throw an exception if parent is already null? | |
252 if (_ptr.parentNode !== null) { | |
253 _ptr.parentNode.removeChild(_ptr); | |
254 } | |
255 return this; | |
256 } | |
257 | |
258 /** @domName contains */ | |
259 bool contains(Node otherNode) { | |
260 // TODO: Feature detect and use built in. | |
261 while (otherNode != null && otherNode != this) { | |
262 otherNode = otherNode.parent; | |
263 } | |
264 return otherNode == this; | |
265 } | |
266 | |
267 // TODO(jacobr): remove when/if List supports a method similar to | |
268 // insertBefore or we switch NodeList to implement LinkedList rather than | |
269 // array. | |
270 Node insertBefore(Node newChild, Node refChild) { | |
271 return LevelDom.wrapNode(_ptr.insertBefore( | |
272 LevelDom.unwrap(newChild), LevelDom.unwrap(refChild))); | |
273 } | |
274 | |
275 Node clone(bool deep) { | |
276 return LevelDom.wrapNode(_ptr.cloneNode(deep)); | |
277 } | |
278 } | |
OLD | NEW |