Fwd: [webidl] Add a [Maplike] tag?

I want to convert the interface at
<http://dev.w3.org/csswg/css-variables/#the-cssvariablesdeclaration-interface>
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 MUST define the list of key/value tuples
(which defines the iterator and the size property), and SHOULD define
a get() method (if not, it's provided automatically based on the
iterator).  If the interface is intended to be mutable, the spec
authors MUST define set() and delete() methods as well.  They MAY
define any of the rest of the methods, if it's possible to
substantially beat the naive predefined implementation.

For my specific example, I'd define:
* the list of map tuples are the custom properties defined on the
associated CSSStyleRule,
* the get() method coerces the argument to string, mangles it
appropriately, then calls getPropertyValue() on the associated
CSSStyleRule,
* the set() coerces both arguments to strings, mangles the first
appropriately, then calls setProperty() on the associated
CSSStyleRule,
* the delete() 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.  Would the same thing be useful for
"array-like", or does [ArrayClass] already cover that?

~TJ

* 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 Thursday, 30 May 2013 20:15:13 UTC