Bug 114457
| Summary: | typeof non-callback interfaces without [NoInterfaceObject] should be "function" | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Erik Arvidsson <arv> |
| Component: | DOM | Assignee: | Nobody <webkit-unassigned> |
| Status: | RESOLVED CONFIGURATION CHANGED | ||
| Severity: | Normal | CC: | ahmad.saleem792, ap, aroben, bfulgham, cdumez, ggaren, glenn, heycam, oliver, rniwa, sam, syoichi, zan |
| Priority: | P2 | Keywords: | EasyFix, WebExposed |
| Version: | 528+ (Nightly build) | ||
| Hardware: | All | ||
| OS: | All | ||
Erik Arvidsson
typeof HTMLElement is "function" in IE, Firefox and Chrome. Safari (WebKit+JSC) is the only one that returns "object" here.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Oliver Hunt
is HTMLElement a constructor now?
Erik Arvidsson
It is not constructable but it has a prototype.
This is speced in WebIDL:
http://dev.w3.org/2006/webapi/WebIDL/#interface-object
> The interface object for a given non-callback interface is a function object.
-------------------
WebKit also returns `"object"` for `typeof XMLHttpRequest` which is clearly constructable. ;-)
----------------------
The DOM interface objects are like:
class HTMLElement extends Element {
constructor() {
throw new TypeError('Illegal constructor');
}
}
Oliver Hunt
(In reply to comment #2)
> It is not constructable but it has a prototype.
>
> This is speced in WebIDL:
>
> http://dev.w3.org/2006/webapi/WebIDL/#interface-object
>
> > The interface object for a given non-callback interface is a function object.
>
> -------------------
>
> WebKit also returns `"object"` for `typeof XMLHttpRequest` which is clearly constructable. ;-)
>
> ----------------------
>
> The DOM interface objects are like:
>
> class HTMLElement extends Element {
> constructor() {
> throw new TypeError('Illegal constructor');
> }
> }
It's really defined as being a constructor, but throws anyway? why?
Erik Arvidsson
(In reply to comment #3)
> It's really defined as being a constructor, but throws anyway? why?
Consistency.
Glenn Adams
My reading of WebIDL 4.4 [1] is that there is a more general requirement for non-callback interfaces that are not declared with [NoInterfaceObject], namely that:
(1) a corresponding property must exist on the ECMAScript global object;
(2) the name of the property is the identifier of the interface;
(3) its value is an object called the interface object; and
(4) the interface object for a given non-callback interface is a function object.
In some W3C CSSOM incoming tests [2], one can see how CSSStyleDeclaration is not instanceof Function on Safari, but works on FF and Opera.
So it isn't just HTMLElement.
[1] http://www.w3.org/TR/WebIDL/#es-interfaces
[2] http://hg.csswg.org/test/raw-file/default/contributors/gadams/incoming/cssom/cssstyledeclaration-interface.xht
Erik Arvidsson
(In reply to comment #5)
> In some W3C CSSOM incoming tests [2], one can see how CSSStyleDeclaration is not instanceof Function on Safari, but works on FF and Opera.
>
> So it isn't just HTMLElement.
Yeah, this all interface objects in WebKit. Even clearly constructable ones (like XMLHttpRequest and Image).
Oliver Hunt
Our behavior is correct here - HTMLElement is not callable, and therefore ECMAScript requires us to report it as type "object".
The bug (if you will) is that HTMLElement, etc aren't callable, and that instead they should be functions that are useless
Glenn Adams
(In reply to comment #7)
> Our behavior is correct here - HTMLElement is not callable, and therefore ECMAScript requires us to report it as type "object".
>
> The bug (if you will) is that HTMLElement, etc aren't callable, and that instead they should be functions that are useless
I concur that typeof(HTMLElement), typeof(CSSStyleDeclaration), etc., should be object, but that the type of the object should be a Function object, i.e., that HTMLElement instanceof Function be true. Are we agreeing?
Glenn Adams
In which case this bug should be closed as INVALID and a new bug opened on instanceof HTMLElement et al, yes?
Oliver Hunt
(In reply to comment #9)
> In which case this bug should be closed as INVALID and a new bug opened on instanceof HTMLElement et al, yes?
I think that's possibly best (new bug will avoid confusion caused by initial description)
Erik Arvidsson
http://dev.w3.org/2006/webapi/WebIDL/#es-interface-call
"The internal [[Call]] method of the interface object behaves as follows, assuming arg0..n−1 is the list of argument values passed to the constructor, and I is the interface:
1. If I was not declared with a [Constructor] extended attribute, then throw a TypeError."
Do we want to change the spec (which is correctly implemented today in 3 out 4 browsers)?
Cameron McCormack (:heycam)
My intention in the spec was to move towards typeof HTMLElement being "function", and HTMLElement being a regular function object. Having HTMLElement be callable but its [[Call]] throwing an exception was the way to do that.
Adam Roben (:aroben)
This causes the CustomEvent polyfill to be used in Safari even though CustomEvent is supported natively. See https://github.com/krambuhl/custom-event-polyfill/blob/eeb828bf89631ae4dc91efc1e8f508910ab41961/custom-event-polyfill.js#L7 which checks window.CustomEvent !== "function".
Ahmad Saleem
rniwa@webkit.org - Is this still an issue or needed? Thanks!
Alexey Proskuryakov
I believe we did work through all these issues. The simple "typeof HTMLElement" does say "function", although it wasn't quite straightforward to get there.