Bug 114457 - typeof non-callback interfaces without [NoInterfaceObject] should be "function"
Summary: typeof non-callback interfaces without [NoInterfaceObject] should be "function"
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords: EasyFix, WebExposed
Depends on:
Blocks:
 
Reported: 2013-04-11 12:29 PDT by Erik Arvidsson
Modified: 2022-09-04 13:11 PDT (History)
13 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Erik Arvidsson 2013-04-11 12:29:14 PDT
typeof HTMLElement is "function" in IE, Firefox and Chrome. Safari (WebKit+JSC) is the only one that returns "object" here.
Comment 1 Oliver Hunt 2013-04-11 12:43:31 PDT
is HTMLElement a constructor now?
Comment 2 Erik Arvidsson 2013-04-11 12:49:04 PDT
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');
  }
}
Comment 3 Oliver Hunt 2013-04-11 12:54:51 PDT
(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?
Comment 4 Erik Arvidsson 2013-04-11 12:59:31 PDT
(In reply to comment #3)
> It's really defined as being a constructor, but throws anyway? why?

Consistency.
Comment 5 Glenn Adams 2013-04-11 13:13:08 PDT
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
Comment 6 Erik Arvidsson 2013-04-11 13:20:04 PDT
(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).
Comment 7 Oliver Hunt 2013-04-11 13:58:43 PDT
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
Comment 8 Glenn Adams 2013-04-11 14:08:06 PDT
(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?
Comment 9 Glenn Adams 2013-04-11 14:10:17 PDT
In which case this bug should be closed as INVALID and a new bug opened on instanceof HTMLElement et al, yes?
Comment 10 Oliver Hunt 2013-04-11 14:11:32 PDT
(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)
Comment 11 Erik Arvidsson 2013-04-11 14:37:49 PDT
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)?
Comment 12 Cameron McCormack (:heycam) 2013-04-11 15:31:09 PDT
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.
Comment 13 Adam Roben (:aroben) 2015-03-19 10:37:50 PDT
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".
Comment 14 Ahmad Saleem 2022-09-03 04:46:25 PDT
rniwa@webkit.org - Is this still an issue or needed? Thanks!
Comment 15 Alexey Proskuryakov 2022-09-04 13:11:26 PDT
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.