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 24403 - WebIDL callbacks should probably default to pushing a new entry settings object
Summary: WebIDL callbacks should probably default to pushing a new entry settings object
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebIDL (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Cameron McCormack
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 17713
  Show dependency treegraph
 
Reported: 2014-01-27 01:24 UTC by Boris Zbarsky
Modified: 2016-06-02 20:46 UTC (History)
7 users (show)

See Also:


Attachments

Description Boris Zbarsky 2014-01-27 01:24:37 UTC
Looks like we set up incumbent settings objects here, but not entry ones.  We need to do the latter in various case.  For example, event dispatch certainly needs to do it; otherwise you end up running event listeners with no entry settings object, but various other specs depend on having an entry settings object.

I believe the simplest thing to do here is to always set the entry settings object to the global of the callback object (which is NOT the same thing as the global of the function getting called, for what it's worth).
Comment 1 Boris Zbarsky 2014-01-27 01:26:22 UTC
Oh, and Anne too, since if we don't do this in WebIDL we'll need to go through all specs using callbacks and set the up as needed...
Comment 2 Bobby Holley (:bholley) 2014-01-27 06:05:09 UTC
(In reply to Boris Zbarsky from comment #0)
> Looks like we set up incumbent settings objects here, but not entry ones. 

IIUC we do, it's just in HTML5 rather than WebIDL (step 3 of 'prepare to run a callback'. I've always been a bit fuzzy about how that interacted with the WebIDL bits though.

> We need to do the latter in various case.  For example, event dispatch
> certainly needs to do it; otherwise you end up running event listeners with
> no entry settings object, but various other specs depend on having an entry
> settings object.

Yeah. The more interesting question is what happens with synchronous event dispatch and treewalker callbacks. Hixie and I discussed this in SF, and IIRC he was more or less open to whatever.

I think the sanest definition of "candidate entry settings object" would be to apply it whenever content script is invoked by the UA (rather than by other content script), which would align with doing it in all WebIDL callacks. It remains to be seen whether this is web compatible, though.
 
> I believe the simplest thing to do here is to always set the entry settings
> object to the global of the callback object (which is NOT the same thing as
> the global of the function getting called, for what it's worth).

Hm. This is different than my current understanding of the spec, and what Gecko does - both use the global of the function getting called (I think).

However, it's a little bit silly, because per spec today we always follow the candidate entry settings object (based on the global of the callee) with another (non-candidate) settings object based on the global of the callback object. It might make sense to align them.
Comment 3 Boris Zbarsky 2014-01-27 08:11:41 UTC
> step 3 of 'prepare to run a callback'

Nothing in event dispatch invokes that algorithm, as far as I can tell.  I realize the intent was to do so, but right now the spec just doesn't say to do it...

> It remains to be seen whether this is web compatible, though.

Hmm.  I guess Firefox 27 is the first Gecko release that actually guarantees the behavior you describe.  So far we haven't had any issues reported on it, but of course we haven't released it yet.

> both use the global of the function getting called (I think)

I don't think Gecko does at the moment.  Gecko uses the global of the JS object that implements the callback or callback interface.

So if you do this:

  var objFromFrame1 = {};
  objFromFrame1.handlEvent = funcFromFrame2;
  foo.addEventListener("evt", objFromFrame1);

I'm pretty darned sure Gecko will treat frame1 as the entry settings object, not frame2.
Comment 4 Bobby Holley (:bholley) 2014-01-27 15:29:46 UTC
(In reply to Boris Zbarsky from comment #3)
> > step 3 of 'prepare to run a callback'
> 
> Nothing in event dispatch invokes that algorithm, as far as I can tell.  I
> realize the intent was to do so, but right now the spec just doesn't say to
> do it...

What about the part that says "In this step, invoke means to run the jump to a code entry-point algorithm"?

> So if you do this:
> 
>   var objFromFrame1 = {};
>   objFromFrame1.handlEvent = funcFromFrame2;
>   foo.addEventListener("evt", objFromFrame1);
> 
> I'm pretty darned sure Gecko will treat frame1 as the entry settings object,
> not frame2.

Ok, but if you do:

foo.addEventListener("evt", funcFromFrame2)

I'm pretty sure Gecko will use frame2 as the entry settings object, even though the implicit conversion to Function theoretically happens in the scope of frame1.
Comment 5 Boris Zbarsky 2014-01-27 16:34:06 UTC
> What about the part that says "In this step, invoke means to run the jump to a
> code entry-point algorithm"?

You mean in http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes ?

That would apply to event _handlers_, but not to event _listeners_.

> I'm pretty sure Gecko will use frame2 as the entry settings object

Yes.  It will use the global of the actual object it was handed (which as I said is possibly different from the object whose [[Call]] it will invoke).

> even though the implicit conversion to Function theoretically happens in the
> scope of frame1.

I don't see how Function is relevant here at all or what implicit conversion you're talking about....  The model in the spec is that there is a WebIDL callback object (in this case an EventListener) which is created with its "callback context" set to frame1 in this case, because that's the incumbent settings object when the API is called.  That "callback context" is then later used to push an incumbent script settings object when the callback is invoked, but of course that's not terribly observable from JS if the function is scripted; you have to resort to some fun trickery to make it observable.
Comment 6 Bobby Holley (:bholley) 2014-01-28 19:56:01 UTC
(In reply to Boris Zbarsky from comment #5)
> That would apply to event _handlers_, but not to event _listeners_.

Ah, yeah. I'd always felt like the spec should say more about this in more places, but I always assumed I just didn't fully understand something.

Ignore the rest of comment 4 - I was confused. I agree that we should set the entry point to the global of the callback object.
Comment 7 Bobby Holley (:bholley) 2014-01-29 17:06:17 UTC
Ok, I think I remember what I was getting at in comment 4 when I was referring to implicit Function conversion.

IIUC, callers can equivalently do:

foo.addEventListener("evt", func);
and
foo.addEventListener("evt", {handleEvent: func});

My understanding was that the bindings were supposed to implicitly box the former into the latter. If that happens, where does the box get created? The options I can think of are:
* The scope of |foo|
* The scope of |func|
* The scope of the caller

Depending on what the answer there is, we get a different entry point.
Comment 8 Olli Pettay 2014-01-29 18:13:17 UTC
Just to remind,
in case of foo.addEventListener("evt", func); 'this' in func is foo

and foo.addEventListener("evt", {handleEvent: func}); 'this' in func
is the object which has handleEvent property
Comment 9 Boris Zbarsky 2014-01-29 19:11:35 UTC
> My understanding was that the bindings were supposed to implicitly box the
> former into the latter.

Not quite.  The bindings in both cases create a WebIDL EventListener object wrapping the JS object.  This WebIDL object has a handleEvent method.  That method, when called, does different things depending on whether the JS object it wraps is callable or not.

> If that happens, where does the box get created?

The question is somewhat meaningless, since the "box" has no corresponding JS object.
Comment 10 Domenic Denicola 2016-06-02 20:46:56 UTC
This was fixed for entry settings in https://github.com/heycam/webidl/pull/113; work on incumbent is ongoing in https://github.com/whatwg/html/pull/1189 but we can track that there.