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

Side by Side Diff: client/html/src/DocumentFragmentWrappingImplementation.dart

Issue 8355019: Make DocumentFragment implement Element. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 9 years, 2 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 | « client/html/src/DocumentFragment.dart ('k') | client/html/src/Element.dart » ('j') | 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 class FilteredElementList implements ElementList {
6 final Node _node;
7 final NodeList _childNodes;
8
9 FilteredElementList(Node node): _childNodes = node.nodes, _node = node;
10
11 // We can't memoize this, since it's possible that children will be messed
12 // with externally to this class.
13 //
14 // TODO(nweiz): Do we really need to copy the list to make the types work out?
15 List<Element> get _filtered() =>
16 new List.from(_childNodes.filter((n) => n is Element));
17
18 // Don't use _filtered.first so we can short-circuit once we find an element.
19 Element get first() {
20 for (var node in _childNodes) {
21 if (node is Element) {
22 return node;
23 }
24 }
25 return null;
26 }
27
28 void forEach(void f(Element element)) {
29 _filtered.forEach(f);
30 }
31
32 void operator []=(int index, Element value) {
33 this[index].replaceWith(value);
34 }
35
36 void set length(int newLength) {
37 var len = this.length;
38 if (newLength >= len) {
39 return;
40 } else if (newLength < 0) {
41 throw const IllegalArgumentException("Invalid list length");
42 }
43
44 removeRange(newLength - 1, len - newLength);
45 }
46
47 void add(Element value) {
48 _childNodes.add(value);
49 }
50
51 void addAll(Collection<Element> collection) {
52 collection.forEach(add);
53 }
54
55 void addLast(Element value) {
56 add(value);
57 }
58
59 void sort(int compare(Element a, Element b)) {
60 throw const UnsupportedOperationException('TODO(jacobr): should we impl?');
61 }
62
63 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) {
64 throw const NotImplementedException();
65 }
66
67 void setRange(int start, int length, List from, [int startFrom = 0]) {
68 throw const NotImplementedException();
69 }
70
71 void removeRange(int start, int length) {
72 _filtered.getRange(start, length).forEach((el) => el.remove());
73 }
74
75 void insertRange(int start, int length, [initialValue = null]) {
76 throw const NotImplementedException();
77 }
78
79 void clear() {
80 // Currently, ElementList#clear clears even non-element nodes, so we follow
81 // that behavior.
82 _childNodes.clear();
83 }
84
85 Element removeLast() {
86 var last = this.last();
87 if (last != null) {
88 last.remove();
89 }
90 return last;
91 }
92
93 Collection<Element> filter(bool f(Element element)) => _filtered.filter(f);
94 bool every(bool f(Element element)) => _filtered.every(f);
95 bool some(bool f(Element element)) => _filtered.some(f);
96 bool isEmpty() => _filtered.isEmpty();
97 int get length() => _filtered.length;
98 Element operator [](int index) => _filtered[index];
99 Iterator<Element> iterator() => _filtered.iterator();
100 List<Element> getRange(int start, int length) =>
101 _filtered.getRange(start, length);
102 int indexOf(Element element, int startIndex) =>
103 _filtered.indexOf(element, startIndex);
104 int lastIndexOf(Element element, int startIndex) =>
105 _filtered.lastIndexOf(element, startIndex);
106 Element last() => _filtered.last();
107 }
108
109 class EmptyStyleDeclaration implements CSSStyleDeclaration {
110 String get cssText() => "";
111 int get length() => 0;
112 CSSRule get parentRule() => null;
113 CSSValue getPropertyCSSValue(String propertyName) => null;
114 String getPropertyPriority(String propertyName) => "";
115 String getPropertyShorthand(String propertyName) => null;
116 String getPropertyValue(String propertyName) => null;
117 bool isPropertyImplicit(String propertyName) => false;
118 String item(int index) => "";
119
120 void set cssText(String value) {
121 throw new UnsupportedOperationException(
122 "Can't modify a frozen style declaration.");
123 }
124
125 String removeProperty(String propertyName) {
126 throw new UnsupportedOperationException(
127 "Can't modify a frozen style declaration.");
128 }
129
130 void setProperty(String propertyName, String value, [String priority]) {
131 throw new UnsupportedOperationException(
132 "Can't modify a frozen style declaration.");
133 }
134 }
135
136 class EmptyClientRect implements ClientRect {
137 num get bottom() => 0;
138 num get top() => 0;
139 num get left() => 0;
140 num get right() => 0;
141 num get height() => 0;
142 num get width() => 0;
143 }
144
5 class DocumentFragmentWrappingImplementation extends NodeWrappingImplementation implements DocumentFragment { 145 class DocumentFragmentWrappingImplementation extends NodeWrappingImplementation implements DocumentFragment {
146 ElementList _elements;
147
6 DocumentFragmentWrappingImplementation._wrap(ptr) : super._wrap(ptr) {} 148 DocumentFragmentWrappingImplementation._wrap(ptr) : super._wrap(ptr) {}
7 149
8 factory DocumentFragmentWrappingImplementation() { 150 factory DocumentFragmentWrappingImplementation() {
9 return new DocumentFragmentWrappingImplementation._wrap( 151 return new DocumentFragmentWrappingImplementation._wrap(
10 dom.document.createDocumentFragment()); 152 dom.document.createDocumentFragment());
11 } 153 }
12 154
13 Element query(String selectors) { 155 factory DocumentFragmentWrappingImplementation.html(String html) {
14 return LevelDom.wrapElement(_ptr.querySelector(selectors)); 156 var fragment = new DocumentFragment();
15 } 157 fragment.innerHTML = html;
16 158 return fragment;
17 ElementList queryAll(String selectors) { 159 }
18 return LevelDom.wrapElementList(_ptr.querySelectorAll(selectors)); 160
19 } 161 ElementList get elements() {
20 } 162 if (_elements == null) {
163 _elements = new FilteredElementList(this);
164 }
165 return _elements;
166 }
167
168 // TODO: The type of value should be Collection<Element>. See http://b/5392897
169 void set elements(value) {
170 // Copy list first since we don't want liveness during iteration.
171 List copy = new List.from(value);
172 final elements = this.elements;
173 elements.clear();
174 elements.addAll(copy);
175 }
176
177 String get innerHTML() {
178 var e = new Element.tag("div");
179 e.nodes.add(this.clone(true));
180 return e.innerHTML;
181 }
182
183 String get outerHTML() => innerHTML;
184
185 void set innerHTML(String value) {
186 this.nodes.clear();
187
188 var e = new Element.tag("div");
189 e.innerHTML = value;
190
191 // Copy list first since we don't want liveness during iteration.
192 List nodes = new List.from(e.nodes);
193 this.nodes.addAll(nodes);
194 }
195
196 Node _insertAdjacentNode(String where, Node node) {
197 switch (where.toLowerCase()) {
198 case "beforebegin": return null;
199 case "afterend": return null;
200 case "afterbegin":
201 this.insertBefore(node, nodes.first);
202 return node;
203 case "beforeend":
204 this.nodes.add(node);
205 return node;
206 default:
207 throw new IllegalArgumentException("Invalid position ${where}");
208 }
209 }
210
211 Element insertAdjacentElement([String where = null, Element element = null])
212 => this._insertAdjacentNode(where, element);
213
214 void insertAdjacentText([String where = null, String text = null]) {
215 this._insertAdjacentNode(where, new Text(text));
216 }
217
218 void insertAdjacentHTML(
219 [String position_OR_where = null, String text = null]) {
220 this._insertAdjacentNode(
221 position_OR_where, new DocumentFragment.html(text));
222 }
223
224 ElementEvents get on() {
225 if (_on === null) {
226 _on = new ElementEventsImplementation._wrap(_ptr);
227 }
228 return _on;
229 }
230
231 Element query(String selectors) =>
232 LevelDom.wrapElement(_ptr.querySelector(selectors));
233
234 ElementList queryAll(String selectors) =>
235 LevelDom.wrapElementList(_ptr.querySelectorAll(selectors));
236
237 // If we can come up with a semi-reasonable default value for an Element
238 // getter, we'll use it. In general, these return the same values as an
239 // element that has no parent.
240 int get clientHeight() => 0;
241 int get clientWidth() => 0;
242 int get offsetHeight() => 0;
243 int get offsetWidth() => 0;
244 int get scrollHeight() => 0;
245 int get scrollWidth() => 0;
246 int get clientLeft() => 0;
247 int get clientTop() => 0;
248 int get offsetLeft() => 0;
249 int get offsetTop() => 0;
250 int get scrollLeft() => 0;
251 int get scrollTop() => 0;
252 String get contentEditable() => "false";
253 bool get isContentEditable() => false;
254 bool get draggable() => false;
255 bool get hidden() => false;
256 bool get spellcheck() => false;
257 int get tabIndex() => -1;
258 String get id() => "";
259 String get title() => "";
260 String get tagName() => "";
261 String get webkitdropzone() => "";
262 Element get firstElementChild() => elements.first();
263 Element get lastElementChild() => elements.last;
264 Element get nextElementSibling() => null;
265 Element get previousElementSibling() => null;
266 Element get offsetParent() => null;
267 Element get parent() => null;
268 Map<String, String> get attributes() => const {};
269 // Issue 174: this should be a const set.
270 Set<String> get classes() => new Set<String>();
271 Map<String, String> get dataAttributes() => const {};
272 CSSStyleDeclaration get style() => new EmptyStyleDeclaration();
273 ClientRect getBoundingClientRect() => new EmptyClientRect();
274 List<ClientRect> getClientRects() => const [];
275 bool matchesSelector([String selectors]) => false;
276
277 // Imperative Element methods are made into no-ops, as they are on parentless
278 // elements.
279 void blur() {}
280 void focus() {}
281 void scrollByLines([int lines]) {}
282 void scrollByPages([int pages]) {}
283 void scrollIntoView([bool centerIfNeeded]) {}
284
285 // Setters throw errors rather than being no-ops because we aren't going to
286 // retain the values that were set, and erroring out seems clearer.
287 void set attributes(Map<String, String> value) {
288 throw new UnsupportedOperationException(
289 "Attributes can't be set for document fragments.");
290 }
291
292 void set classes(Collection<String> value) {
293 throw new UnsupportedOperationException(
294 "Classes can't be set for document fragments.");
295 }
296
297 void set dataAttributes(Map<String, String> value) {
298 throw new UnsupportedOperationException(
299 "Data attributes can't be set for document fragments.");
300 }
301
302 void set contentEditable(String value) {
303 throw new UnsupportedOperationException(
304 "Content editable can't be set for document fragments.");
305 }
306
307 String get dir() {
308 throw new UnsupportedOperationException(
309 "Document fragments don't support text direction.");
310 }
311
312 void set dir(String value) {
313 throw new UnsupportedOperationException(
314 "Document fragments don't support text direction.");
315 }
316
317 void set draggable(bool value) {
318 throw new UnsupportedOperationException(
319 "Draggable can't be set for document fragments.");
320 }
321
322 void set hidden(bool value) {
323 throw new UnsupportedOperationException(
324 "Hidden can't be set for document fragments.");
325 }
326
327 void set id(String value) {
328 throw new UnsupportedOperationException(
329 "ID can't be set for document fragments.");
330 }
331
332 String get lang() {
333 throw new UnsupportedOperationException(
334 "Document fragments don't support language.");
335 }
336
337 void set lang(String value) {
338 throw new UnsupportedOperationException(
339 "Document fragments don't support language.");
340 }
341
342 void set scrollLeft(int value) {
343 throw new UnsupportedOperationException(
344 "Document fragments don't support scrolling.");
345 }
346
347 void set scrollTop(int value) {
348 throw new UnsupportedOperationException(
349 "Document fragments don't support scrolling.");
350 }
351
352 void set spellcheck(bool value) {
353 throw new UnsupportedOperationException(
354 "Spellcheck can't be set for document fragments.");
355 }
356
357 void set tabIndex(int value) {
358 throw new UnsupportedOperationException(
359 "Tab index can't be set for document fragments.");
360 }
361
362 void set title(String value) {
363 throw new UnsupportedOperationException(
364 "Title can't be set for document fragments.");
365 }
366
367 void set webkitdropzone(String value) {
368 throw new UnsupportedOperationException(
369 "WebKit drop zone can't be set for document fragments.");
370 }
371 }
OLDNEW
« no previous file with comments | « client/html/src/DocumentFragment.dart ('k') | client/html/src/Element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698