3

For functions on prototypes I used to do something like:

var attachShadow = HTMLElement.prototype.attachShadow
HTMLElement.prototype.attachShadow = function (option) {
    var sh = attachShadow.call(this, option)
    console.log('ShadowDOM Attached!')
    return sh
}

On this example, I modified the attachShadow method inside the HTMLElement prototype to get me notified when a new shadowDOM get attached to an element.

Now I wanna do something similar with ShadowRoot.prototype.adoptedStyleSheets, but this time adoptedStyleSheets is a getter/setter, var adoptedStyleSheets = HTMLElement.prototype.adoptedStyleSheets will cause an error: Uncaught TypeError: Illegal invocation.

I'm not sure what to do, How to modify getters/setters on prototypes?

iMrDJAi
  • 33
  • 3

1 Answers1

2

You don't want to retrieve the value inside adoptedStyleSheets (which obviously throws an error when called from the prototype) but its property descriptor in order to reuse it in your own adoptedStyleSheets:

(function () {
    const oldAdoptedStyleSheetsGetter = Object.getOwnPropertyDescriptor(ShadowRoot.prototype, 'adoptedStyleSheets');

    Object.defineProperty(ShadowRoot.prototype, "adoptedStyleSheets", {
        get: function () {
            console.log('adoptedStyleSheets was accessed!');
            return oldAdoptedStyleSheetsGetter.get.call(this)
        },
    });
})();

customElements.define('web-component', class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.innerHTML = `Hi I'm a web component`;
    console.log('this.shadowRoot.adoptedStyleSheets:', this.shadowRoot.adoptedStyleSheets);
  }
});
<web-component></web-component>
Guerric P
  • 20,579
  • 2
  • 28
  • 66