Breaking change on CssClassSet for upcoming Dart 1.10 release

Skip to first unread message

Kevin Moore

Apr 23, 2015, 12:06:22 AM4/23/15
You can no longer use spaces like this:  element.classes.add('foo bar')
Angular users need to update to upcoming bugfix release 1.1.2.


In 1.10 CssClassSet operations will be more strict in their arguments.  Arguments to add, remove, contains and toggle must betokens, which are non-empty strings containing no whitespace characters, i.e. a single class name.  The collection-based operations like addAll take Iterables containing tokens.

This will now cause an exception to be thrown:

element.classes.add('foo bar');

Replace with one of


element.classes.addAll(['foo', 'bar']);

// Only one space.
element.classes.addAll('foo bar'.split(' '));

// Multiple adjacent spaces, or spaces before and after the class names.
element.classes.addAll('foo bar'.split(' ').where((s) => s.isNotEmpty);

The change was motivated by two factors:
  1. The operations were incorrect for strings containing spaces. I think it was an oversight that the token restriction was not enforced from the initial implementation of CssClassSet.
  2. We have customers with performance sensitive code worried about CssClassSet operations showing up too high in their profiles.
We can't fix both of these problems at the same time.  We could split and sanitize the string, making all operations slower, or we could adopt arguments that are allowable on HTML5 DOMTokenList operations [1].  This excludes empty strings and strings with spaces. 

Compatibility with DOMTokenList lets us use Element.classList directly.  We measured a performance improvement of 4.5x.  With a little more (non breaking) work we will be at parity with hand-written JavaScript.

Had we instead chosen to support spaces, we would be locked into a ~10x performance penalty.  I think we all want to avoid this.

Reply all
Reply to author
This conversation is locked
You cannot reply and perform actions on locked conversations.
0 new messages