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 html; | 5 part of html; |
6 | 6 |
7 // TODO(jacobr): use _Lists.dart to remove some of the duplicated | 7 // TODO(jacobr): use _Lists.dart to remove some of the duplicated |
8 // functionality. | 8 // functionality. |
9 class _ChildrenElementList implements List { | 9 class _ChildrenElementList implements List { |
10 // Raw Element. | 10 // Raw Element. |
11 final Element _element; | 11 final Element _element; |
12 final HtmlCollection _childElements; | 12 final HtmlCollection _childElements; |
13 | 13 |
14 _ChildrenElementList._wrap(Element element) | 14 _ChildrenElementList._wrap(Element element) |
15 : _childElements = element.$dom_children, | 15 : _childElements = element.$dom_children, |
16 _element = element; | 16 _element = element; |
17 | 17 |
18 List<Element> _toList() { | 18 List<Element> toList() { |
19 final output = new List(_childElements.length); | 19 final output = new List<Element>.fixedLength(_childElements.length); |
20 for (int i = 0, len = _childElements.length; i < len; i++) { | 20 for (int i = 0, len = _childElements.length; i < len; i++) { |
21 output[i] = _childElements[i]; | 21 output[i] = _childElements[i]; |
22 } | 22 } |
23 return output; | 23 return output; |
24 } | 24 } |
25 | 25 |
| 26 Set<Element> toSet() { |
| 27 final output = new Set<Element>(_childElements.length); |
| 28 for (int i = 0, len = _childElements.length; i < len; i++) { |
| 29 output.add(_childElements[i]); |
| 30 } |
| 31 return output; |
| 32 } |
| 33 |
26 bool contains(Element element) => _childElements.contains(element); | 34 bool contains(Element element) => _childElements.contains(element); |
27 | 35 |
28 void forEach(void f(Element element)) { | 36 void forEach(void f(Element element)) { |
29 for (Element element in _childElements) { | 37 for (Element element in _childElements) { |
30 f(element); | 38 f(element); |
31 } | 39 } |
32 } | 40 } |
33 | 41 |
34 List<Element> filter(bool f(Element element)) { | |
35 final output = []; | |
36 forEach((Element element) { | |
37 if (f(element)) { | |
38 output.add(element); | |
39 } | |
40 }); | |
41 return new _FrozenElementList._wrap(output); | |
42 } | |
43 | |
44 bool every(bool f(Element element)) { | 42 bool every(bool f(Element element)) { |
45 for (Element element in this) { | 43 for (Element element in this) { |
46 if (!f(element)) { | 44 if (!f(element)) { |
47 return false; | 45 return false; |
48 } | 46 } |
49 }; | 47 } |
50 return true; | 48 return true; |
51 } | 49 } |
52 | 50 |
53 bool some(bool f(Element element)) { | 51 bool any(bool f(Element element)) { |
54 for (Element element in this) { | 52 for (Element element in this) { |
55 if (f(element)) { | 53 if (f(element)) { |
56 return true; | 54 return true; |
57 } | 55 } |
58 }; | 56 } |
59 return false; | 57 return false; |
60 } | 58 } |
61 | 59 |
62 Collection map(f(Element element)) { | 60 String join([String separator]) { |
63 final out = []; | 61 return Collections.joinList(this, separator); |
64 for (Element el in this) { | |
65 out.add(f(el)); | |
66 } | |
67 return out; | |
68 } | 62 } |
69 | 63 |
| 64 List mappedBy(f(Element element)) { |
| 65 return new MappedList<Element, dynamic>(this, f); |
| 66 } |
| 67 |
| 68 Iterable<Element> where(bool f(Element element)) |
| 69 => new WhereIterable<Element>(this, f); |
| 70 |
70 bool get isEmpty { | 71 bool get isEmpty { |
71 return _element.$dom_firstElementChild == null; | 72 return _element.$dom_firstElementChild == null; |
72 } | 73 } |
73 | 74 |
| 75 List<Element> take(int n) { |
| 76 return new ListView<Element>(this, 0, n); |
| 77 } |
| 78 |
| 79 Iterable<Element> takeWhile(bool test(Element value)) { |
| 80 return new TakeWhileIterable<Element>(this, test); |
| 81 } |
| 82 |
| 83 List<Element> skip(int n) { |
| 84 return new ListView<Element>(this, n, null); |
| 85 } |
| 86 |
| 87 Iterable<Element> skipWhile(bool test(Element value)) { |
| 88 return new SkipWhileIterable<Element>(this, test); |
| 89 } |
| 90 |
| 91 Element firstMatching(bool test(Element value), {Element orElse()}) { |
| 92 return Collections.firstMatching(this, test, orElse); |
| 93 } |
| 94 |
| 95 Element lastMatching(bool test(Element value), {Element orElse()}) { |
| 96 return Collections.lastMatchingInList(this, test, orElse); |
| 97 } |
| 98 |
| 99 Element singleMatching(bool test(Element value)) { |
| 100 return Collections.singleMatching(this, test); |
| 101 } |
| 102 |
| 103 Element elementAt(int index) { |
| 104 return this[index]; |
| 105 } |
| 106 |
74 int get length { | 107 int get length { |
75 return _childElements.length; | 108 return _childElements.length; |
76 } | 109 } |
77 | 110 |
78 Element operator [](int index) { | 111 Element operator [](int index) { |
79 return _childElements[index]; | 112 return _childElements[index]; |
80 } | 113 } |
81 | 114 |
82 void operator []=(int index, Element value) { | 115 void operator []=(int index, Element value) { |
83 _element.$dom_replaceChild(value, _childElements[index]); | 116 _element.$dom_replaceChild(value, _childElements[index]); |
84 } | 117 } |
85 | 118 |
86 void set length(int newLength) { | 119 void set length(int newLength) { |
87 // TODO(jacobr): remove children when length is reduced. | 120 // TODO(jacobr): remove children when length is reduced. |
88 throw new UnsupportedError(''); | 121 throw new UnsupportedError(''); |
89 } | 122 } |
90 | 123 |
91 Element add(Element value) { | 124 Element add(Element value) { |
92 _element.$dom_appendChild(value); | 125 _element.$dom_appendChild(value); |
93 return value; | 126 return value; |
94 } | 127 } |
95 | 128 |
96 Element addLast(Element value) => add(value); | 129 Element addLast(Element value) => add(value); |
97 | 130 |
98 Iterator<Element> iterator() => _toList().iterator(); | 131 Iterator<Element> get iterator => toList().iterator; |
99 | 132 |
100 void addAll(Collection<Element> collection) { | 133 void addAll(Iterable<Element> iterable) { |
101 for (Element element in collection) { | 134 for (Element element in iterable) { |
102 _element.$dom_appendChild(element); | 135 _element.$dom_appendChild(element); |
103 } | 136 } |
104 } | 137 } |
105 | 138 |
106 void sort([int compare(Element a, Element b)]) { | 139 void sort([int compare(Element a, Element b)]) { |
107 throw new UnsupportedError('TODO(jacobr): should we impl?'); | 140 throw new UnsupportedError('TODO(jacobr): should we impl?'); |
108 } | 141 } |
109 | 142 |
110 dynamic reduce(dynamic initialValue, | 143 dynamic reduce(dynamic initialValue, |
111 dynamic combine(dynamic previousValue, Element element)) { | 144 dynamic combine(dynamic previousValue, Element element)) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 185 |
153 Element removeLast() { | 186 Element removeLast() { |
154 final result = this.last; | 187 final result = this.last; |
155 if (result != null) { | 188 if (result != null) { |
156 _element.$dom_removeChild(result); | 189 _element.$dom_removeChild(result); |
157 } | 190 } |
158 return result; | 191 return result; |
159 } | 192 } |
160 | 193 |
161 Element get first { | 194 Element get first { |
162 return _element.$dom_firstElementChild; | 195 Element result = _element.$dom_firstElementChild; |
| 196 if (result == null) throw new StateError("No elements"); |
| 197 return result; |
163 } | 198 } |
164 | 199 |
165 | 200 |
166 Element get last { | 201 Element get last { |
167 return _element.$dom_lastElementChild; | 202 Element result = _element.$dom_lastElementChild; |
| 203 if (result == null) throw new StateError("No elements"); |
| 204 return result; |
| 205 } |
| 206 |
| 207 Element get single { |
| 208 if (length > 1) throw new StateError("More than one element"); |
| 209 return first; |
| 210 } |
| 211 |
| 212 Element min([int compare(Element a, Element b)]) { |
| 213 return _Collections.minInList(this, compare); |
| 214 } |
| 215 |
| 216 Element max([int compare(Element a, Element b)]) { |
| 217 return _Collections.maxInList(this, compare); |
168 } | 218 } |
169 } | 219 } |
170 | 220 |
171 // TODO(jacobr): this is an inefficient implementation but it is hard to see | 221 // TODO(jacobr): this is an inefficient implementation but it is hard to see |
172 // a better option given that we cannot quite force NodeList to be an | 222 // a better option given that we cannot quite force NodeList to be an |
173 // ElementList as there are valid cases where a NodeList JavaScript object | 223 // ElementList as there are valid cases where a NodeList JavaScript object |
174 // contains Node objects that are not Elements. | 224 // contains Node objects that are not Elements. |
175 class _FrozenElementList implements List { | 225 class _FrozenElementList implements List { |
176 final List<Node> _nodeList; | 226 final List<Node> _nodeList; |
177 | 227 |
178 _FrozenElementList._wrap(this._nodeList); | 228 _FrozenElementList._wrap(this._nodeList); |
179 | 229 |
180 bool contains(Element element) { | 230 bool contains(Element element) { |
181 for (Element el in this) { | 231 for (Element el in this) { |
182 if (el == element) return true; | 232 if (el == element) return true; |
183 } | 233 } |
184 return false; | 234 return false; |
185 } | 235 } |
186 | 236 |
187 void forEach(void f(Element element)) { | 237 void forEach(void f(Element element)) { |
188 for (Element el in this) { | 238 for (Element el in this) { |
189 f(el); | 239 f(el); |
190 } | 240 } |
191 } | 241 } |
192 | 242 |
193 Collection map(f(Element element)) { | 243 String join([String separator]) { |
194 final out = []; | 244 return Collections.joinList(this, separator); |
195 for (Element el in this) { | |
196 out.add(f(el)); | |
197 } | |
198 return out; | |
199 } | 245 } |
200 | 246 |
201 List<Element> filter(bool f(Element element)) { | 247 List mappedBy(f(Element element)) { |
202 final out = []; | 248 return new MappedList<Element, dynamic>(this, f); |
203 for (Element el in this) { | |
204 if (f(el)) out.add(el); | |
205 } | |
206 return out; | |
207 } | 249 } |
208 | 250 |
| 251 Iterable<Element> where(bool f(Element element)) |
| 252 => new WhereIterable<Element>(this, f); |
| 253 |
209 bool every(bool f(Element element)) { | 254 bool every(bool f(Element element)) { |
210 for(Element element in this) { | 255 for(Element element in this) { |
211 if (!f(element)) { | 256 if (!f(element)) { |
212 return false; | 257 return false; |
213 } | 258 } |
214 }; | 259 }; |
215 return true; | 260 return true; |
216 } | 261 } |
217 | 262 |
218 bool some(bool f(Element element)) { | 263 bool any(bool f(Element element)) { |
219 for(Element element in this) { | 264 for(Element element in this) { |
220 if (f(element)) { | 265 if (f(element)) { |
221 return true; | 266 return true; |
222 } | 267 } |
223 }; | 268 }; |
224 return false; | 269 return false; |
225 } | 270 } |
226 | 271 |
| 272 List<Element> take(int n) { |
| 273 return new ListView<Element>(this, 0, n); |
| 274 } |
| 275 |
| 276 Iterable<Element> takeWhile(bool test(T value)) { |
| 277 return new TakeWhileIterable<Element>(this, test); |
| 278 } |
| 279 |
| 280 List<Element> skip(int n) { |
| 281 return new ListView<Element>(this, n, null); |
| 282 } |
| 283 |
| 284 Iterable<Element> skipWhile(bool test(T value)) { |
| 285 return new SkipWhileIterable<Element>(this, test); |
| 286 } |
| 287 |
| 288 Element firstMatching(bool test(Element value), {Element orElse()}) { |
| 289 return Collections.firstMatching(this, test, orElse); |
| 290 } |
| 291 |
| 292 Element lastMatching(bool test(Element value), {Element orElse()}) { |
| 293 return Collections.lastMatchingInList(this, test, orElse); |
| 294 } |
| 295 |
| 296 Element singleMatching(bool test(Element value)) { |
| 297 return Collections.singleMatching(this, test); |
| 298 } |
| 299 |
| 300 Element elementAt(int index) { |
| 301 return this[index]; |
| 302 } |
| 303 |
227 bool get isEmpty => _nodeList.isEmpty; | 304 bool get isEmpty => _nodeList.isEmpty; |
228 | 305 |
229 int get length => _nodeList.length; | 306 int get length => _nodeList.length; |
230 | 307 |
231 Element operator [](int index) => _nodeList[index]; | 308 Element operator [](int index) => _nodeList[index]; |
232 | 309 |
233 void operator []=(int index, Element value) { | 310 void operator []=(int index, Element value) { |
234 throw new UnsupportedError(''); | 311 throw new UnsupportedError(''); |
235 } | 312 } |
236 | 313 |
237 void set length(int newLength) { | 314 void set length(int newLength) { |
238 _nodeList.length = newLength; | 315 _nodeList.length = newLength; |
239 } | 316 } |
240 | 317 |
241 void add(Element value) { | 318 void add(Element value) { |
242 throw new UnsupportedError(''); | 319 throw new UnsupportedError(''); |
243 } | 320 } |
244 | 321 |
245 void addLast(Element value) { | 322 void addLast(Element value) { |
246 throw new UnsupportedError(''); | 323 throw new UnsupportedError(''); |
247 } | 324 } |
248 | 325 |
249 Iterator<Element> iterator() => new _FrozenElementListIterator(this); | 326 Iterator<Element> get iterator => new _FrozenElementListIterator(this); |
250 | 327 |
251 void addAll(Collection<Element> collection) { | 328 void addAll(Iterable<Element> iterable) { |
252 throw new UnsupportedError(''); | 329 throw new UnsupportedError(''); |
253 } | 330 } |
254 | 331 |
255 void sort([int compare(Element a, Element b)]) { | 332 void sort([int compare(Element a, Element b)]) { |
256 throw new UnsupportedError(''); | 333 throw new UnsupportedError(''); |
257 } | 334 } |
258 | 335 |
259 dynamic reduce(dynamic initialValue, | 336 dynamic reduce(dynamic initialValue, |
260 dynamic combine(dynamic previousValue, Element element)) { | 337 dynamic combine(dynamic previousValue, Element element)) { |
261 return Collections.reduce(this, initialValue, combine); | 338 return Collections.reduce(this, initialValue, combine); |
(...skipping 28 matching lines...) Expand all Loading... |
290 throw new UnsupportedError(''); | 367 throw new UnsupportedError(''); |
291 } | 368 } |
292 | 369 |
293 Element removeLast() { | 370 Element removeLast() { |
294 throw new UnsupportedError(''); | 371 throw new UnsupportedError(''); |
295 } | 372 } |
296 | 373 |
297 Element get first => _nodeList.first; | 374 Element get first => _nodeList.first; |
298 | 375 |
299 Element get last => _nodeList.last; | 376 Element get last => _nodeList.last; |
| 377 |
| 378 Element get single => _nodeList.single; |
| 379 |
| 380 Element min([int compare(Element a, Element b)]) { |
| 381 return _Collections.minInList(this, compare); |
| 382 } |
| 383 |
| 384 Element max([int compare(Element a, Element b)]) { |
| 385 return _Collections.maxInList(this, compare); |
| 386 } |
300 } | 387 } |
301 | 388 |
302 class _FrozenElementListIterator implements Iterator<Element> { | 389 class _FrozenElementListIterator implements Iterator<Element> { |
303 final _FrozenElementList _list; | 390 final _FrozenElementList _list; |
304 int _index = 0; | 391 int _index = 0; |
305 | 392 |
306 _FrozenElementListIterator(this._list); | 393 _FrozenElementListIterator(this._list); |
307 | 394 |
308 /** | 395 /** |
309 * Gets the next element in the iteration. Throws a | 396 * Moves to the next element. Returns true if the iterator is positioned |
310 * [StateError("No more elements")] if no element is left. | 397 * at an element. Returns false if it is positioned after the last element. |
311 */ | 398 */ |
312 Element next() { | 399 bool moveNext() { |
313 if (!hasNext) { | 400 int nextIndex = _index + 1; |
314 throw new StateError("No more elements"); | 401 if (nextIndex < _list.length) { |
| 402 _current = _list[nextIndex]; |
| 403 _index = nextIndex; |
| 404 return true; |
315 } | 405 } |
316 | 406 _index = _list.length; |
317 return _list[_index++]; | 407 _current = null; |
| 408 return false; |
318 } | 409 } |
319 | 410 |
320 /** | 411 /** |
321 * Returns whether the [Iterator] has elements left. | 412 * Returns the element the [Iterator] is positioned at. |
| 413 * |
| 414 * Return [:null:] if the iterator is positioned before the first, or |
| 415 * after the last element. |
322 */ | 416 */ |
323 bool get hasNext => _index < _list.length; | 417 E get current => _current; |
324 } | 418 } |
325 | 419 |
326 class _ElementCssClassSet extends CssClassSet { | 420 class _ElementCssClassSet extends CssClassSet { |
327 | 421 |
328 final Element _element; | 422 final Element _element; |
329 | 423 |
330 _ElementCssClassSet(this._element); | 424 _ElementCssClassSet(this._element); |
331 | 425 |
332 Set<String> readClasses() { | 426 Set<String> readClasses() { |
333 var s = new Set<String>(); | 427 var s = new Set<String>(); |
334 var classname = _element.$dom_className; | 428 var classname = _element.$dom_className; |
335 | 429 |
336 for (String name in classname.split(' ')) { | 430 for (String name in classname.split(' ')) { |
337 String trimmed = name.trim(); | 431 String trimmed = name.trim(); |
338 if (!trimmed.isEmpty) { | 432 if (!trimmed.isEmpty) { |
339 s.add(trimmed); | 433 s.add(trimmed); |
340 } | 434 } |
341 } | 435 } |
342 return s; | 436 return s; |
343 } | 437 } |
344 | 438 |
345 void writeClasses(Set<String> s) { | 439 void writeClasses(Set<String> s) { |
346 List list = new List.from(s); | 440 List list = new List.from(s); |
347 _element.$dom_className = Strings.join(list, ' '); | 441 _element.$dom_className = s.join(' '); |
348 } | 442 } |
349 } | 443 } |
350 | 444 |
351 /** | 445 /** |
352 * An abstract class, which all HTML elements extend. | 446 * An abstract class, which all HTML elements extend. |
353 */ | 447 */ |
354 abstract class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { | 448 abstract class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { |
355 | 449 |
356 /** | 450 /** |
357 * Creates an HTML element from a valid fragment of HTML. | 451 * Creates an HTML element from a valid fragment of HTML. |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 $if DART2JS | 880 $if DART2JS |
787 // Optimization to improve performance until the dart2js compiler inlines this | 881 // Optimization to improve performance until the dart2js compiler inlines this |
788 // method. | 882 // method. |
789 static dynamic createElement_tag(String tag) => | 883 static dynamic createElement_tag(String tag) => |
790 JS('Element', 'document.createElement(#)', tag); | 884 JS('Element', 'document.createElement(#)', tag); |
791 $else | 885 $else |
792 static Element createElement_tag(String tag) => | 886 static Element createElement_tag(String tag) => |
793 document.$dom_createElement(tag); | 887 document.$dom_createElement(tag); |
794 $endif | 888 $endif |
795 } | 889 } |
OLD | NEW |