This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 27114 - Make DOMTokenList constructible
Summary: Make DOMTokenList constructible
Status: RESOLVED NEEDSINFO
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: DOM (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: ---
Assignee: Anne
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-20 21:06 UTC by Domenic Denicola
Modified: 2017-07-26 18:19 UTC (History)
4 users (show)

See Also:


Attachments

Description Domenic Denicola 2014-10-20 21:06:27 UTC
I would like to implement a custom element with an attribute that is a token list, and another that is a settable token list. When I try to reflect these attributes as properties, I would rather do them as instances of DOMTokenList and DOMSettableTokenList than as my own custom types.

To be able to do this, both classes should be constructible. I think it'd be fine if they just had empty constructors and developers had to call add() to use them. You can imagine more complicated designs, e.g.:

- Pass a sequence<DOMString> and use that as the initial seed values
- Pass an element and an attribute and use mutation observers to monitor changes to the attribute and automatically reflect them in the list

but empty constructor is fine.

Another use case besides custom elements is being able to create mock DOMTokenLists for writing unit tests.

There is interest from Chrome in implementing this so we can implement more HTML elements in JS.
Comment 1 Boris Zbarsky 2014-10-20 21:12:47 UTC
Fwiw, the internal tokenlist constructor in Gecko takes an element and an attribute name.  Then again, it also relies on the attribute itself treating the attribute as a list of whitespace-separated tokens, so generalizing it to arbitrary attributes without loss of performance would probably require a separate implementation for those arbitrary attributes.
Comment 2 Domenic Denicola 2014-10-20 21:37:30 UTC
For the record:

http://dxr.mozilla.org/mozilla-central/source/content/base/src/nsDOMTokenList.cpp

https://code.google.com/p/chromium/codesearch#chromium/src/out/Debug/gen/blink/bindings/core/v8/V8DOMTokenList.cpp

https://github.com/WebKit/webkit/blob/master/Source/WebCore/html/DOMTokenList.cpp

WebKit and Blink haven't diverged much (some Oilpan stuff in Blink mostly) and they seem to be purely string-manipulation based, if I am understanding them correctly.

Gecko only seems to use their mElement pointer toward the end of the functions, so I think it could be factored out into a separate wrapper class (or similar code-reuse strategy) so that the generic DOMTokenList doesn't have an element dependency while still providing a convenient constructor for the cases where you want that to automatically happen.

That said even after looking at the code I didn't quite understand

> it also relies on the attribute itself treating the attribute as a list of whitespace-separated tokens, so generalizing it to arbitrary attributes without loss of performance would probably require a separate implementation for those arbitrary attributes.

It seems from the code that it's fairly generic and will just split on whitespace for whatever attribute you give it. So I think if you threw it at an arbitrary attribute it would just end up doing what you expect?
Comment 3 Boris Zbarsky 2014-10-20 22:07:31 UTC
> It seems from the code that it's fairly generic and will just split on
> whitespace for whatever attribute you give it.

Some parts of it: the ones that are supposed to change the whitespace setup in the attribute (largely AddInternal/RemoveInternal).

Other parts rely on the attribute parsing that happens by default.  For example, contains() relies on the attribute being pre-parsed into a token array.  So does the length getter, the indexed getter,
Comment 4 Anne 2014-10-21 07:28:59 UTC
Re comment 0: You can't use mutation observer, changes are synchronous. So yeah, if you want this for custom elements you either want this to handle the monitoring or you want synchronous observers (which we don't want to hand out, but there's likely other things you can't do without them)...
Comment 5 Domenic Denicola 2014-10-21 18:13:16 UTC
(In reply to Anne from comment #4)
> Re comment 0: You can't use mutation observer, changes are synchronous. So
> yeah, if you want this for custom elements you either want this to handle
> the monitoring or you want synchronous observers (which we don't want to
> hand out, but there's likely other things you can't do without them)...

You're right; you'd have to use attributeChangedCallback.
Comment 6 Anne 2016-03-14 13:13:37 UTC
Domenic, any preference here for what the API should be?
Comment 7 Anne 2016-08-16 08:19:55 UTC
Closing due to lack of API proposal. Happy to reconsider this on GitHub if someone wants to drive this.