This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 25830 - [Custom]: What should be the name of the generated constructor returned by registerElement?
Summary: [Custom]: What should be the name of the generated constructor returned by re...
Status: RESOLVED MOVED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 14968
  Show dependency treegraph
 
Reported: 2014-05-20 15:54 UTC by johnjbarton
Modified: 2015-07-06 08:04 UTC (History)
4 users (show)

See Also:


Attachments

Description johnjbarton 2014-05-20 15:54:42 UTC
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 Dimitri Glazkov 2014-05-20 16:51:48 UTC
(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 johnjbarton 2014-05-20 17:00:14 UTC
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 Dimitri Glazkov 2014-05-20 17:03:11 UTC
(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 johnjbarton 2014-05-20 17:31:48 UTC
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 Dimitri Glazkov 2014-05-20 17:37:20 UTC
(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 Dimitri Glazkov 2014-05-20 17:42:41 UTC
Filed https://code.google.com/p/chromium/issues/detail?id=375357
Comment 7 johnjbarton 2014-05-20 17:46:02 UTC
What value does the spec say the constructor function name should have?
Comment 8 Dimitri Glazkov 2014-05-20 17:48:12 UTC
(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 johnjbarton 2014-05-20 17:57:48 UTC
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 Erik Arvidsson 2014-05-20 17:59:35 UTC
Anonymous sounds reasonable to me. The name should be "".

var f = function() {};
console.log(f.name); // ""
Comment 11 Dominic Cooney 2014-05-22 02:04:24 UTC
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.
Comment 12 Hayato Ito 2015-07-06 08:04:39 UTC
Moved to https://github.com/w3c/webcomponents/issues/211