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

Side by Side Diff: tools/dom/src/dart2js_CssClassSet.dart

Issue 1054863002: CssClassSet upgrade (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix webcomponents test, IE toggle. Created 5 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/src/CssClassSet.dart ('k') | tools/dom/src/dartium_CssClassSet.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of html;
6
7 /**
8 * A set (union) of the CSS classes that are present in a set of elements.
9 * Implemented separately from _ElementCssClassSet for performance.
10 */
11 class _MultiElementCssClassSet extends CssClassSetImpl {
12 final Iterable<Element> _elementIterable;
13
14 // TODO(sra): Perhaps we should store the DomTokenList instead.
15 final List<CssClassSetImpl> _sets;
16
17 factory _MultiElementCssClassSet(Iterable<Element> elements) {
18 return new _MultiElementCssClassSet._(elements,
19 elements.map((Element e) => e.classes).toList());
20 }
21
22 _MultiElementCssClassSet._(this._elementIterable, this._sets);
23
24 Set<String> readClasses() {
25 var s = new LinkedHashSet<String>();
26 _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
27 return s;
28 }
29
30 void writeClasses(Set<String> s) {
31 var classes = s.join(' ');
32 for (Element e in _elementIterable) {
33 e.className = classes;
34 }
35 }
36
37 /**
38 * Helper method used to modify the set of css classes on this element.
39 *
40 * f - callback with:
41 * s - a Set of all the css class name currently on this element.
42 *
43 * After f returns, the modified set is written to the
44 * className property of this element.
45 */
46 modify( f(Set<String> s)) {
47 _sets.forEach((CssClassSetImpl e) => e.modify(f));
48 }
49
50 /**
51 * Adds the class [value] to the element if it is not on it, removes it if it
52 * is.
53 *
54 * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
55 * underlying toggle returns an 'is set' flag.
56 */
57 bool toggle(String value, [bool shouldAdd]) =>
58 _sets.fold(false,
59 (bool changed, CssClassSetImpl e) =>
60 e.toggle(value, shouldAdd) || changed);
61
62 /**
63 * Remove the class [value] from element, and return true on successful
64 * removal.
65 *
66 * This is the Dart equivalent of jQuery's
67 * [removeClass](http://api.jquery.com/removeClass/).
68 */
69 bool remove(Object value) => _sets.fold(false,
70 (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
71 }
72
73 class _ElementCssClassSet extends CssClassSetImpl {
74 final Element _element;
75
76 _ElementCssClassSet(this._element);
77
78 Set<String> readClasses() {
79 var s = new LinkedHashSet<String>();
80 var classname = _element.className;
81
82 for (String name in classname.split(' ')) {
83 String trimmed = name.trim();
84 if (!trimmed.isEmpty) {
85 s.add(trimmed);
86 }
87 }
88 return s;
89 }
90
91 void writeClasses(Set<String> s) {
92 _element.className = s.join(' ');
93 }
94
95 int get length => _classListLength(_classListOf(_element));
96 bool get isEmpty => length == 0;
97 bool get isNotEmpty => length != 0;
98
99 void clear() {
100 _element.className = '';
101 }
102
103 bool contains(String value) {
104 return _contains(_element, value);
105 }
106
107 bool add(String value) {
108 return _add(_element, value);
109 }
110
111 bool remove(Object value) {
112 return value is String && _remove(_element, value);
113 }
114
115 bool toggle(String value, [bool shouldAdd]) {
116 return _toggle(_element, value, shouldAdd);
117 }
118
119 void addAll(Iterable<String> iterable) {
120 _addAll(_element, iterable);
121 }
122
123 void removeAll(Iterable<String> iterable) {
124 _removeAll(_element, iterable);
125 }
126
127 void retainAll(Iterable<String> iterable) {
128 _removeWhere(_element, iterable.toSet().contains, false);
129 }
130
131 void removeWhere(bool test(String name)) {
132 _removeWhere(_element, test, true);
133 }
134
135 void retainWhere(bool test(String name)) {
136 _removeWhere(_element, test, false);
137 }
138
139 static bool _contains(Element _element, String value) {
140 return _classListContains(_classListOf(_element), value);
141 }
142
143 static bool _add(Element _element, String value) {
144 DomTokenList list = _classListOf(_element);
145 // Compute returned result independently of action upon the set. One day we
146 // will be able to optimize it way if unused.
147 bool added = !_classListContains(list, value);
148 _classListAdd(list, value);
149 return added;
150 }
151
152 static bool _remove(Element _element, String value) {
153 DomTokenList list = _classListOf(_element);
154 bool removed = _classListContains(list, value);
155 _classListRemove(list, value);
156 return removed;
157 }
158
159 static bool _toggle(Element _element, String value, bool shouldAdd) {
160 // There is no value that can be passed as the second argument of
161 // DomTokenList.toggle that behaves the same as passing one argument.
162 // `null` is seen as false, meaning 'remove'.
163 return shouldAdd == null
164 ? _toggleDefault(_element, value)
165 : _toggleOnOff(_element, value, shouldAdd);
166 }
167
168 static bool _toggleDefault(Element _element, String value) {
169 DomTokenList list = _classListOf(_element);
170 return _classListToggle1(list, value);
171 }
172
173 static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
174 DomTokenList list = _classListOf(_element);
175 // IE's toggle does not take a second parameter. We would prefer:
176 //
177 // return _classListToggle2(list, value, shouldAdd);
178 //
179 if (shouldAdd) {
180 _classListAdd(list, value);
181 return true;
182 } else {
183 _classListRemove(list, value);
184 return false;
185 }
186 }
187
188 static void _addAll(Element _element, Iterable<String> iterable) {
189 DomTokenList list = _classListOf(_element);
190 for (String value in iterable) {
191 _classListAdd(list, value);
192 }
193 }
194
195 static void _removeAll(Element _element, Iterable<String> iterable) {
196 DomTokenList list = _classListOf(_element);
197 for (var value in iterable) {
198 _classListRemove(list, value);
199 }
200 }
201
202 static void _removeWhere(
203 Element _element, bool test(String name), bool doRemove) {
204 DomTokenList list = _classListOf(_element);
205 int i = 0;
206 while (i < _classListLength(list)) {
207 String item = list.item(i);
208 if (doRemove == test(item)) {
209 _classListRemove(list, item);
210 } else {
211 ++i;
212 }
213 }
214 }
215
216 // A collection of static methods for DomTokenList. These methods are a
217 // work-around for the lack of annotations to express the full behaviour of
218 // the DomTokenList methods.
219
220 static DomTokenList _classListOf(Element e) =>
221 JS('returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
222 '#.classList', e);
223
224 static int _classListLength(DomTokenList list) =>
225 JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);
226
227 static bool _classListContains(DomTokenList list, String value) =>
228 JS('returns:bool;effects:none;depends:all;',
229 '#.contains(#)', list, value);
230
231 static void _classListAdd(DomTokenList list, String value) {
232 // list.add(value);
233 JS('', '#.add(#)', list, value);
234 }
235
236 static void _classListRemove(DomTokenList list, String value) {
237 // list.remove(value);
238 JS('', '#.remove(#)', list, value);
239 }
240
241 static bool _classListToggle1(DomTokenList list, String value) {
242 return JS('bool', '#.toggle(#)', list, value);
243 }
244
245 static bool _classListToggle2(
246 DomTokenList list, String value, bool shouldAdd) {
247 return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
248 }
249 }
OLDNEW
« no previous file with comments | « tools/dom/src/CssClassSet.dart ('k') | tools/dom/src/dartium_CssClassSet.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698