Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: tools/dom/templates/html/impl/impl_Node.darttemplate

Issue 13617003: Remove some usages of IterableMixinWorkaround from HTML library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/dom/templates/html/impl/impl_Element.darttemplate ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 $LIBRARYNAME; 5 part of $LIBRARYNAME;
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 extends ListBase<Node> {
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 { 19 Node get first {
20 Node result = JS('Node|Null', '#.firstChild', _this); 20 Node result = JS('Node|Null', '#.firstChild', _this);
21 if (result == null) throw new StateError("No elements"); 21 if (result == null) throw new StateError("No elements");
22 return result; 22 return result;
(...skipping 21 matching lines...) Expand all
44 return result; 44 return result;
45 } 45 }
46 Node get single { 46 Node get single {
47 int l = this.length; 47 int l = this.length;
48 if (l == 0) throw new StateError("No elements"); 48 if (l == 0) throw new StateError("No elements");
49 if (l > 1) throw new StateError("More than one element"); 49 if (l > 1) throw new StateError("More than one element");
50 return _this.$dom_firstChild; 50 return _this.$dom_firstChild;
51 } 51 }
52 $endif 52 $endif
53 53
54 Node min([int compare(Node a, Node b)]) {
55 return IterableMixinWorkaround.min(this, compare);
56 }
57
58 Node max([int compare(Node a, Node b)]) {
59 return IterableMixinWorkaround.max(this, compare);
60 }
61
62 void add(Node value) { 54 void add(Node value) {
63 _this.append(value); 55 _this.append(value);
64 } 56 }
65 57
66 void addAll(Iterable<Node> iterable) { 58 void addAll(Iterable<Node> iterable) {
67 if (iterable is _ChildNodeListLazy) { 59 if (iterable is _ChildNodeListLazy) {
68 if (!identical(iterable._this, _this)) { 60 if (!identical(iterable._this, _this)) {
69 // Optimized route for copying between nodes. 61 // Optimized route for copying between nodes.
70 for (var i = 0, len = iterable.length; i < len; ++i) { 62 for (var i = 0, len = iterable.length; i < len; ++i) {
71 // Should use $dom_firstChild, Bug 8886. 63 // Should use $dom_firstChild, Bug 8886.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 99 }
108 100
109 void remove(Object object) { 101 void remove(Object object) {
110 if (object is! Node) return; 102 if (object is! Node) return;
111 Node node = object; 103 Node node = object;
112 if (!identical(_this, node.parentNode)) return; 104 if (!identical(_this, node.parentNode)) return;
113 _this.$dom_removeChild(node); 105 _this.$dom_removeChild(node);
114 } 106 }
115 107
116 void removeAll(Iterable elements) { 108 void removeAll(Iterable elements) {
117 IterableMixinWorkaround.removeAll(this, elements); 109 // This is not using the default removeAll from ListBase because
110 // DOM nodes can be efficiently removed in constant time.
111 for (var element in elements) {
112 remove(element);
113 }
114 }
115
116 void _filter(bool test(Node node), bool removeMatching) {
117 // This implementation of removeWhere/retainWhere is more efficient
118 // than the default in ListBase. Child nodes can be removed in constant
119 // time.
120 Node child = _this.$dom_firstChild;
121 while (child != null) {
122 Node nextChild = child.nextSibling;
123 if (test(child) == removeMatching) {
124 _this.$dom_removeChild(child);
125 }
126 child = nextChild;
127 }
118 } 128 }
119 129
120 void retainAll(Iterable elements) { 130 void retainAll(Iterable elements) {
121 IterableMixinWorkaround.retainAll(this, elements); 131 Set retainSet = (elements is Set) ? elements : elements.toSet();
132 _filter(retainSet.contains, false);
122 } 133 }
123 134
124 void removeWhere(bool test(Node node)) { 135 void removeWhere(bool test(Node node)) {
125 IterableMixinWorkaround.removeWhere(this, test); 136 _filter(test, true);
126 } 137 }
127 138
128 void retainWhere(bool test(Node node)) { 139 void retainWhere(bool test(Node node)) {
129 IterableMixinWorkaround.retainWhere(this, test); 140 _filter(test, false);
130 } 141 }
131 142
132 void clear() { 143 void clear() {
133 _this.text = ''; 144 _this.text = '';
134 } 145 }
135 146
136 void operator []=(int index, Node value) { 147 void operator []=(int index, Node value) {
137 _this.$dom_replaceChild(value, this[index]); 148 _this.$dom_replaceChild(value, this[index]);
138 } 149 }
139 150
140 Iterator<Node> get iterator => _this.$dom_childNodes.iterator; 151 Iterator<Node> get iterator => _this.$dom_childNodes.iterator;
141 152
142 // TODO(jacobr): We can implement these methods much more efficiently by
143 // looking up the nodeList only once instead of once per iteration.
144 bool contains(Node element) => IterableMixinWorkaround.contains(this, element) ;
145
146 void forEach(void f(Node element)) => IterableMixinWorkaround.forEach(this, f) ;
147
148 dynamic reduce(dynamic initialValue,
149 dynamic combine(dynamic previousValue, Node element)) {
150 return IterableMixinWorkaround.reduce(this, initialValue, combine);
151 }
152
153 dynamic fold(dynamic initialValue,
154 dynamic combine(dynamic previousValue, Node element)) {
155 return IterableMixinWorkaround.fold(this, initialValue, combine);
156 }
157
158 String join([String separator]) {
159 return IterableMixinWorkaround.joinList(this, separator);
160 }
161
162 Iterable map(f(Node element)) {
163 return IterableMixinWorkaround.mapList(this, f);
164 }
165
166 Iterable<Node> where(bool f(Node element)) {
167 return IterableMixinWorkaround.where(this, f);
168 }
169
170 Iterable expand(Iterable f(Node element)) {
171 return IterableMixinWorkaround.expand(this, f);
172 }
173
174 bool every(bool f(Node element)) => IterableMixinWorkaround.every(this, f);
175
176 bool any(bool f(Node element)) => IterableMixinWorkaround.any(this, f);
177
178 List<Node> toList({ bool growable: true }) => 153 List<Node> toList({ bool growable: true }) =>
179 new List<Node>.from(this, growable: growable); 154 new List<Node>.from(this, growable: growable);
180 Set<Node> toSet() => new Set<Node>.from(this); 155 Set<Node> toSet() => new Set<Node>.from(this);
181 156
182 bool get isEmpty => this.length == 0; 157 bool get isEmpty => this.length == 0;
183 158
184 // From List<Node>: 159 // From List<Node>:
185 160
186 Iterable<Node> take(int n) {
187 return IterableMixinWorkaround.takeList(this, n);
188 }
189
190 Iterable<Node> takeWhile(bool test(Node value)) {
191 return IterableMixinWorkaround.takeWhile(this, test);
192 }
193
194 Iterable<Node> skip(int n) {
195 return IterableMixinWorkaround.skipList(this, n);
196 }
197
198 Iterable<Node> skipWhile(bool test(Node value)) {
199 return IterableMixinWorkaround.skipWhile(this, test);
200 }
201
202 Node firstWhere(bool test(Node value), {Node orElse()}) {
203 return IterableMixinWorkaround.firstWhere(this, test, orElse);
204 }
205
206 Node lastWhere(bool test(Node value), {Node orElse()}) {
207 return IterableMixinWorkaround.lastWhereList(this, test, orElse);
208 }
209
210 Node singleWhere(bool test(Node value)) {
211 return IterableMixinWorkaround.singleWhere(this, test);
212 }
213
214 Node elementAt(int index) {
215 return this[index];
216 }
217
218 Iterable<Node> get reversed {
219 return IterableMixinWorkaround.reversedList(this);
220 }
221
222 // TODO(jacobr): this could be implemented for child node lists. 161 // TODO(jacobr): this could be implemented for child node lists.
223 // The exception we throw here is misleading. 162 // The exception we throw here is misleading.
224 void sort([int compare(Node a, Node b)]) { 163 void sort([int compare(Node a, Node b)]) {
225 throw new UnsupportedError("Cannot sort immutable List."); 164 throw new UnsupportedError("Cannot sort immutable List.");
226 } 165 }
227 166
228 int indexOf(Node element, [int start = 0]) =>
229 Lists.indexOf(this, element, start, this.length);
230
231 int lastIndexOf(Node element, [int start = 0]) =>
232 Lists.lastIndexOf(this, element, start);
233
234 // FIXME: implement these. 167 // FIXME: implement these.
235 void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) { 168 void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
236 throw new UnsupportedError( 169 throw new UnsupportedError(
237 "Cannot setRange on immutable List."); 170 "Cannot setRange on immutable List.");
238 } 171 }
239 void removeRange(int start, int rangeLength) { 172 void removeRange(int start, int rangeLength) {
240 throw new UnsupportedError( 173 throw new UnsupportedError(
241 "Cannot removeRange on immutable List."); 174 "Cannot removeRange on immutable List.");
242 } 175 }
243 void insertRange(int start, int rangeLength, [Node initialValue]) { 176 void insertRange(int start, int rangeLength, [Node initialValue]) {
(...skipping 19 matching lines...) Expand all
263 // TODO(jacobr): benchmark whether this is more efficient or whether caching 196 // TODO(jacobr): benchmark whether this is more efficient or whether caching
264 // a local copy of $dom_childNodes is more efficient. 197 // a local copy of $dom_childNodes is more efficient.
265 int get length => _this.$dom_childNodes.length; 198 int get length => _this.$dom_childNodes.length;
266 199
267 void set length(int value) { 200 void set length(int value) {
268 throw new UnsupportedError( 201 throw new UnsupportedError(
269 "Cannot set length on immutable List."); 202 "Cannot set length on immutable List.");
270 } 203 }
271 204
272 Node operator[](int index) => _this.$dom_childNodes[index]; 205 Node operator[](int index) => _this.$dom_childNodes[index];
273
274 Map<int, Node> asMap() => IterableMixinWorkaround.asMapList(this);
275 } 206 }
276 207
277 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { 208 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
278 List<Node> get nodes { 209 List<Node> get nodes {
279 return new _ChildNodeListLazy(this); 210 return new _ChildNodeListLazy(this);
280 } 211 }
281 212
282 void set nodes(Collection<Node> value) { 213 void set nodes(Collection<Node> value) {
283 // Copy list first since we don't want liveness during iteration. 214 // Copy list first since we don't want liveness during iteration.
284 // TODO(jacobr): there is a better way to do this. 215 // TODO(jacobr): there is a better way to do this.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 */ 348 */
418 Stream<Node> get onModelChanged { 349 Stream<Node> get onModelChanged {
419 if (_modelChangedStream == null) { 350 if (_modelChangedStream == null) {
420 // Ensure the model is cached locally to minimize change notifications. 351 // Ensure the model is cached locally to minimize change notifications.
421 _model = model; 352 _model = model;
422 _modelChangedStream = new StreamController.broadcast(); 353 _modelChangedStream = new StreamController.broadcast();
423 } 354 }
424 return _modelChangedStream.stream; 355 return _modelChangedStream.stream;
425 } 356 }
426 357
427 /** 358 /**
428 * Print out a String representation of this Node. 359 * Print out a String representation of this Node.
429 */ 360 */
430 String toString() => localName == null ? 361 String toString() => localName == null ?
431 (nodeValue == null ? super.toString() : nodeValue) : localName; 362 (nodeValue == null ? super.toString() : nodeValue) : localName;
432 363
433 $!MEMBERS 364 $!MEMBERS
434 } 365 }
OLDNEW
« no previous file with comments | « tools/dom/templates/html/impl/impl_Element.darttemplate ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698