[webcomponents] [Custom]: A tag name should be associated with the constructor and not the prototype (bugzilla: 24020) (#214)

Title: [Custom]: A tag name should be associated with the constructor and not the prototype (bugzilla: 24020)

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

----
comment: 0
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=24020#c0
*Erik Arvidsson* wrote on 2013-12-06 15:58:32 +0000.

Given how WebIdl works with interfaces that are realized as ES constructor functions with a prototype we should associate the tag name with a function and not the prototype.

class MyElement extends HTMLElement {}
associate('my-element, MyElement)

When an element is created for 'my-element' we find the registered Function and call its @@create-(this-is-inserted-to-avoid-notification-in-migration). Here is how HTMLElement @@create-(this-is-inserted-to-avoid-notification-in-migration) is implemented.

var constructorToNameMap = new WeakMap();

function associate(name, constr) {
  constructorToNameMap.set(constr, name);
}

HTMLElement[Symbol.create] = function() {
  var name = constructorToNameMap.get(this);
  if (!name)
    throw new TypeError('Illegal constructor');

  // $Internal_createElementWithName(name);
  return document.createElement(name);    
};

The common case is that people do not override @@create-(this-is-inserted-to-avoid-notification-in-migration) so we do not need to run any user code to create an instance. When the user does a `new MyElement` we do run the constructor, just like for all other js constructors.

----

comment: 1
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=24020#c1
*Dominic Cooney* wrote on 2013-12-08 00:32:29 +0000.

I think this should be addressed in Level 2 of the Custom Elements spec, or in a related spec. Chrome is not in a position to implement this now.

The current implementation in Chrome associates the registered element name with the generated constructor. This is effectively the same data as the constructorToNameMap. So I think Chrome would have no problem implementing requirements based on your proposal.

I do not think the specification needs to be as literal as the JavaScript you have provided here, but it is a good informative sketch.

I think that the requirement that registering a Custom Element with a prototype that is an interface prototype object should be relaxed to allow multiple element names to share a prototype as is the case with built-in elements like HTMLHeadingElement, etc. Perhaps misuse of a built-in interface prototype object should be disallowed, however Chrome would not have a problem with a completely laissez-faire approach.

Relaxing the interface prototype object restriction would be a forward-compatible change because it makes errors into non-errors.

----

comment: 2
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=24020#c2
*Dimitri Glazkov* wrote on 2014-05-12 22:08:11 +0000.

I am trying to work out what is the significance of storing constructor, rather than prototype in custom element definition. Can you help me understand that?

----

comment: 3
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=24020#c3
*Erik Arvidsson* wrote on 2014-05-13 13:56:04 +0000.

I think this is mostly conceptual since we are locking down the prototype and constructor properties so we can go back and forth as needed.

However, ES/WebIDL works with Functions and ES6 has meta operations for creating new objects from a constructor, not from its prototype (since the prototype does not have any relevance to how the instance is created).

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-createfromconstructor

----

comment: 4
comment_url: https://www.w3.org/Bugs/Public/show_bug.cgi?id=24020#c4
*Dimitri Glazkov* wrote on 2014-05-13 14:22:28 +0000.

(In reply to Erik Arvidsson from comment #3)
> I think this is mostly conceptual since we are locking down the prototype
> and constructor properties so we can go back and forth as needed.
> 
> However, ES/WebIDL works with Functions and ES6 has meta operations for
> creating new objects from a constructor, not from its prototype (since the
> prototype does not have any relevance to how the instance is created).
> 
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-
> createfromconstructor

Ah! That makes sense. I will leave the bug open and block it on bug 25669.

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

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