webcomponents / polyfills

Web Components Polyfills
BSD 3-Clause "New" or "Revised" License
1.14k stars 165 forks source link

[scoped-custom-element-registry]: insertAdjacentHTML throws exception #444

Closed epithet closed 3 years ago

epithet commented 3 years ago

Exception is thrown here: https://github.com/webcomponents/polyfills/blob/041aff1a2408a5854c880e45dfad150556e51bcb/packages/scoped-custom-element-registry/src/scoped-custom-element-registry.js#L345

Reason: native insertAdjacentHTML returns undefined, but WeakMaps only support objects as keys:

Can be reproduced with the following example, which should spell out "success" (I can get the example to work by commenting out the line installScopedCreationMethod(Element, 'insertAdjacentHTML');):

<span>u</span><span id="host"></span>
<script>
    class MyWidgetGlobal extends HTMLElement {
        constructor() {
            super()
            this.attachShadow({ mode: 'open' })
            this.shadowRoot.innerHTML = '<span>s</span>'
        }
    }
    class MyWidgetScoped extends HTMLElement {
        constructor() {
            super()
            this.attachShadow({ mode: 'open' })
            this.shadowRoot.innerHTML = '<span>c</span>'
        }
    }
    window.customElements.define('my-widget', MyWidgetGlobal)
    try {
        const span = document.querySelector('span')
        span.insertAdjacentHTML('beforebegin', '<my-widget></my-widget>')
        // next line won't execute
        span.insertAdjacentText('afterend', 'c')
    } catch (ex) {
        console.log(ex)
    }
    const scope = new CustomElementRegistry()
    scope.define('my-widget', MyWidgetScoped)
    const host = document.querySelector('#host')
    const shadowRoot = host.attachShadow({ mode: 'open', customElements: scope })
    shadowRoot.innerHTML = '<span>es</span>'
    try {
        const span = shadowRoot.querySelector('span')
        span.insertAdjacentHTML('beforebegin', '<my-widget></my-widget>')
        // next line won't execute
        span.insertAdjacentText('afterend', 's')
    } catch (ex) {
        console.log(ex)
    }
</script>
RS-Sautter commented 3 years ago

@justinfagnani