W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2013

Re: document.register and ES6

From: Daniel Buchner <daniel@mozilla.com>
Date: Tue, 5 Feb 2013 17:51:11 -0800
Message-ID: <CAHZ6zJEbS1c51nTAmaz_EWLSFGcJGzuVedhFktXYeTLE5_seNA@mail.gmail.com>
To: Erik Arvidsson <arv@chromium.org>
Cc: public-webapps <public-webapps@w3.org>, Dimitri Glazkov <dglazkov@google.com>, Boris Zbarsky <bzbarsky@mit.edu>
*
So this won't work?*

var MyButton = document.register(‘x-mybutton’, {
    prototype: Object.create(HTMLButtonElement.prototype, { ... })
});
class MySuperButton extends MyButton { ... };
document.register('x-superbutton', MySuperButton);

*But this will?*

function MyButton() {
  HTMLButtonElement.call(this);
  // yay, I can have a real constructor!
  // do constructor stuff ...
}
MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
  ...
});
document.register(‘x-button’, MyButton);

Can someone reply with a terse pro/con/gain/loss list that identifies what
parts of the current API (and its behavior) this proposal affects?

Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation


On Tue, Feb 5, 2013 at 2:12 PM, Erik Arvidsson <arv@chromium.org> wrote:

> The way document.register is currently proposed makes it
> future-hostile to ES6. I've heard several people from different
> organizations say that this is a blocking issue.
>
> Over the last couple of days we (me, Dimitri and others) have worked
> on some alterations to the current spec proposal. The discussion got
> pretty extensive so I'll try to summarize the main points.
>
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=20831
>
> With ES6 we really want to be able to write code like this:
>
> class MyButton extends HTMLButtonElement {
>   ...
> }
> document.register('x-button', MyButton);
>
> In ES6 speak, we have split the "new Foo(...args)" expression into
> "Foo.call(Foo[@@create](), ...args)" which means that creating the
> instance has been separated from the call to the function. This allows
> us to subclass Array etc. It also opens up possibilities to subclass
> Element. All Element need is a @@create method that creates the
> instance (and sets the internal pointer to the underlying C++ object
> like we do today). For custom elements we can therefore generate the
> @@create method for the function passed to document.register. This
> function would create an instance in the same way as previously speced
> at
> https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-instantiation
>
> == What about ES5/3? ==
>
> In ES5/3 speak we don't have the @@create refactoring but we do have
> an internal [[Construct]] method. In the reformed version of
> document.create we can override [[Construct]] of the passed in
> function to create the instance and then do the [[Call]].
>
> This also means API change from what is currently specified. Instead of
>
> document.register(‘x-button’, { prototype:
> Object.create(HTMLButtonElement.prototype, {
>   ...
> });
>
> We will have:
>
> function MyButton() {
>   HTMLButtonElement.call(this);
>   // yay, I can have a real constructor!
>   // do constructor stuff ...
> }
> MyButton.prototype = Object.create(HTMLButtonElement.prototype, {
>   ...
> });
> document.register(‘x-button’, MyButton);
>
> We think it’s much better, because:
> a) we no longer have to spit out some magic generated constructor
> b) we can let developers have a constructor in their custom element
> c) there will be no API changes when ES6 classes arrive
> d) there is no longer a need for crazy callbacks “created” and
> “shadowRootCreated”, because they can just be code in the constructor
>
> == Does this mean that the user code now runs while parsing? ==
>
> We’ve heard in the past that allowing user code execution while the
> parser is building a tree is undesirable due to performance and
> specific design issues. However, now that the custom element
> constructor is no longer generated, it may appear as if the
> user-specified constructor would run when each element is
> instantiated.
>
> We intend to address this as follows:
> * When the parser builds a tree, it only creates underlying C++ objects
> * Just before entering script,
> * we first instantiate all custom elements (think Object.create, but
> with all the baggage of being a wrapper around a C++ object), so that
> they all have the right prototype chains, in tree order
> * then, we invoke the respective internal [[Call]] methods of all
> custom elements, in tree order
>
> How does template fit into this?
>
> The dependencies on template and shadow DOM are now removed from
> document.register API. If people want to use a template and shadow DOM
> they can easily do this in code:
>
> class MyButton extends HTMLButtonElement {
>   constructor() {
>     super();
>     var template = ...
>     var shadowRoot = this.createShadowRoot();
>     shadowRoot.appendChild(template.content.cloneNode(true));
>   }
> }
> document.register('x-button', MyButton);
>
>
> --
> erik
>
Received on Wednesday, 6 February 2013 01:52:08 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:57 GMT