This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
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.
(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?
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.
(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.
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] }
(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.
Filed https://code.google.com/p/chromium/issues/detail?id=375357
What value does the spec say the constructor function name should have?
(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?
Yes seems like anonymous is fine: >function fakeRegisterElement() { return function() { console.log('born'); } } undefined >var xFoo = fakeRegisterElement() undefined > new xFoo born VM2040:2 Object {}
Anonymous sounds reasonable to me. The name should be "". var f = function() {}; console.log(f.name); // ""
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.
Moved to https://github.com/w3c/webcomponents/issues/211