[webcomponents] [Custom]: What should be the name of the generated constructor returned by registerElement? (bugzilla: 25830) (#211)

Title: [Custom]: What should be the name of the generated constructor returned by registerElement? (bugzilla: 25830)

Migrated from: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830

----
comment: 0
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c0
*johnjbarton* wrote on 2014-05-20 15:54:42 +0000.

Two parts of the definition of Custom Elements conflict:

http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-type
"The custom element type identifies a custom element interface and is a sequence of characters that must match the NCName production, must contain a U+002D HYPHEN-MINUS character, and must not contain any uppercase ASCII letters."

http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-constructor
"All custom elements must be constructable with a function object, called custom element constructor. "

A name defined as containing a dash cannot be parsed as a function name in JavaScript. Consequently the two definitions above prevent mocking of Custom Elements in a way fully compatible with the standard.

----

comment: 1
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c1
*Dimitri Glazkov* wrote on 2014-05-20 16:51:48 +0000.

(In reply to johnjbarton from comment #0)
> Two parts of the definition of Custom Elements conflict:
> 
> http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-type
> "The custom element type identifies a custom element interface and is a
> sequence of characters that must match the NCName production, must contain a
> U+002D HYPHEN-MINUS character, and must not contain any uppercase ASCII
> letters."
> 
> http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-
> constructor
> "All custom elements must be constructable with a function object, called
> custom element constructor. "
> 
> A name defined as containing a dash cannot be parsed as a function name in
> JavaScript. Consequently the two definitions above prevent mocking of Custom
> Elements in a way fully compatible with the standard.

\<_< ... Is the problem with the meaning of the word "identifies"? Where is the custom element type parsed into a function name in the spec?

----

comment: 2
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c2
*johnjbarton* wrote on 2014-05-20 17:00:14 +0000.

This issue arose when mocking or faking Custom Elements. I needed to create a representation for the constructor function returned by document.registerElement(). It's not currently possible because registerElement() requires a function name identifier that is invalid in JavaScript.  That seems unfortunate given the focus on JavaScript for the API.

----

comment: 3
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c3
*Dimitri Glazkov* wrote on 2014-05-20 17:03:11 +0000.

(In reply to johnjbarton from comment #2)
> This issue arose when mocking or faking Custom Elements. I needed to create
> a representation for the constructor function returned by
> document.registerElement(). It's not currently possible because
> registerElement() requires a function name identifier that is invalid in
> JavaScript.  That seems unfortunate given the focus on JavaScript for the
> API.

Can you help me understand where in the spec the custom element type and function name are connected? They should be two separate concepts that are associated together in a definition via the process of registration.

----

comment: 4
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c4
*johnjbarton* wrote on 2014-05-20 17:31:48 +0000.

Yes, the type name is passed in to registerElement():
---
partial interface Document {
    Function registerElement(DOMString type, optional ElementRegistrationOptions options);
};
---
and a Function is returned. The 'name' property of the returned function object will be a string matching 'type'.


The section on es6 
http://w3c.github.io/webcomponents/spec/custom/#es6
has a different API and here it seems even more problematic:
---
The steps run when calling registerElement will change to:

Input
DOCUMENT, method's context object, a document
TYPE, the custom element type of the element being registered
FUNCTION, the custom element constructor, optional
---
The 'custom element constructor' is 
http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-constructor
which says in part
---
Let CONSTRUCTOR be the interface object whose interface prototype object is PROTOTYPE and when called as a constructor, executes these steps:
Let ELEMENT be the context object
Let TYPE be the custom element type in DEFINITION
Let NAME be the local name in DEFINITION
---
I don't see how one can supply the constructor function required by this API through ordinary JS code.

To be sure I am not able to see exactly where the standard connects the "local name" with the TYPE. Experimentally you can see the connection in Chrome by typing into devtools console:

document.registerElement('x-foo')
gives
function x-foo() { [native code] }

----

comment: 5
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c5
*Dimitri Glazkov* wrote on 2014-05-20 17:37:20 +0000.

(In reply to johnjbarton from comment #4)
> Yes, the type name is passed in to registerElement():
> ---
> partial interface Document {
>     Function registerElement(DOMString type, optional
> ElementRegistrationOptions options);
> };
> ---
> and a Function is returned. The 'name' property of the returned function
> object will be a string matching 'type'.

Well, no, that's not specified anywhere.

> 
> 
> The section on es6 
> http://w3c.github.io/webcomponents/spec/custom/#es6
> has a different API and here it seems even more problematic:
> ---
> The steps run when calling registerElement will change to:
> 
> Input
> DOCUMENT, method's context object, a document
> TYPE, the custom element type of the element being registered
> FUNCTION, the custom element constructor, optional
> ---
> The 'custom element constructor' is 
> http://w3c.github.io/webcomponents/spec/custom/#dfn-custom-element-
> constructor
> which says in part
> ---
> Let CONSTRUCTOR be the interface object whose interface prototype object is
> PROTOTYPE and when called as a constructor, executes these steps:
> Let ELEMENT be the context object
> Let TYPE be the custom element type in DEFINITION
> Let NAME be the local name in DEFINITION
> ---
> I don't see how one can supply the constructor function required by this API
> through ordinary JS code.

No, you're just not reading the rest of the monkey-patching of the spec down below. The meaning of custom element constructor will change for ES6.

> 
> To be sure I am not able to see exactly where the standard connects the
> "local name" with the TYPE. Experimentally you can see the connection in
> Chrome by typing into devtools console:
> 
> document.registerElement('x-foo')
> gives
> function x-foo() { [native code] }

This just seems like a bug in Chrome. It's not anything that spec describes.

----

comment: 6
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c6
*Dimitri Glazkov* wrote on 2014-05-20 17:42:41 +0000.

Filed https://code.google.com/p/chromium/issues/detail?id=375357

----

comment: 7
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c7
*johnjbarton* wrote on 2014-05-20 17:46:02 +0000.

What value does the spec say the constructor function name should have?

----

comment: 8
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c8
*Dimitri Glazkov* wrote on 2014-05-20 17:48:12 +0000.

(In reply to johnjbarton from comment #7)
> What value does the spec say the constructor function name should have?

Now, that's a good question. Can it be anonymous function?

----

comment: 9
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c9
*johnjbarton* wrote on 2014-05-20 17:57:48 +0000.

Yes seems like anonymous is fine:

>function fakeRegisterElement() { return function() { console.log('born'); } }
undefined
>var xFoo = fakeRegisterElement()
undefined
> new xFoo
born VM2040:2
Object {}

----

comment: 10
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c10
*Erik Arvidsson* wrote on 2014-05-20 17:59:35 +0000.

Anonymous sounds reasonable to me. The name should be "".

var f = function() {};
console.log(f.name); // ""

----

comment: 11
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25830#c11
*Dominic Cooney* wrote on 2014-05-22 02:04:24 +0000.

Blink implementor feedback:

Blink names the function after the Custom Element name. My thinking was it is helpful for the developer to have a hint about what the function relates to when playing with it interactively. It is not a valid JavaScript identifier, although for that matter [native code] is not a valid function body; I'm not sure what spec requires these names to be valid.

>From this bug and feedback from our test suite submission authors apparently people expect the spec to have a requirement for this.

I think it will not be a problem for Blink to implement a different name.

---
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/211

Received on Monday, 6 July 2015 07:41:13 UTC