W3C home > Mailing lists > Public > public-script-coord@w3.org > January to March 2015

Re: A new hack for singleton objects

From: Boris Zbarsky <bzbarsky@mit.edu>
Date: Tue, 17 Mar 2015 10:28:29 -0400
Message-ID: <55083A0D.9010306@mit.edu>
To: public-script-coord@w3.org
On 3/17/15 7:29 AM, Domenic Denicola wrote:
> The only differences I see are: (a) it looks function-ey instead of object-ey, e.g. via `typeof` or `.constructor` or `instanceof` or `__proto__`

We could change this in Web IDL, right?  As in, we could have interfaces 
that only have static attributes/operations and have nothing inheriting 
from them have no [[Call]] or [[Construct]] and have Object.prototype on 
their proto chain.  And no .prototype (which is already the case for 
CSS, say, in Gecko, which is currently technically a spec violation).

> (b) the capitalization implies to people that Permissions is a class, instances of which should either exist or be constructible.

Nothing actually prevents you from writing "interface permissions" in 
your IDL, as you noted.

But also, there is precedent for capitalized non-class things with 
typeof == "object" in the platform (Math comes to mind).  I guess it 
depends on whether you're thinking of your thing as an object or a 
collection of functions.

The distinction between objects and namespaces may be somewhat important 
when you try to apply methods cross-global.  If you do something like:

   window.history.back.call(otherWindow.history)

that will navigate otherWindow today, because the History methods 
operate on their "this" object and that object is associated with 
otherWindow.

But current static methods in Web IDL don't have a concept of "this 
object" at all, afaict.  So if you do:

   window.Notification.requestPermission.call(otherWindow.Notification)

that will request permissions in the context of window (which is the 
global of the Realm of the requestPermission function), and completely 
ignore the "this" value.  In fact, you could do:

   var rp = Notification.requestPermission;
   rp();

and it would work fine.

I'm not sure how much of an issue this is in practice, of course.  It 
would be somewhat of an issue in the history case, I expect...

Two other notes here that may or may not matter:

1) Right now you can tell when you have a history object by doing 
instanceof History.  Whether that's useful given the state of instanceof 
in cross-global cases in non-Gecko browsers is unclear; obviously in the 
single-global case you could do obj === history to check.

2) Just using interfaces with static-only methods allows you to add 
properties to Window, but not to other objects (like Navigator).  Not 
sure whether that's a problem in practice...

> What do people think? Too crazy, or just crazy enough? (Or, not crazy enough, i.e., we should just add namespace objects to WebIDL and get on with it?

If all we want are namespace objects a la Math, then interfaces with 
static-only stuff seem perfectly fine; whatever minor fixups we want to 
do in terms of their proto chain and [[Call]] can be done in parallel 
with people actually using them, right?

If we want singleton-objects-with-state (like history) that don't have a 
corresponding class, then we'd need new primitives.  But it's not clear 
to me that we actually want those.

> But nobody wants to block shipping new APIs on that, better to just wait until modules arrive I guess...)

I don't quite follow how waiting for a different thing makes things 
better in terms of not blocking APIs.  ;)

-Boris
Received on Tuesday, 17 March 2015 14:28:59 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 17 March 2015 14:28:59 UTC