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 24020 - [Custom]: A tag name should be associated with the constructor and not the prototype
Summary: [Custom]: A tag name should be associated with the constructor and not the pr...
Status: RESOLVED MOVED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 25669
  Show dependency treegraph
 
Reported: 2013-12-06 15:58 UTC by Erik Arvidsson
Modified: 2015-07-06 08:16 UTC (History)
1 user (show)

See Also:


Attachments

Description Erik Arvidsson 2013-12-06 15:58:32 UTC
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. Here is how HTMLElement @@create 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 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 Dominic Cooney 2013-12-08 00:32:29 UTC
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 Dimitri Glazkov 2014-05-12 22:08:11 UTC
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 Erik Arvidsson 2014-05-13 13:56:04 UTC
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 Dimitri Glazkov 2014-05-13 14:22:28 UTC
(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.
Comment 5 Hayato Ito 2015-07-06 08:16:49 UTC
Moved to https://github.com/w3c/webcomponents/issues/214