| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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 * A set (union) of the CSS classes that are present in a set of elements. | 8 * A set (union) of the CSS classes that are present in a set of elements. |
| 9 * Implemented separately from _ElementCssClassSet for performance. | 9 * Implemented separately from _ElementCssClassSet for performance. |
| 10 */ | 10 */ |
| 11 class _MultiElementCssClassSet extends CssClassSetImpl { | 11 class _MultiElementCssClassSet extends CssClassSetImpl { |
| 12 final Iterable<Element> _elementIterable; | 12 final Iterable<Element> _elementIterable; |
| 13 | 13 |
| 14 // TODO(sra): Perhaps we should store the DomTokenList instead. | 14 // TODO(sra): Perhaps we should store the DomTokenList instead. |
| 15 final List<CssClassSetImpl> _sets; | 15 final List<CssClassSetImpl> _sets; |
| 16 | 16 |
| 17 factory _MultiElementCssClassSet(Iterable<Element> elements) { | 17 factory _MultiElementCssClassSet(Iterable<Element> elements) { |
| 18 return new _MultiElementCssClassSet._(elements, | 18 return new _MultiElementCssClassSet._( |
| 19 elements.map((Element e) => e.classes).toList()); | 19 elements, elements.map((Element e) => e.classes).toList()); |
| 20 } | 20 } |
| 21 | 21 |
| 22 _MultiElementCssClassSet._(this._elementIterable, this._sets); | 22 _MultiElementCssClassSet._(this._elementIterable, this._sets); |
| 23 | 23 |
| 24 Set<String> readClasses() { | 24 Set<String> readClasses() { |
| 25 var s = new LinkedHashSet<String>(); | 25 var s = new LinkedHashSet<String>(); |
| 26 _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses())); | 26 _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses())); |
| 27 return s; | 27 return s; |
| 28 } | 28 } |
| 29 | 29 |
| 30 void writeClasses(Set<String> s) { | 30 void writeClasses(Set<String> s) { |
| 31 var classes = s.join(' '); | 31 var classes = s.join(' '); |
| 32 for (Element e in _elementIterable) { | 32 for (Element e in _elementIterable) { |
| 33 e.className = classes; | 33 e.className = classes; |
| 34 } | 34 } |
| 35 } | 35 } |
| 36 | 36 |
| 37 /** | 37 /** |
| 38 * Helper method used to modify the set of css classes on this element. | 38 * Helper method used to modify the set of css classes on this element. |
| 39 * | 39 * |
| 40 * f - callback with: | 40 * f - callback with: |
| 41 * s - a Set of all the css class name currently on this element. | 41 * s - a Set of all the css class name currently on this element. |
| 42 * | 42 * |
| 43 * After f returns, the modified set is written to the | 43 * After f returns, the modified set is written to the |
| 44 * className property of this element. | 44 * className property of this element. |
| 45 */ | 45 */ |
| 46 modify( f(Set<String> s)) { | 46 modify(f(Set<String> s)) { |
| 47 _sets.forEach((CssClassSetImpl e) => e.modify(f)); | 47 _sets.forEach((CssClassSetImpl e) => e.modify(f)); |
| 48 } | 48 } |
| 49 | 49 |
| 50 /** | 50 /** |
| 51 * Adds the class [value] to the element if it is not on it, removes it if it | 51 * Adds the class [value] to the element if it is not on it, removes it if it |
| 52 * is. | 52 * is. |
| 53 * | 53 * |
| 54 * TODO(sra): It seems wrong to collect a 'changed' flag like this when the | 54 * TODO(sra): It seems wrong to collect a 'changed' flag like this when the |
| 55 * underlying toggle returns an 'is set' flag. | 55 * underlying toggle returns an 'is set' flag. |
| 56 */ | 56 */ |
| 57 bool toggle(String value, [bool shouldAdd]) => | 57 bool toggle(String value, [bool shouldAdd]) => _sets.fold( |
| 58 _sets.fold(false, | 58 false, |
| 59 (bool changed, CssClassSetImpl e) => | 59 (bool changed, CssClassSetImpl e) => |
| 60 e.toggle(value, shouldAdd) || changed); | 60 e.toggle(value, shouldAdd) || changed); |
| 61 | 61 |
| 62 /** | 62 /** |
| 63 * Remove the class [value] from element, and return true on successful | 63 * Remove the class [value] from element, and return true on successful |
| 64 * removal. | 64 * removal. |
| 65 * | 65 * |
| 66 * This is the Dart equivalent of jQuery's | 66 * This is the Dart equivalent of jQuery's |
| 67 * [removeClass](http://api.jquery.com/removeClass/). | 67 * [removeClass](http://api.jquery.com/removeClass/). |
| 68 */ | 68 */ |
| 69 bool remove(Object value) => _sets.fold(false, | 69 bool remove(Object value) => _sets.fold( |
| 70 (bool changed, CssClassSetImpl e) => e.remove(value) || changed); | 70 false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed); |
| 71 } | 71 } |
| 72 | 72 |
| 73 class _ElementCssClassSet extends CssClassSetImpl { | 73 class _ElementCssClassSet extends CssClassSetImpl { |
| 74 final Element _element; | 74 final Element _element; |
| 75 | 75 |
| 76 _ElementCssClassSet(this._element); | 76 _ElementCssClassSet(this._element); |
| 77 | 77 |
| 78 Set<String> readClasses() { | 78 Set<String> readClasses() { |
| 79 var s = new LinkedHashSet<String>(); | 79 var s = new LinkedHashSet<String>(); |
| 80 var classname = _element.className; | 80 var classname = _element.className; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 } else { | 211 } else { |
| 212 ++i; | 212 ++i; |
| 213 } | 213 } |
| 214 } | 214 } |
| 215 } | 215 } |
| 216 | 216 |
| 217 // A collection of static methods for DomTokenList. These methods are a | 217 // A collection of static methods for DomTokenList. These methods are a |
| 218 // work-around for the lack of annotations to express the full behaviour of | 218 // work-around for the lack of annotations to express the full behaviour of |
| 219 // the DomTokenList methods. | 219 // the DomTokenList methods. |
| 220 | 220 |
| 221 static DomTokenList _classListOf(Element e) => | 221 static DomTokenList _classListOf(Element e) => JS( |
| 222 JS('returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;', | 222 'returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;', |
| 223 '#.classList', e); | 223 '#.classList', |
| 224 e); |
| 224 | 225 |
| 225 static int _classListLength(DomTokenList list) => | 226 static int _classListLength(DomTokenList list) => |
| 226 JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list); | 227 JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list); |
| 227 | 228 |
| 228 static bool _classListContains(DomTokenList list, String value) => | 229 static bool _classListContains(DomTokenList list, String value) => |
| 229 JS('returns:bool;effects:none;depends:all', | 230 JS('returns:bool;effects:none;depends:all', '#.contains(#)', list, value); |
| 230 '#.contains(#)', list, value); | |
| 231 | 231 |
| 232 static bool _classListContainsBeforeAddOrRemove( | 232 static bool _classListContainsBeforeAddOrRemove( |
| 233 DomTokenList list, String value) => | 233 DomTokenList list, String value) => |
| 234 // 'throws:never' is a lie, since 'contains' will throw on an illegal | 234 // 'throws:never' is a lie, since 'contains' will throw on an illegal |
| 235 // token. However, we always call this function immediately prior to | 235 // token. However, we always call this function immediately prior to |
| 236 // add/remove/toggle with the same token. Often the result of 'contains' | 236 // add/remove/toggle with the same token. Often the result of 'contains' |
| 237 // is unused and the lie makes it possible for the 'contains' instruction | 237 // is unused and the lie makes it possible for the 'contains' instruction |
| 238 // to be removed. | 238 // to be removed. |
| 239 JS('returns:bool;effects:none;depends:all;throws:null(1)', | 239 JS('returns:bool;effects:none;depends:all;throws:null(1)', |
| 240 '#.contains(#)', list, value); | 240 '#.contains(#)', list, value); |
| 241 | 241 |
| 242 static void _classListAdd(DomTokenList list, String value) { | 242 static void _classListAdd(DomTokenList list, String value) { |
| 243 // list.add(value); | 243 // list.add(value); |
| 244 JS('', '#.add(#)', list, value); | 244 JS('', '#.add(#)', list, value); |
| 245 } | 245 } |
| 246 | 246 |
| 247 static void _classListRemove(DomTokenList list, String value) { | 247 static void _classListRemove(DomTokenList list, String value) { |
| 248 // list.remove(value); | 248 // list.remove(value); |
| 249 JS('', '#.remove(#)', list, value); | 249 JS('', '#.remove(#)', list, value); |
| 250 } | 250 } |
| 251 | 251 |
| 252 static bool _classListToggle1(DomTokenList list, String value) { | 252 static bool _classListToggle1(DomTokenList list, String value) { |
| 253 return JS('bool', '#.toggle(#)', list, value); | 253 return JS('bool', '#.toggle(#)', list, value); |
| 254 } | 254 } |
| 255 | 255 |
| 256 static bool _classListToggle2( | 256 static bool _classListToggle2( |
| 257 DomTokenList list, String value, bool shouldAdd) { | 257 DomTokenList list, String value, bool shouldAdd) { |
| 258 return JS('bool', '#.toggle(#, #)', list, value, shouldAdd); | 258 return JS('bool', '#.toggle(#, #)', list, value, shouldAdd); |
| 259 } | 259 } |
| 260 } | 260 } |
| OLD | NEW |