Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
hayatoito opened this issue Jul 6, 2015 · 1 comment

Comments

@hayatoito
Copy link
Contributor

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.

@rniwa
Copy link
Collaborator

rniwa commented Mar 1, 2016

This is irrelevant now that we're going to have defineElement which preserves the author defined constructor in the issue #140.

@rniwa rniwa closed this as completed Mar 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants