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 |