Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is a subclass still a platform object? #540

Closed
annevk opened this issue Apr 5, 2018 · 13 comments
Closed

Is a subclass still a platform object? #540

annevk opened this issue Apr 5, 2018 · 13 comments

Comments

@annevk
Copy link
Member

annevk commented Apr 5, 2018

Related a bit to #533.

I'm wondering if a subclass of, .e.g., EventTarget, would still be considered a platform object. Otherwise we need to expand the definition of "relevant global object" and potentially other such concepts.

And even then we might need to clarify things here, e.g.,

<iframe></iframe>
...<script>
class X extends frames[0].EventTarget {};
</script>
@annevk
Copy link
Member Author

annevk commented Apr 5, 2018

FWIW, it seems that at least Chrome shifts the relevant global object in that case, see:

.<iframe></iframe>
<script>
class X extends frames[0].EventTarget {};
obj = new X();
obj.addEventListener("hi", () => w(window.event));
obj.dispatchEvent(new Event("hi"));
</script>

@bzbarsky
Copy link
Collaborator

bzbarsky commented Apr 5, 2018

So in Gecko, if you do your example above, I am pretty sure that obj is a platform object and its relevant global is frames[0].

@annevk
Copy link
Member Author

annevk commented Apr 5, 2018

Yeah, Henri said that's what happened with his patch in https://bugzilla.mozilla.org/show_bug.cgi?id=218415. For Chrome it's window though. 😟

@bzbarsky
Copy link
Collaborator

bzbarsky commented Apr 5, 2018

Hrm. In the end you're executing frames[0].EventTarget and that's defined to create objects in its own global... The WebIDL spec used to clearly say that when you create things via a constructor they are associated with that constructor's global, but I don't see that text in there now. @tobie, @domenic, did it get lost in one of the refactorings or something?

Anyway, here's a less-magical testcase for this:

<iframe></iframe>
<script>
class X extends frames[0].Image {};
obj = new X();
w(obj.ownerDocument == document);
w(obj.ownerDocument == frames[0].document);
</script>

(live at http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=5856). And yes, Firefox and Chrome disagree here. Firefox logs false then true, while Chrome logs true then false.

Safari logs false then true (but also doesn't create the object with X.prototype as the proto, of course). Edge behaves like Safari.

Given that, sounds like Chrome is the odd one out in terms of what it does here....

@bzbarsky
Copy link
Collaborator

bzbarsky commented Apr 5, 2018

And for extra excitement, here's another interesting testcase:

<iframe></iframe>
<script>
var X = new frames[0].Proxy(Image, {})
obj = new X();
w(obj.ownerDocument == document);
w(obj.ownerDocument == frames[0].document);
</script>

live at http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=5859. Here Chrome logs false, then true. Everyone else logs true then false. This doesn't involve subclassing, but shows the same behavior difference. Basically, Chrome is using the Realm of new.target, not the Realm of the actual constructor, to create objects. Per that language that's mysteriously disappeared from the IDL spec, that's a Chrome bug.

@bzbarsky
Copy link
Collaborator

bzbarsky commented Apr 5, 2018

Oh, also, even in today's spec https://heycam.github.io/webidl/#interface-object creation steps step 11 asserts that the newly-created thing's Realm is the realm of the constructor, not of the NewTarget. Which is an assert Chrome would fail.

Looks like that assert is not clearly supported by any normative requirements, though. Those normative requirements used to exist, but were removed in 4a8f57e2 for some reason. Before that, there were clear statements like:

This object also must be associated with the ECMAScript global environment associated with the [=named constructor=]

which seem to be gone now. @tobie, @domenic, why did those get removed?

@tobie
Copy link
Collaborator

tobie commented Apr 13, 2018

So to make sure we're on the same page here, we're looking at both interface objects and named constructors, right?

Prior to 4a8f57e, there were no additional normative requirements for platform objects created by interface objects to be of the same Realm as the interface object that constructed them beyond the |O|.\[[Realm]] is equal to |F|.\[[Realm]] assertion. I think the idea was that it was for the spec defining the interface to be explicit about the Realm platform objects were created in (is that right, @domenic?). I agree that the assertion makes that requirement on the interface defining spec sort of redundant, however. IMHO, this is something we should fix in the platform object creation algorithm I'm working on, by making it explicit. Do we agree?

Wrt to named constructors, that requirement is still there, it just was rephrase a bit and moved to the second paragraph of §3.6.2. Named constructors (emphasis mine):

If the actions listed in the description of the constructor return normally, then those steps must return an object that implements interface I. This object’s relevant Realm must be the same as that of the named constructor.

This should be also fixed in the same platform object creation algorithm. Does that make sense?

Am I missing anything?

@annevk
Copy link
Member Author

annevk commented Apr 13, 2018

That all sounds correct. What's unique here is that the "interface object" is in userland.

@bzbarsky
Copy link
Collaborator

Prior to 4a8f57e, there were no additional normative requirements for platform objects created by interface objects to be of the same Realm as the interface object that constructed them

Yes, but I believe there were such requirements earlier on. I didn't dig further back in history to double-check, though.

What's unique here is that the "interface object" is in userland.

new.target is in userland, if by that you mean page-script-defined. The actual constructor that's running is not.

And yes, we're talking about both named constructors and interface objects.

@Ms2ger
Copy link
Member

Ms2ger commented Feb 27, 2019

I think this is all fully defined now.

@annevk
Copy link
Member Author

annevk commented Feb 27, 2019

So how is #540 (comment) defined? Presumably it at least requires changes in DOM of some kind?

@Ms2ger
Copy link
Member

Ms2ger commented Mar 1, 2019

We talked about this a bit on IRC: https://freenode.logbot.info/whatwg/20190227#c2028215

@annevk
Copy link
Member Author

annevk commented Mar 1, 2019

And the conclusion there was that the remainder is effectively #135.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants