I'm going to use the accessor technique as it's the only way. Thanks! I was trying to patch `Element` because there's also `SVGElement`. I suppose I can duplicate efforts and patch both `HTMLElement` and `SVGElement`; that's not too difficult, but it is conceptually uglier because for example, what if browsers come out with `MathElement`, `WebGLElement`, etc. /#!/JoePea
On Tue, Oct 24, 2017 at 10:55 AM, Michał Wadas <[email protected]> wrote: >> To "polyfill" an idea I have for DOM, to propose it later, etc. > > You can consider something like this depending on your needs: > https://gist.github.com/Ginden/03004e52b3d331e236b5256e3b4c08ff > > On Tue, Oct 24, 2017 at 7:47 PM, /#!/JoePea <[email protected]> wrote: >> >> @Michał >> >> > But why do you need this? >> >> To "polyfill" an idea I have for DOM, to propose it later, etc. >> >> @Logan >> >> > Why not store your data separately in a WeakMap and rather than >> > injecting properties onto existing objects? Then you can initialize the >> > stored data on first access of the data you want. >> >> I thought about that, it seems like the only way, but was curious to >> see about the the during-construction way if possible. >> >> @Andrea >> >> But this one doesn't work: >> >> ```js >> window.Element = class extends Element { >> constructor() { >> super(); >> console.log('hello darkness my old friend'); >> } >> }; >> >> // then ... >> class MyEl extends HTMLElement {} >> customElements.define('my-el', MyEl); >> >> new MyEl; >> ``` >> >> /#!/JoePea >> >> >> On Tue, Oct 24, 2017 at 10:36 AM, Andrea Giammarchi >> <[email protected]> wrote: >> > I know I'm going to regret this already, but since I've secretly played >> > with >> > polyfills, you can still do this: >> > >> > ```js >> > window.HTMLElement = class extends HTMLElement { >> > constructor() { >> > super(); >> > console.log('hello darkness my old friend'); >> > } >> > }; >> > >> > // then ... >> > class MyEl extends HTMLElement {} >> > customElements.define('my-el', MyEl); >> > >> > new MyEl; >> > ``` >> > >> > Regards >> > >> > >> > >> > On Tue, Oct 24, 2017 at 2:32 PM, Logan Smyth <[email protected]> >> > wrote: >> >> >> >> Given that these are constructors that you don't own, adding your own >> >> properties to them seems like an overall ugly approach to me. Why not >> >> store >> >> your data separately in a WeakMap and rather than injecting properties >> >> onto >> >> existing objects? Then you can initialize the stored data on first >> >> access of >> >> the data you want. >> >> >> >> On Tue, Oct 24, 2017 at 10:25 AM, /#!/JoePea <[email protected]> wrote: >> >>> >> >>> Well, I know I can set accessors on a prototype easily, but what I >> >>> mean is, I need each instance of an `Element` to have exactly one >> >>> instance of something right after construction during the same >> >>> synchronous operation. >> >>> >> >>> For example, if we have an application with a bunch of pre-existing >> >>> Elements that do not extend from any classes of mine, I'd like for the >> >>> all to have `foo` properties, so that I can do this: >> >>> >> >>> ```js >> >>> const el = new SomeCustomElementThatWasDefinedCreatedByMe >> >>> console.log(el.foo) // it exists and is specific to the instance, not >> >>> a prototype property >> >>> >> >>> // or >> >>> >> >>> const div = document.createElement('div') >> >>> console.log(div.foo) // it exists and is specific to the instance, not >> >>> a prototype property >> >>> ``` >> >>> >> >>> Can this be done? >> >>> /#!/JoePea >> >>> >> >>> >> >>> On Tue, Oct 24, 2017 at 10:19 AM, /#!/JoePea <[email protected]> wrote: >> >>> >> This feels like a problem similar to >> >>> >> https://esdiscuss.org/topic/block-scoped-prototype-extensions >> >>> > >> >>> > @Boris, even if it were scoped, how do we monkey patch a >> >>> > *constructor*? By the way, for some reason your link to >> >>> > `https://esdiscuss.org/topic/block-scoped-prototype-extensions` >> >>> > posted >> >>> > as `https://esdiscuss.org/topic/block` which is 404. If you can edit >> >>> > it it would help others not to stumble on a broken link. >> >>> > >> >>> >> if that would be possible, then everyone could just monkey patch >> >>> >> Object, right? >> >>> > >> >>> > But everyone can monkey patch the entire class already, aside from >> >>> > the >> >>> > constructor, by modifying the prototype. Obviously if someone >> >>> > returns >> >>> > something new from the constructor they might break everything, but >> >>> > it >> >>> > will be completely obvious and people then won't do that. The same >> >>> > applies with methods and properties, it is super easy to break >> >>> > entire >> >>> > applications monkey patching methods. >> >>> > >> >>> > --- >> >>> > >> >>> > So suppose I want to "polyfill" a concept. For example, I want all >> >>> > elements to have a new "foo" accessor after they've been >> >>> > constructed. >> >>> > Or for example, suppose `HTMLElement.prototype.style` and >> >>> > `SVGElement.prototype.style` didn't exist yet. How would I patch >> >>> > those >> >>> > in? >> >>> > /#!/JoePea >> >>> > >> >>> > >> >>> > On Tue, Oct 24, 2017 at 10:07 AM, Michał Wadas >> >>> > <[email protected]> >> >>> > wrote: >> >>> >> AFAIR DOM classes are not extensible by any means. >> >>> >> >> >>> >> >> >>> >> >> >>> >> On 24 Oct 2017 6:51 pm, "/#!/JoePea" <[email protected]> wrote: >> >>> >>> >> >>> >>> Is it possible to monkey-patch an intermediate constructor of a >> >>> >>> built-in >> >>> >>> subclass? >> >>> >>> >> >>> >>> For example, suppose I want all `Element` instances in a web app >> >>> >>> to >> >>> >>> have >> >>> >>> new instance properties, is there a way to monkey-patch the >> >>> >>> Element >> >>> >>> constructor so that when I make a custom element by extending a >> >>> >>> subclass of >> >>> >>> `Element` that the new logic will fire? >> >>> >>> >> >>> >>> For example: >> >>> >>> >> >>> >>> ```js >> >>> >>> // monkey-patch the Element constructor somehow so that it logs >> >>> >>> "patched >> >>> >>> in Element". >> >>> >>> >> >>> >>> // then >> >>> >>> class FooBar extends HTMLElement {} >> >>> >>> customElement.define('foo-bar', FooBar) >> >>> >>> new FooBar // "patched in Element" >> >>> >>> ``` >> >>> >>> >> >>> >>> I tried >> >>> >>> >> >>> >>> ```js >> >>> >>> const OldElement = window.Element >> >>> >>> >> >>> >>> window.Element = function Element() { >> >>> >>> const _this = new OldElement >> >>> >>> console.log("patched in Element") >> >>> >>> return _this >> >>> >>> } >> >>> >>> >> >>> >>> window.Element.prototype = OldElement.prototype >> >>> >>> window.Element.prototype.constructor = window.Element >> >>> >>> >> >>> >>> class FooBar extends HTMLElement {} >> >>> >>> customElements.define('f-b', FooBar) >> >>> >>> new FooBar // does not log "patched in Element" >> >>> >>> ``` >> >>> >>> >> >>> >>> But when I make a new custom element, constructing it seems to use >> >>> >>> the old >> >>> >>> Element constructor, as if a non-global reference to the original >> >>> >>> constructor is kept inside a module so that modifying the global >> >>> >>> wouldn't >> >>> >>> have any effect. >> >>> >>> >> >>> >>> Is there a way to monkey patch a constructor in the middle of a >> >>> >>> built-in >> >>> >>> prototype chain or to otherwise inject construction logic to base >> >>> >>> classes of >> >>> >>> existing class hierarchies? >> >>> >>> >> >>> >>> >> >>> >>> /#!/JoePea >> >>> >>> >> >>> >>> _______________________________________________ >> >>> >>> es-discuss mailing list >> >>> >>> [email protected] >> >>> >>> https://mail.mozilla.org/listinfo/es-discuss >> >>> >>> >> >>> >> >> >>> _______________________________________________ >> >>> es-discuss mailing list >> >>> [email protected] >> >>> https://mail.mozilla.org/listinfo/es-discuss >> >> >> >> >> >> >> >> _______________________________________________ >> >> es-discuss mailing list >> >> [email protected] >> >> https://mail.mozilla.org/listinfo/es-discuss >> >> >> > >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss > > _______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

