| 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 /** | 7 /** |
| 8 * Lazy implementation of the child nodes of an element that does not request | 8 * Lazy implementation of the child nodes of an element that does not request |
| 9 * the actual child nodes of an element until strictly necessary greatly | 9 * the actual child nodes of an element until strictly necessary greatly |
| 10 * improving performance for the typical cases where it is not required. | 10 * improving performance for the typical cases where it is not required. |
| 11 */ | 11 */ |
| 12 class _ChildNodeListLazy implements List { | 12 class _ChildNodeListLazy implements List { |
| 13 final Node _this; | 13 final Node _this; |
| 14 | 14 |
| 15 _ChildNodeListLazy(this._this); | 15 _ChildNodeListLazy(this._this); |
| 16 | 16 |
| 17 | 17 |
| 18 $if DART2JS | 18 $if DART2JS |
| 19 Node get first => JS('Node', '#.firstChild', _this); | 19 Node get first { |
| 20 Node get last => JS('Node', '#.lastChild', _this); | 20 Node result = JS('Node', '#.firstChild', _this); |
| 21 if (result == null) throw new StateError("No elements"); |
| 22 return result; |
| 23 } |
| 24 Node get last { |
| 25 Node result = JS('Node', '#.lastChild', _this); |
| 26 if (result == null) throw new StateError("No elements"); |
| 27 return result; |
| 28 } |
| 29 Node get single { |
| 30 int l = this.length; |
| 31 if (l == 0) throw new StateError("No elements"); |
| 32 if (l > 1) throw new StateError("More than one element"); |
| 33 return JS('Node', '#.firstChild', _this); |
| 34 } |
| 21 $else | 35 $else |
| 22 Node get first => _this.$dom_firstChild; | 36 Node get first { |
| 23 Node get last => _this.$dom_lastChild; | 37 Node result = _this.$dom_firstChild; |
| 38 if (result == null) throw new StateError("No elements"); |
| 39 return result; |
| 40 } |
| 41 Node get last { |
| 42 Node result = _this.$dom_lastChild; |
| 43 if (result == null) throw new StateError("No elements"); |
| 44 return result; |
| 45 } |
| 46 Node get single { |
| 47 int l = this.length; |
| 48 if (l == 0) throw new StateError("No elements"); |
| 49 if (l > 1) throw new StateError("More than one element"); |
| 50 return _this.$dom_firstChild; |
| 51 } |
| 24 $endif | 52 $endif |
| 25 | 53 |
| 54 Node min([int compare(Node a, Node b)]) { |
| 55 return _Collections.minInList(this, compare); |
| 56 } |
| 57 |
| 58 Node max([int compare(Node a, Node b)]) { |
| 59 return _Collections.maxInList(this, compare); |
| 60 } |
| 61 |
| 26 void add(Node value) { | 62 void add(Node value) { |
| 27 _this.$dom_appendChild(value); | 63 _this.$dom_appendChild(value); |
| 28 } | 64 } |
| 29 | 65 |
| 30 void addLast(Node value) { | 66 void addLast(Node value) { |
| 31 _this.$dom_appendChild(value); | 67 _this.$dom_appendChild(value); |
| 32 } | 68 } |
| 33 | 69 |
| 34 | 70 |
| 35 void addAll(Collection<Node> collection) { | 71 void addAll(Iterable<Node> iterable) { |
| 36 for (Node node in collection) { | 72 for (Node node in iterable) { |
| 37 _this.$dom_appendChild(node); | 73 _this.$dom_appendChild(node); |
| 38 } | 74 } |
| 39 } | 75 } |
| 40 | 76 |
| 41 Node removeLast() { | 77 Node removeLast() { |
| 42 final result = last; | 78 final result = last; |
| 43 if (result != null) { | 79 if (result != null) { |
| 44 _this.$dom_removeChild(result); | 80 _this.$dom_removeChild(result); |
| 45 } | 81 } |
| 46 return result; | 82 return result; |
| 47 } | 83 } |
| 48 | 84 |
| 49 Node removeAt(int index) { | 85 Node removeAt(int index) { |
| 50 var result = this[index]; | 86 var result = this[index]; |
| 51 if (result != null) { | 87 if (result != null) { |
| 52 _this.$dom_removeChild(result); | 88 _this.$dom_removeChild(result); |
| 53 } | 89 } |
| 54 return result; | 90 return result; |
| 55 } | 91 } |
| 56 | 92 |
| 57 void clear() { | 93 void clear() { |
| 58 _this.text = ''; | 94 _this.text = ''; |
| 59 } | 95 } |
| 60 | 96 |
| 61 void operator []=(int index, Node value) { | 97 void operator []=(int index, Node value) { |
| 62 _this.$dom_replaceChild(value, this[index]); | 98 _this.$dom_replaceChild(value, this[index]); |
| 63 } | 99 } |
| 64 | 100 |
| 65 Iterator<Node> iterator() => _this.$dom_childNodes.iterator(); | 101 Iterator<Node> get iterator => _this.$dom_childNodes.iterator; |
| 66 | 102 |
| 67 // TODO(jacobr): We can implement these methods much more efficiently by | 103 // TODO(jacobr): We can implement these methods much more efficiently by |
| 68 // looking up the nodeList only once instead of once per iteration. | 104 // looking up the nodeList only once instead of once per iteration. |
| 69 bool contains(Node element) => Collections.contains(this, element); | 105 bool contains(Node element) => Collections.contains(this, element); |
| 70 | 106 |
| 71 void forEach(void f(Node element)) => Collections.forEach(this, f); | 107 void forEach(void f(Node element)) => Collections.forEach(this, f); |
| 72 | 108 |
| 73 dynamic reduce(dynamic initialValue, | 109 dynamic reduce(dynamic initialValue, |
| 74 dynamic combine(dynamic previousValue, Node element)) { | 110 dynamic combine(dynamic previousValue, Node element)) { |
| 75 return Collections.reduce(this, initialValue, combine); | 111 return Collections.reduce(this, initialValue, combine); |
| 76 } | 112 } |
| 77 | 113 |
| 78 Collection map(f(Node element)) => Collections.map(this, [], f); | 114 String join([String separator]) { |
| 115 return Collections.joinList(this, separator); |
| 116 } |
| 79 | 117 |
| 80 Collection<Node> filter(bool f(Node element)) => | 118 List mappedBy(f(Node element)) => |
| 81 Collections.filter(this, <Node>[], f); | 119 new MappedList<Node, dynamic>(this, f); |
| 120 |
| 121 Iterable<Node> where(bool f(Node element)) => |
| 122 new WhereIterable<Node>(this, f); |
| 82 | 123 |
| 83 bool every(bool f(Node element)) => Collections.every(this, f); | 124 bool every(bool f(Node element)) => Collections.every(this, f); |
| 84 | 125 |
| 85 bool some(bool f(Node element)) => Collections.some(this, f); | 126 bool any(bool f(Node element)) => Collections.any(this, f); |
| 86 | 127 |
| 87 bool get isEmpty => this.length == 0; | 128 bool get isEmpty => this.length == 0; |
| 88 | 129 |
| 89 // From List<Node>: | 130 // From List<Node>: |
| 90 | 131 |
| 132 List<Node> take(int n) { |
| 133 return new ListView<Node>(this, 0, n); |
| 134 } |
| 135 |
| 136 Iterable<Node> takeWhile(bool test(Node value)) { |
| 137 return new TakeWhileIterable<Node>(this, test); |
| 138 } |
| 139 |
| 140 List<Node> skip(int n) { |
| 141 return new ListView<Node>(this, n, null); |
| 142 } |
| 143 |
| 144 Iterable<Node> skipWhile(bool test(Node value)) { |
| 145 return new SkipWhileIterable<Node>(this, test); |
| 146 } |
| 147 |
| 148 Node firstMatching(bool test(Node value), {Node orElse()}) { |
| 149 return Collections.firstMatching(this, test, orElse); |
| 150 } |
| 151 |
| 152 Node lastMatching(bool test(Node value), {Node orElse()}) { |
| 153 return Collections.lastMatchingInList(this, test, orElse); |
| 154 } |
| 155 |
| 156 Node singleMatching(bool test(Node value)) { |
| 157 return Collections.singleMatching(this, test); |
| 158 } |
| 159 |
| 160 Node elementAt(int index) { |
| 161 return this[index]; |
| 162 } |
| 163 |
| 91 // TODO(jacobr): this could be implemented for child node lists. | 164 // TODO(jacobr): this could be implemented for child node lists. |
| 92 // The exception we throw here is misleading. | 165 // The exception we throw here is misleading. |
| 93 void sort([int compare(Node a, Node b)]) { | 166 void sort([int compare(Node a, Node b)]) { |
| 94 throw new UnsupportedError("Cannot sort immutable List."); | 167 throw new UnsupportedError("Cannot sort immutable List."); |
| 95 } | 168 } |
| 96 | 169 |
| 97 int indexOf(Node element, [int start = 0]) => | 170 int indexOf(Node element, [int start = 0]) => |
| 98 Lists.indexOf(this, element, start, this.length); | 171 Lists.indexOf(this, element, start, this.length); |
| 99 | 172 |
| 100 int lastIndexOf(Node element, [int start = 0]) => | 173 int lastIndexOf(Node element, [int start = 0]) => |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 final Node parent = this.parentNode; | 241 final Node parent = this.parentNode; |
| 169 parent.$dom_replaceChild(otherNode, this); | 242 parent.$dom_replaceChild(otherNode, this); |
| 170 } catch (e) { | 243 } catch (e) { |
| 171 | 244 |
| 172 }; | 245 }; |
| 173 return this; | 246 return this; |
| 174 } | 247 } |
| 175 | 248 |
| 176 $!MEMBERS | 249 $!MEMBERS |
| 177 } | 250 } |
| OLD | NEW |