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

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

Issue 14941002: Aggregate CSS manipulation functions in html lib. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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
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 html; 5 part of html;
6 6
7 /** A Set that stores the CSS class names for an element. */
7 abstract class CssClassSet implements Set<String> { 8 abstract class CssClassSet implements Set<String> {
8 9
9 String toString() {
10 return readClasses().join(' ');
11 }
12
13 /** 10 /**
14 * Adds the class [value] to the element if it is not on it, removes it if it 11 * Adds the class [value] to the element if it is not on it, removes it if it
15 * is. 12 * is.
16 */ 13 */
17 bool toggle(String value) { 14 bool toggle(String value);
18 Set<String> s = readClasses();
19 bool result = false;
20 if (s.contains(value)) {
21 s.remove(value);
22 } else {
23 s.add(value);
24 result = true;
25 }
26 writeClasses(s);
27 return result;
28 }
29 15
30 /** 16 /**
31 * Returns [:true:] if classes cannot be added or removed from this 17 * Returns [:true:] if classes cannot be added or removed from this
32 * [:CssClassSet:]. 18 * [:CssClassSet:].
33 */ 19 */
34 bool get frozen => false; 20 bool get frozen;
35 21
36 // interface Iterable - BEGIN
37 Iterator<String> get iterator => readClasses().iterator;
38 // interface Iterable - END
39
40 // interface Collection - BEGIN
41 void forEach(void f(String element)) {
42 readClasses().forEach(f);
43 }
44
45 String join([String separator = ""]) => readClasses().join(separator);
46
47 Iterable map(f(String element)) => readClasses().map(f);
48
49 Iterable<String> where(bool f(String element)) => readClasses().where(f);
50
51 Iterable expand(Iterable f(String element)) => readClasses().expand(f);
52
53 bool every(bool f(String element)) => readClasses().every(f);
54
55 bool any(bool f(String element)) => readClasses().any(f);
56
57 bool get isEmpty => readClasses().isEmpty;
58
59 int get length => readClasses().length;
60
61 String reduce(String combine(String value, String element)) {
62 return readClasses().reduce(combine);
63 }
64
65 dynamic fold(dynamic initialValue,
66 dynamic combine(dynamic previousValue, String element)) {
67 return readClasses().fold(initialValue, combine);
68 }
69 // interface Collection - END
70
71 // interface Set - BEGIN
72 /** 22 /**
73 * Determine if this element contains the class [value]. 23 * Determine if this element contains the class [value].
74 * 24 *
75 * This is the Dart equivalent of jQuery's 25 * This is the Dart equivalent of jQuery's
76 * [hasClass](http://api.jquery.com/hasClass/). 26 * [hasClass](http://api.jquery.com/hasClass/).
77 */ 27 */
78 bool contains(String value) => readClasses().contains(value); 28 bool contains(String value);
79 29
80 /** 30 /**
81 * Add the class [value] to element. 31 * Add the class [value] to element.
82 * 32 *
83 * This is the Dart equivalent of jQuery's 33 * This is the Dart equivalent of jQuery's
84 * [addClass](http://api.jquery.com/addClass/). 34 * [addClass](http://api.jquery.com/addClass/).
85 */ 35 */
86 void add(String value) { 36 void add(String value);
87 // TODO - figure out if we need to do any validation here
88 // or if the browser natively does enough.
89 _modify((s) => s.add(value));
90 }
91 37
92 /** 38 /**
93 * Remove the class [value] from element, and return true on successful 39 * Remove the class [value] from element, and return true on successful
94 * removal. 40 * removal.
95 * 41 *
96 * This is the Dart equivalent of jQuery's 42 * This is the Dart equivalent of jQuery's
97 * [removeClass](http://api.jquery.com/removeClass/). 43 * [removeClass](http://api.jquery.com/removeClass/).
98 */ 44 */
99 bool remove(Object value) { 45 bool remove(Object value);
100 if (value is! String) return false;
101 Set<String> s = readClasses();
102 bool result = s.remove(value);
103 writeClasses(s);
104 return result;
105 }
106 46
107 /** 47 /**
108 * Add all classes specified in [iterable] to element. 48 * Add all classes specified in [iterable] to element.
109 * 49 *
110 * This is the Dart equivalent of jQuery's 50 * This is the Dart equivalent of jQuery's
111 * [addClass](http://api.jquery.com/addClass/). 51 * [addClass](http://api.jquery.com/addClass/).
112 */ 52 */
113 void addAll(Iterable<String> iterable) { 53 void addAll(Iterable<String> iterable);
114 // TODO - see comment above about validation.
115 _modify((s) => s.addAll(iterable));
116 }
117 54
118 /** 55 /**
119 * Remove all classes specified in [iterable] from element. 56 * Remove all classes specified in [iterable] from element.
120 * 57 *
121 * This is the Dart equivalent of jQuery's 58 * This is the Dart equivalent of jQuery's
122 * [removeClass](http://api.jquery.com/removeClass/). 59 * [removeClass](http://api.jquery.com/removeClass/).
123 */ 60 */
124 void removeAll(Iterable<String> iterable) { 61 void removeAll(Iterable<String> iterable);
125 _modify((s) => s.removeAll(iterable));
126 }
127 62
128 /** 63 /**
129 * Toggles all classes specified in [iterable] on element. 64 * Toggles all classes specified in [iterable] on element.
130 * 65 *
131 * Iterate through [iterable]'s items, and add it if it is not on it, or 66 * Iterate through [iterable]'s items, and add it if it is not on it, or
132 * remove it if it is. This is the Dart equivalent of jQuery's 67 * remove it if it is. This is the Dart equivalent of jQuery's
133 * [toggleClass](http://api.jquery.com/toggleClass/). 68 * [toggleClass](http://api.jquery.com/toggleClass/).
134 */ 69 */
135 void toggleAll(Iterable<String> iterable) { 70 void toggleAll(Iterable<String> iterable);
136 iterable.forEach(toggle); 71 }
72
73 /**
74 * A set (union) of the CSS classes that are present in a set of elements.
75 * Implemented separately from _ElementCssClassSet for performance.
76 */
77 class _MultiElementCssClassSet extends CssClassSetImpl {
78 final Iterable<Element> _elementIterable;
79 Iterable<_ElementCssClassSet> _elementCssClassSetIterable;
80
81 _MultiElementCssClassSet(this._elementIterable) {
82 _elementCssClassSetIterable = new List.from(_elementIterable).map(
83 (e) => new _ElementCssClassSet(e));
137 } 84 }
138 85
139 void retainAll(Iterable<String> iterable) { 86 Set<String> readClasses() {
140 _modify((s) => s.retainAll(iterable)); 87 var s = new LinkedHashSet<String>();
88 _elementCssClassSetIterable.forEach((e) => s.addAll(e.readClasses()));
89 return s;
141 } 90 }
142 91
143 void removeWhere(bool test(String name)) { 92 void writeClasses(Set<String> s) {
144 _modify((s) => s.removeWhere(test)); 93 var classes = new List.from(s).join(' ');
94 for (Element e in _elementIterable) {
95 e.$dom_className = classes;
96 }
145 } 97 }
146 98
147 void retainWhere(bool test(String name)) {
148 _modify((s) => s.retainWhere(test));
149 }
150
151 bool containsAll(Iterable<String> collection) =>
152 readClasses().containsAll(collection);
153
154 Set<String> intersection(Set<String> other) =>
155 readClasses().intersection(other);
156
157 Set<String> union(Set<String> other) =>
158 readClasses().union(other);
159
160 Set<String> difference(Set<String> other) =>
161 readClasses().difference(other);
162
163 String get first => readClasses().first;
164 String get last => readClasses().last;
165 String get single => readClasses().single;
166 List<String> toList({ bool growable: true }) =>
167 readClasses().toList(growable: growable);
168 Set<String> toSet() => readClasses().toSet();
169 Iterable<String> take(int n) => readClasses().take(n);
170 Iterable<String> takeWhile(bool test(String value)) =>
171 readClasses().takeWhile(test);
172 Iterable<String> skip(int n) => readClasses().skip(n);
173 Iterable<String> skipWhile(bool test(String value)) =>
174 readClasses().skipWhile(test);
175 String firstWhere(bool test(String value), { String orElse() }) =>
176 readClasses().firstWhere(test, orElse: orElse);
177 String lastWhere(bool test(String value), {String orElse()}) =>
178 readClasses().lastWhere(test, orElse: orElse);
179 String singleWhere(bool test(String value)) =>
180 readClasses().singleWhere(test);
181 String elementAt(int index) => readClasses().elementAt(index);
182
183 void clear() {
184 _modify((s) => s.clear());
185 }
186 // interface Set - END
187
188 /** 99 /**
189 * Helper method used to modify the set of css classes on this element. 100 * Helper method used to modify the set of css classes on this element.
190 * 101 *
191 * f - callback with: 102 * f - callback with:
192 * s - a Set of all the css class name currently on this element. 103 * s - a Set of all the css class name currently on this element.
193 * 104 *
194 * After f returns, the modified set is written to the 105 * After f returns, the modified set is written to the
195 * className property of this element. 106 * className property of this element.
196 */ 107 */
197 void _modify( f(Set<String> s)) { 108 void modify( f(Set<String> s)) {
198 Set<String> s = readClasses(); 109 _elementCssClassSetIterable.forEach((e) => e.modify(f));
199 f(s);
200 writeClasses(s);
201 } 110 }
202 111
203 /** 112 /**
204 * Read the class names from the Element class property, 113 * Adds the class [value] to the element if it is not on it, removes it if it
205 * and put them into a set (duplicates are discarded). 114 * is.
206 * This is intended to be overridden by specific implementations.
207 */ 115 */
208 Set<String> readClasses(); 116 bool toggle(String value) =>
117 _modifyWithReturnValue((e) => e.toggle(value));
209 118
210 /** 119 /**
211 * Join all the elements of a set into one string and write 120 * Remove the class [value] from element, and return true on successful
212 * back to the element. 121 * removal.
213 * This is intended to be overridden by specific implementations. 122 *
123 * This is the Dart equivalent of jQuery's
124 * [removeClass](http://api.jquery.com/removeClass/).
214 */ 125 */
215 void writeClasses(Set<String> s); 126 bool remove(Object value) => _modifyWithReturnValue((e) => e.remove(value));
127
128 bool _modifyWithReturnValue(f) => _elementCssClassSetIterable.fold(
129 false, (prevValue, element) => f(element) || prevValue);
216 } 130 }
131
132 class _ElementCssClassSet extends CssClassSetImpl {
133
134 final Element _element;
135
136 _ElementCssClassSet(this._element);
137
138 Set<String> readClasses() {
139 var s = new LinkedHashSet<String>();
140 var classname = _element.$dom_className;
141
142 for (String name in classname.split(' ')) {
143 String trimmed = name.trim();
144 if (!trimmed.isEmpty) {
145 s.add(trimmed);
146 }
147 }
148 return s;
149 }
150
151 void writeClasses(Set<String> s) {
152 List list = new List.from(s);
153 _element.$dom_className = s.join(' ');
154 }
155 }
OLDNEW
« no previous file with comments | « tests/html/element_classes_test.dart ('k') | tools/dom/templates/html/impl/impl_Document.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698