webcomponents / polyfills

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

[scoped-custom-element-registry] Elements can lose registry when removed from DOM #569

Open sorvell opened 11 months ago

sorvell commented 11 months ago

Description

If a nested element is removed from a shadowRoot using a registry and then innerHTML is called on it with html containing a scoped element, the element will not customize.

Example

Playground example

Expected behavior

Both elements in the example should customize.

Actual behavior

The 2nd scoped element fails to customize.

sorvell commented 11 months ago

Here are 3 possible ways to fix this issue:

  1. When trees of elements are created inside scoped roots (via innerHTML, insertAdjacentHtml, importNode, and maybe cloneNode?), stamp the entire subtree of elements with the creating registry. Currently only the top-most element is stamped.

    Preferred This will be a small perf hit but is robust and simple.

  2. Patch all DOM modification APIs to "pass along" the registry before mutating the DOM. This would involve patching a lot of the API surface area, e.g. all append's, all replaceWith..., all remove/removeChild, all setters textContent, innerHTML, innerText, outerText.

    Issues There's a lot to maintain and get right here and a large amount of code to add.

  3. Use a MutationObserver to detect DOM changes. This seems straightforward, but it would need to observe disconnected nodes as well, and likely would want to un-observe them when re-connection.

    Issues This is also a lot to get just right, validate, and maintain.