- From: Scott Miles <sjmiles@google.com>
- Date: Wed, 6 Feb 2013 11:59:09 -0800
- To: Erik Arvidsson <arv@chromium.org>
- Cc: Dimitri Glazkov <dglazkov@google.com>, Daniel Buchner <daniel@mozilla.com>, public-webapps <public-webapps@w3.org>, Boris Zbarsky <bzbarsky@mit.edu>
- Message-ID: <CAHbmOLYC3gvFq4YustOK4gzcgEKV0n4eaQUQ_rPodVzgGy083w@mail.gmail.com>
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 >
Received on Wednesday, 6 February 2013 19:59:37 UTC