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 12:59:58 -0800
Message-ID: <CAHbmOLbLqpN=gF2ybwh9UY0ywprFxJaBUtkZiRrTrGG0r-NVCg@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>
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:00:27 GMT

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