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

Re: document.register and ES6

From: Erik Arvidsson <arv@chromium.org>
Date: Wed, 6 Feb 2013 15:50:33 -0500
Message-ID: <CAJ8+GojKg9h7h6Mw_d9VX881ReswoZOff9V1v312O+p6Tco7wA@mail.gmail.com>
To: Scott Miles <sjmiles@google.com>
Cc: Daniel Buchner <daniel@mozilla.com>, Dimitri Glazkov <dglazkov@google.com>, public-webapps <public-webapps@w3.org>, Boris Zbarsky <bzbarsky@mit.edu>
If we are willing to return a new constructor function I think we have
no problems. I was concerned that it would lead to people using the
wrong function but it does solve the issues.

class MyButtonImpl extends HTMLButtonElement {
}
let MyButton = document.register('my-button', {
  class: MyButtonImpl // maybe call the property "implementation" if
we don't want to use "class".
});

I feel like this is getting close to my pain tolerance for boilerplate
code but I'm willing to realize that currently this is the only
working proposal (for polyfilling in __proto__ browser).

I'm still curious how people are planning to do this in non __proto__ browsers?

On Wed, Feb 6, 2013 at 3:43 PM, Scott Miles <sjmiles@google.com> wrote:
> Yes, it's not intended to work in IE ... I used __proto__.
>
>
> On Wed, Feb 6, 2013 at 12:41 PM, Daniel Buchner <daniel@mozilla.com> wrote:
>>
>> Scott: is this example not intended to work in IE9? It throws, the output
>> object is missing the 'oranginate' method.
>>
>> Daniel J. Buchner
>> Product Manager, Developer Ecosystem
>> Mozilla Corporation
>>
>>
>> On Wed, Feb 6, 2013 at 12:32 PM, Scott Miles <sjmiles@google.com> wrote:
>>>
>>> There were several errors in my pseudo-code, here is a working version:
>>>
>>> http://jsfiddle.net/yNbnL/1/
>>>
>>> S
>>>
>>>
>>> On Wed, Feb 6, 2013 at 12:01 PM, Scott Miles <sjmiles@google.com> wrote:
>>>>
>>>> Errata:
>>>>  makePrototypeTwiddlingConstructorForDomNodes needs to know the extendee
>>>>
>>>> var ctor = makePrototypeTwiddlingConstructorForDomNodes(inExtends,
>>>> inClass);
>>>>
>>>>
>>>> On Wed, Feb 6, 2013 at 11:59 AM, Scott Miles <sjmiles@google.com> wrote:
>>>>>
>>>>> On Wed, Feb 6, 2013 at 11:18 AM, Erik Arvidsson <arv@chromium.org>
>>>>> wrote:
>>>>>>
>>>>>> On Wed, Feb 6, 2013 at 1:38 PM, Scott Miles <sjmiles@google.com>
>>>>>> wrote:
>>>>>> > Sorry, replace MyButton.super() with MyButton.super.call(this);
>>>>>> >
>>>>>> >
>>>>>> > On Wed, Feb 6, 2013 at 10:37 AM, Scott Miles <sjmiles@google.com>
>>>>>> > wrote:
>>>>>> >>
>>>>>> >> So, neglecting issues around the syntax of document.register and
>>>>>> >> the
>>>>>> >> privatization of callbacks, is it fair to say the following is the
>>>>>> >> intended
>>>>>> >> future:
>>>>>> >>
>>>>>> >> class MyButton extends HTMLButtonElement {
>>>>>> >>   constructor() {
>>>>>> >>     super();
>>>>>> >>     // make root, etc.
>>>>>> >>   }
>>>>>> >> }
>>>>>> >> document.register('x-button', MyButton);
>>>>>> >>
>>>>>> >> If so then can we do this in the present:
>>>>>> >>
>>>>>> >> MyButtonImpl = function() {
>>>>>>
>>>>>> What do you mean here?
>>>>>>
>>>>>> >>   MyButton.super();
>>>>>>
>>>>>> Did you get that backwards? I don't see how MyButtonImpl can be
>>>>>> derived from MyButton.
>>>>>
>>>>>
>>>>> Its not. The 'super' means 'the super-class constructor for MyButton
>>>>> that does not include magic DOM object generation' (in this case,
>>>>> HTMLButtonElement). For MyDerivedButton, MyDerivedButton.super would point
>>>>> to MyButtonImpl.
>>>>>
>>>>> The existence of MyButtonImpl is an unfortunate side-effect of needing
>>>>> a generated constructor.
>>>>>
>>>>> The idea is to correspond as closely as possible with the ES6 version.
>>>>> MyButtonImpl goes away in ES6, it's purpose in the meantime is just to
>>>>> provide something that looks like a proper class.
>>>>>
>>>>> I could write it this way:
>>>>>
>>>>> MyButton = function() {
>>>>>
>>>>>  MyButton.super();
>>>>>  // make root, etc.
>>>>> };
>>>>> MyButton.prototype = Object.create(HTMLButtonElement, { ... });
>>>>> MyButton = document.register(‘x-button’, MyButton);
>>>>>
>>>>> Written this way, MyButton no longer refers to the constructor you
>>>>> specified, but instead refers to the generated constructor. This is
>>>>> conceptually cleaner, but it's a bit tricky. For maximum clarity, I named
>>>>> the internal version MyButtonImpl in my example code, but there is no reason
>>>>> to have that symbol.
>>>>>
>>>>>>
>>>>>>
>>>>>> >>   // make root, etc.
>>>>>> >> };
>>>>>> >> MyButtonImpl.prototype = Object.create(HTMLButtonElement, { ... });
>>>>>> >>
>>>>>> >> // the ‘real’ constructor comes from document.register
>>>>>> >> // register injects ‘super’ into MyButton
>>>>>> >> MyButton = document.register(‘x-button’, MyButtonImpl);
>>>>>>
>>>>>> What is the relationship between MyButton and MyButtonImpl?
>>>>>>
>>>>>> If MyButton.__proto__ === MyButtonImpl and
>>>>>> MyButton.prototype.__proto__ === MyButtonImpl.prototype then this
>>>>>> might work (but this cannot be polyfilled either).
>>>>>>
>>>>>
>>>>> MyButton.prototype == MyButtonImpl.prototype or
>>>>> MyButton.prototype.__proto__ == MyButtonImpl.prototype, depending on needs.
>>>>>
>>>>> MyButton itself does magic DOM construction work that we cannot do with
>>>>> normal inheritance, then invokes MyButtonImpl. MyButtonImpl is never used as
>>>>> a constructor itself (not as an argument to 'new' anyway).
>>>>>
>>>>> From the user's perspective, he has made a single class which
>>>>> implements his element (the goal!). The unfortunate name shenanigan (I
>>>>> called my class MyButtonImpl, but after 'register' I refer to it as
>>>>> MyButton) is the simplest way I could conceive to overcome the 'generated
>>>>> constructor' problem.
>>>>>
>>>>> To be clear, everything I come up with is intended to polyfill (modulo
>>>>> my error), because I generally am writing those myself (at first anyway).
>>>>> One version might look like this:
>>>>>
>>>>> document.register = function(inExtends, inClass) {
>>>>>   var ctor = makePrototypeTwiddlingConstructorForDomNodes(inClass);
>>>>>   ctor.prototype = inClass.prototype;
>>>>>   addToTagRegistry(inExtends, ctor, inClass);
>>>>>   ctor.super = getClassForExtendee(inExtends);
>>>>>   return ctor;
>>>>> };
>>>>>
>>>>>
>>>>>> --
>>>>>> erik
>>>>>
>>>>>
>>>>
>>>
>>
>



--
erik
Received on Wednesday, 6 February 2013 20:51:22 GMT

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