[webidl] Add a [Maplike] tag?

I want to convert the interface at
from an "object map"* to an actual Map, so that it uses a (soon-to-be)
familiar API and interoperates with other code that works on Maps.  I
recently talked about this on es-discuss a bit (see the threads
"Overriding Map/etc with get/set hooks?" and "Non-generic traps for
non-generic objects"), and the conversation seems to have ended with
the conclusion "do it in WebIDL instead".  So!

I propose that we have some way to tag an interface as "map-like".
This means that it exposes the same methods and properties as Map and
has Map on the prototype chain, but specifies potentially custom
behavior for getting/setting/deleting values.

This could be based on the gist at
<https://gist.github.com/jorendorff/5662673>, in terms of defining the
operations.  The spec author would have to define similar things to
today's "object maps" - a list of map tuples (for the iterator), a
mapgetter, a mapsetter, and a mapdeleter.

For my specific example, I'd define:
* the list of map tuples are the custom properties defined on the
associated CSSStyleRule,
* the mapgetter coerces the argument to string, mangles it
appropriately, then calls getPropertyValue() on the associated
* the mapsetter coerces both arguments to strings, mangles the first
appropriately, then calls setProperty() on the associated
* the mapdeleter coerces+mangles the argument, then calls
removeProperty() on the associated CSSStyleRule.

There are a lot of other interfaces that could benefit from being
changed to Maps, so I think there's an obvious strong argument for
this being used in the future.  For example, we're having a
conversation about the interface for @font-feature-values, and it
would likely benefit from this as well.

While we're at it, do the same thing for "set-like", which is the same
but for the Set class.


* Why change from an "object map"?  This kind of interface is subject
to accidental or malicious corruption when things are added to any of
its prototypes (including Object.prototype), where it *looks* like
there's a value on it, but there really isn't, and the only way to
actually set that key on the actual object map is to use
Object.defineProperty().  It's also harder to extend in the future; if
you ever want to add a method or property to it, you have to be
careful about existing usage possible using your desired name as a
key, and add a restriction disallowing that key from being used to the
appropriate spec.  Maps gets around all these issues nicely.

Received on Wednesday, 29 May 2013 22:24:39 UTC