| 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 |