- From: Erik Arvidsson <arv@chromium.org>
- Date: Wed, 6 Feb 2013 15:50:33 -0500
- 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 UTC