[Bug 29421] Should getters on a global without an explicit 'this' really throw TypeError?

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

Boris Zbarsky bzbarsky@mit.edu changed:

       What    |Removed                     |Added

             CC|                            |bzbarsky@mit.edu

--- Comment #1 from Boris Zbarsky bzbarsky@mit.edu ---

So the big web compat constraint here is that this should do the right thing:

var perf = performance;

needs to work. I believe in spec terms this ends up in www.ecma-international.org/ecma-262/6.0/#sec-object-environment-records-getbindingvalue-n-s which lands in www.ecma-international.org/ecma-262/6.0/#sec-get-o-p which will use the object associated with the object enviroment record (in this case the global) as "this". So for this part to work, no effort is needed on the part of IDL.

You're correct that the current Firefox behavior makes this also work:

Object.getOwnPropertyDescriptor(window, "performance").get.call()

I tried this in a few other browsers, with the following results:

1) Chrome. Seems to not actually have accessor properties on the window yet. Presumably they're still updating to Web IDL for the window... In any case, Object.getOwnPropertyDescriptor(window, "performance") returns a value descriptor.

2) Safari. Has some bizarre setup where descriptors on the global have undefined get and no value, but stuff somehow still works. Basically, totally violates the ES spec.

3) IE11. This seems to put the properties on window.proto, not window. Subject to that constraint, Object.getOwnPropertyDescriptor(window.proto, "performance").get.call() works.

4) Edge. Object.getOwnPropertyDescriptor(window, "performance").get.call() works.

Speccing the Firefox/Edge behavior makes some sense to me, especially because the only reason the bareword works otherwise is because it takes a weird path to the getter.

Contact us to advertise here
# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #2 from Christophe Dumez dchris@gmail.com --- (In reply to Boris Zbarsky from comment #1)

So the big web compat constraint here is that this should do the right thing:

var perf = performance;

needs to work. I believe in spec terms this ends up in www.ecma-international.org/ecma-262/6.0/#sec-object-environment- records-getbindingvalue-n-s which lands in www.ecma-international.org/ecma-262/6.0/#sec-get-o-p which will use the object associated with the object enviroment record (in this case the global) as "this". So for this part to work, no effort is needed on the part of IDL.

You're correct that the current Firefox behavior makes this also work:

Object.getOwnPropertyDescriptor(window, "performance").get.call()

I tried this in a few other browsers, with the following results:

1) Chrome. Seems to not actually have accessor properties on the window yet. Presumably they're still updating to Web IDL for the window... In any case, Object.getOwnPropertyDescriptor(window, "performance") returns a value descriptor.

2) Safari. Has some bizarre setup where descriptors on the global have undefined get and no value, but stuff somehow still works. Basically, totally violates the ES spec.

Yes, I work on WebKit and am currently fixing this issue. This is also why I wanted the behavior of implicit 'this' for the global Window Object to be clarified.

On WebKit nightly, it does return getters/setters now but the following: $ Object.getOwnPropertyDescriptor(window.proto, "performance").get.call() throws a "TypeError: The DOMWindow.performance getter can only be used on instances of DOMWindow" for now.

3) IE11. This seems to put the properties on window.proto, not window. Subject to that constraint, Object.getOwnPropertyDescriptor(window.proto, "performance").get.call() works.

4) Edge. Object.getOwnPropertyDescriptor(window, "performance").get.call() works.

Speccing the Firefox/Edge behavior makes some sense to me, especially because the only reason the bareword works otherwise is because it takes a weird path to the getter.

Also, I think we should be clear about which window we should fall back to when 'this' is null/undefined, in the case of subframes. E.g.

otherWin = open("about:blank"); locationGetter = Object.getOwnPropertyDescriptor(otherWin, "location"); locationGetter.call()

should this be identical to: locationGetter.call(otherWin) or locationGetter.call(window) ?

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #3 from Christophe Dumez dchris@gmail.com --- (In reply to Christophe Dumez from comment #2)

(In reply to Boris Zbarsky from comment #1)

So the big web compat constraint here is that this should do the right thing:

var perf = performance;

needs to work. I believe in spec terms this ends up in www.ecma-international.org/ecma-262/6.0/#sec-object-environment- records-getbindingvalue-n-s which lands in www.ecma-international.org/ecma-262/6.0/#sec-get-o-p which will use the object associated with the object enviroment record (in this case the global) as "this". So for this part to work, no effort is needed on the part of IDL.

You're correct that the current Firefox behavior makes this also work:

Object.getOwnPropertyDescriptor(window, "performance").get.call()

I tried this in a few other browsers, with the following results:

1) Chrome. Seems to not actually have accessor properties on the window yet. Presumably they're still updating to Web IDL for the window... In any case, Object.getOwnPropertyDescriptor(window, "performance") returns a value descriptor.

2) Safari. Has some bizarre setup where descriptors on the global have undefined get and no value, but stuff somehow still works. Basically, totally violates the ES spec.

Yes, I work on WebKit and am currently fixing this issue. This is also why I wanted the behavior of implicit 'this' for the global Window Object to be clarified.

On WebKit nightly, it does return getters/setters now but the following: $ Object.getOwnPropertyDescriptor(window.proto, "performance").get.call() throws a "TypeError: The DOMWindow.performance getter can only be used on instances of DOMWindow" for now.

3) IE11. This seems to put the properties on window.proto, not window. Subject to that constraint, Object.getOwnPropertyDescriptor(window.proto, "performance").get.call() works.

4) Edge. Object.getOwnPropertyDescriptor(window, "performance").get.call() works.

Speccing the Firefox/Edge behavior makes some sense to me, especially because the only reason the bareword works otherwise is because it takes a weird path to the getter.

Also, I think we should be clear about which window we should fall back to when 'this' is null/undefined, in the case of subframes. E.g.

otherWin = open("about:blank"); locationGetter = Object.getOwnPropertyDescriptor(otherWin, "location").get; locationGetter.call()

should this be identical to: locationGetter.call(otherWin) or locationGetter.call(window) ?

FYI, in this case, I would expect locationGetter.call() to behave the same way as locationGetter.call(window) as I think this is how it works in EcmaScript.

However, Firefox seems to do locationGetter.call(otherWin) in this case.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #4 from Boris Zbarsky bzbarsky@mit.edu ---

Yes, I work on WebKit and am currently fixing this issue.

Ah, awesome. :)

If we spec auto-picking a global, we should fall back to the global of the Realm of the getter function (basically, do what a non-strict scripted function would do). So in your example, for the same-origin case, that would be mean locationGetter.call() and locationGetter.call(otherWin) do the same thing.

For the cross-origin case, given the current spec proposals for cross-origin objects, the getter would be created in the Realm of the thing touching the cross-origin object, so locationGetter.call() would be equivalent to locationGetter.call(window). This slight weirdness only affects things one can get cross-origin on a window, which is just "location"... so I think I'm ok with it.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #5 from Christophe Dumez dchris@gmail.com --- (In reply to Boris Zbarsky from comment #4)

Yes, I work on WebKit and am currently fixing this issue.

Ah, awesome. :)

If we spec auto-picking a global, we should fall back to the global of the Realm of the getter function (basically, do what a non-strict scripted function would do). So in your example, for the same-origin case, that would be mean locationGetter.call() and locationGetter.call(otherWin) do the same thing.

Oh right, never mind. After re-reading the EcmaScript again, my initial expectation was incorrect. Firefox does seem to behave correctly then.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #6 from Christophe Dumez dchris@gmail.com ---

If this gets spec'd, I will work on supporting this in WebKit as well so Safari and Firefox would behave the same.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #7 from Christophe Dumez dchris@gmail.com ---

By the way, I have just noticed that the Window interface is not marked as [ImplicitThis] in the latest HTML specification: whatwg/html#643

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

Anne annevk@annevk.nl changed:

       What    |Removed                     |Added

             CC|                            |annevk@annevk.nl

--- Comment #8 from Anne annevk@annevk.nl ---

Is this a duplicate of bug 18547 now?

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #9 from Boris Zbarsky bzbarsky@mit.edu ---

Depends on whether "methods" includes attribute getters/setters or not.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

Domenic Denicola d@domenic.me changed:

       What    |Removed                     |Added

             CC|                            |d@domenic.me

--- Comment #10 from Domenic Denicola d@domenic.me ---

It should, right? I can edit the title; I guess that was just an assumption on my part.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #11 from Boris Zbarsky bzbarsky@mit.edu ---

If we expand the other bug to include accessors, then dupping seems fine to me.

# bugzilla at jessica.w3.org (a year ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

--- Comment #12 from Christophe Dumez dchris@gmail.com ---

FYI, this was implemented in WebKit to match Firefox's behavior: trac.webkit.org/changeset/196303

# bugzilla at jessica.w3.org (7 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

Domenic Denicola d@domenic.me changed:

       What    |Removed                     |Added

       Assignee|cam@mcc.id.au               |d@domenic.me

--- Comment #13 from Domenic Denicola d@domenic.me ---

I think this is not fixed for attributes, only for operations, so we can use this bug to track it. I'll take this since I fixed operations. In the process I'll probably overhaul the attribute getter/setter definitions to be modern.

# bugzilla at jessica.w3.org (4 months ago)

www.w3.org/Bugs/Public/show_bug.cgi?id=29421

Tobie Langel tobie.langel@gmail.com changed:

       What    |Removed                     |Added

         Status|NEW                         |RESOLVED
     Resolution|---                         |FIXED
             CC|                            |tobie.langel@gmail.com

--- Comment #14 from Tobie Langel tobie.langel@gmail.com ---

Fixed in heycam/webidl/commit/4c9c298

Want more features?

Request early access to our private beta of readable email premium.