This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
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).
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...
(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.
> 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.
(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.
> 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.
(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.
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.
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
> 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.
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.