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

Re: document.register and ES6

From: Scott Miles <sjmiles@google.com>
Date: Wed, 6 Feb 2013 13:07:32 -0800
Message-ID: <CAHbmOLaw92YqdKuPKO1Q+oU+COWv6tn16ePOtWNCtNf6UKw6EQ@mail.gmail.com>
To: Erik Arvidsson <arv@chromium.org>
Cc: Daniel Buchner <daniel@mozilla.com>, Dimitri Glazkov <dglazkov@google.com>, public-webapps <public-webapps@w3.org>, Boris Zbarsky <bzbarsky@mit.edu>
Well, this (non-robust quicky test) works in IE:

http://jsfiddle.net/zUzCx/1/


On Wed, Feb 6, 2013 at 12:59 PM, Scott Miles <sjmiles@google.com> wrote:

> Afaik, the 'generated constructor' is technical debt we are stuck with
> until we can actually invoke DOM constructors from JS. If there is a better
> way around it, I'm all ears!
>
> polyfilling without __proto__: I don't know if it's possible, which is a
> good point. I was basically ignoring that problem, but I guess I should not
> do that: we may have to utterly change our target.
>
> Iow, perhaps we can decorate node instances with API scraped off of a
> separate prototype chain. Ironically, this is close to what my component
> sugaring layer does anyway, in order to support protected API.
>
> S
>
>
> On Wed, Feb 6, 2013 at 12:50 PM, Erik Arvidsson <arv@chromium.org> wrote:
>
>> 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 21:08:02 GMT

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