OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 part of html_common; |
| 6 |
| 7 abstract class CssClassSetImpl implements CssClassSet { |
| 8 |
| 9 static final RegExp _validTokenRE = new RegExp(r'^\S+$'); |
| 10 |
| 11 String _validateToken(String value) { |
| 12 if (_validTokenRE.hasMatch(value)) return value; |
| 13 throw new ArgumentError.value(value, 'value', 'Not a valid class token'); |
| 14 } |
| 15 |
| 16 String toString() { |
| 17 return readClasses().join(' '); |
| 18 } |
| 19 |
| 20 /** |
| 21 * Adds the class [value] to the element if it is not on it, removes it if it |
| 22 * is. |
| 23 * |
| 24 * If [shouldAdd] is true, then we always add that [value] to the element. If |
| 25 * [shouldAdd] is false then we always remove [value] from the element. |
| 26 */ |
| 27 bool toggle(String value, [bool shouldAdd]) { |
| 28 _validateToken(value); |
| 29 Set<String> s = readClasses(); |
| 30 bool result = false; |
| 31 if (shouldAdd == null) shouldAdd = !s.contains(value); |
| 32 if (shouldAdd) { |
| 33 s.add(value); |
| 34 result = true; |
| 35 } else { |
| 36 s.remove(value); |
| 37 } |
| 38 writeClasses(s); |
| 39 return result; |
| 40 } |
| 41 |
| 42 /** |
| 43 * Returns [:true:] if classes cannot be added or removed from this |
| 44 * [:CssClassSet:]. |
| 45 */ |
| 46 bool get frozen => false; |
| 47 |
| 48 // interface Iterable - BEGIN |
| 49 Iterator<String> get iterator => readClasses().iterator; |
| 50 // interface Iterable - END |
| 51 |
| 52 // interface Collection - BEGIN |
| 53 void forEach(void f(String element)) { |
| 54 readClasses().forEach(f); |
| 55 } |
| 56 |
| 57 String join([String separator = ""]) => readClasses().join(separator); |
| 58 |
| 59 Iterable map(f(String element)) => readClasses().map(f); |
| 60 |
| 61 Iterable<String> where(bool f(String element)) => readClasses().where(f); |
| 62 |
| 63 Iterable expand(Iterable f(String element)) => readClasses().expand(f); |
| 64 |
| 65 bool every(bool f(String element)) => readClasses().every(f); |
| 66 |
| 67 bool any(bool f(String element)) => readClasses().any(f); |
| 68 |
| 69 bool get isEmpty => readClasses().isEmpty; |
| 70 |
| 71 bool get isNotEmpty => readClasses().isNotEmpty; |
| 72 |
| 73 int get length => readClasses().length; |
| 74 |
| 75 String reduce(String combine(String value, String element)) { |
| 76 return readClasses().reduce(combine); |
| 77 } |
| 78 |
| 79 dynamic fold(dynamic initialValue, |
| 80 dynamic combine(dynamic previousValue, String element)) { |
| 81 return readClasses().fold(initialValue, combine); |
| 82 } |
| 83 // interface Collection - END |
| 84 |
| 85 // interface Set - BEGIN |
| 86 /** |
| 87 * Determine if this element contains the class [value]. |
| 88 * |
| 89 * This is the Dart equivalent of jQuery's |
| 90 * [hasClass](http://api.jquery.com/hasClass/). |
| 91 */ |
| 92 bool contains(Object value) { |
| 93 if (value is! String) return false; |
| 94 _validateToken(value); |
| 95 return readClasses().contains(value); |
| 96 } |
| 97 |
| 98 /** Lookup from the Set interface. Not interesting for a String set. */ |
| 99 String lookup(Object value) => contains(value) ? value : null; |
| 100 |
| 101 /** |
| 102 * Add the class [value] to element. |
| 103 * |
| 104 * This is the Dart equivalent of jQuery's |
| 105 * [addClass](http://api.jquery.com/addClass/). |
| 106 */ |
| 107 bool add(String value) { |
| 108 _validateToken(value); |
| 109 // TODO - figure out if we need to do any validation here |
| 110 // or if the browser natively does enough. |
| 111 return modify((s) => s.add(value)); |
| 112 } |
| 113 |
| 114 /** |
| 115 * Remove the class [value] from element, and return true on successful |
| 116 * removal. |
| 117 * |
| 118 * This is the Dart equivalent of jQuery's |
| 119 * [removeClass](http://api.jquery.com/removeClass/). |
| 120 */ |
| 121 bool remove(Object value) { |
| 122 _validateToken(value); |
| 123 if (value is! String) return false; |
| 124 Set<String> s = readClasses(); |
| 125 bool result = s.remove(value); |
| 126 writeClasses(s); |
| 127 return result; |
| 128 } |
| 129 |
| 130 /** |
| 131 * Add all classes specified in [iterable] to element. |
| 132 * |
| 133 * This is the Dart equivalent of jQuery's |
| 134 * [addClass](http://api.jquery.com/addClass/). |
| 135 */ |
| 136 void addAll(Iterable<String> iterable) { |
| 137 // TODO - see comment above about validation. |
| 138 modify((s) => s.addAll(iterable.map(_validateToken))); |
| 139 } |
| 140 |
| 141 /** |
| 142 * Remove all classes specified in [iterable] from element. |
| 143 * |
| 144 * This is the Dart equivalent of jQuery's |
| 145 * [removeClass](http://api.jquery.com/removeClass/). |
| 146 */ |
| 147 void removeAll(Iterable<Object> iterable) { |
| 148 modify((s) => s.removeAll(iterable.map(_validateToken))); |
| 149 } |
| 150 |
| 151 /** |
| 152 * Toggles all classes specified in [iterable] on element. |
| 153 * |
| 154 * Iterate through [iterable]'s items, and add it if it is not on it, or |
| 155 * remove it if it is. This is the Dart equivalent of jQuery's |
| 156 * [toggleClass](http://api.jquery.com/toggleClass/). |
| 157 * If [shouldAdd] is true, then we always add all the classes in [iterable] |
| 158 * element. If [shouldAdd] is false then we always remove all the classes in |
| 159 * [iterable] from the element. |
| 160 */ |
| 161 void toggleAll(Iterable<String> iterable, [bool shouldAdd]) { |
| 162 iterable.forEach((e) => toggle(e, shouldAdd)); |
| 163 } |
| 164 |
| 165 void retainAll(Iterable<Object> iterable) { |
| 166 modify((s) => s.retainAll(iterable)); |
| 167 } |
| 168 |
| 169 void removeWhere(bool test(String name)) { |
| 170 modify((s) => s.removeWhere(test)); |
| 171 } |
| 172 |
| 173 void retainWhere(bool test(String name)) { |
| 174 modify((s) => s.retainWhere(test)); |
| 175 } |
| 176 |
| 177 bool containsAll(Iterable<Object> collection) => |
| 178 readClasses().containsAll(collection); |
| 179 |
| 180 Set<String> intersection(Set<Object> other) => |
| 181 readClasses().intersection(other); |
| 182 |
| 183 Set<String> union(Set<String> other) => |
| 184 readClasses().union(other); |
| 185 |
| 186 Set<String> difference(Set<String> other) => |
| 187 readClasses().difference(other); |
| 188 |
| 189 String get first => readClasses().first; |
| 190 String get last => readClasses().last; |
| 191 String get single => readClasses().single; |
| 192 List<String> toList({ bool growable: true }) => |
| 193 readClasses().toList(growable: growable); |
| 194 Set<String> toSet() => readClasses().toSet(); |
| 195 Iterable<String> take(int n) => readClasses().take(n); |
| 196 Iterable<String> takeWhile(bool test(String value)) => |
| 197 readClasses().takeWhile(test); |
| 198 Iterable<String> skip(int n) => readClasses().skip(n); |
| 199 Iterable<String> skipWhile(bool test(String value)) => |
| 200 readClasses().skipWhile(test); |
| 201 String firstWhere(bool test(String value), { String orElse() }) => |
| 202 readClasses().firstWhere(test, orElse: orElse); |
| 203 String lastWhere(bool test(String value), { String orElse()}) => |
| 204 readClasses().lastWhere(test, orElse: orElse); |
| 205 String singleWhere(bool test(String value)) => |
| 206 readClasses().singleWhere(test); |
| 207 String elementAt(int index) => readClasses().elementAt(index); |
| 208 |
| 209 void clear() { |
| 210 // TODO(sra): Do this without reading the classes. |
| 211 modify((s) => s.clear()); |
| 212 } |
| 213 // interface Set - END |
| 214 |
| 215 /** |
| 216 * Helper method used to modify the set of css classes on this element. |
| 217 * |
| 218 * f - callback with: |
| 219 * s - a Set of all the css class name currently on this element. |
| 220 * |
| 221 * After f returns, the modified set is written to the |
| 222 * className property of this element. |
| 223 */ |
| 224 modify( f(Set<String> s)) { |
| 225 Set<String> s = readClasses(); |
| 226 var ret = f(s); |
| 227 writeClasses(s); |
| 228 return ret; |
| 229 } |
| 230 |
| 231 /** |
| 232 * Read the class names from the Element class property, |
| 233 * and put them into a set (duplicates are discarded). |
| 234 * This is intended to be overridden by specific implementations. |
| 235 */ |
| 236 Set<String> readClasses(); |
| 237 |
| 238 /** |
| 239 * Join all the elements of a set into one string and write |
| 240 * back to the element. |
| 241 * This is intended to be overridden by specific implementations. |
| 242 */ |
| 243 void writeClasses(Set<String> s); |
| 244 } |
OLD | NEW |