- From: Scott Miles <sjmiles@google.com>
- Date: Wed, 6 Feb 2013 12:59:58 -0800
- 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>
- Message-ID: <CAHbmOLbLqpN=gF2ybwh9UY0ywprFxJaBUtkZiRrTrGG0r-NVCg@mail.gmail.com>
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 UTC