Skip to content

Cloning a template's content into another template's shadow tree doesn't update its custom element registry #12213

@AtkinsSJ

Description

@AtkinsSJ

What is the issue with the HTML Standard?

This is closely related to #12209, but distinct.

I was investigating a Ladybird regression in https://wpt.live/css/css-shadow/part/inner-host.html with my scoped-custom-element-registries patches and I think this might be a spec issue.

Specifically, there's no blue text from the inner custom element, because <custom-element-inner> doesn't get a shadow tree.
Image

For easier reference, here's the relevant HTML:

<script>installCustomElement("custom-element-inner", "custom-element-inner-template");</script>
<template id="custom-element-inner-template">
  <style>span { color: blue; }</style>
  <span id="blue_part" part="partp">This text</span>
</template>
<script>installCustomElement("custom-element-outer", "custom-element-outer-template");</script>
<template id="custom-element-outer-template">
  <style>span { color: red; }</style>
  <span id="green_part" part="partp">This text</span>
  The following text should be blue:
  <custom-element-inner id="c-e-inner"></custom-element-inner>
</template>
The following text should be green:
<custom-element-outer id="c-e-outer"></custom-element-outer>

and JS:

function installCustomElement(element_name, template_id) {
  ceClass = class extends HTMLElement {
    constructor() {
      super();
      var template = document
        .getElementById(template_id)
        .content;
      this
        .attachShadow({mode: 'open'})
        .appendChild(template.cloneNode(true));
    }
  };
  window.customElements.define(element_name, ceClass);
}

I am not 100% sure on this, but I believe the issue is, when constructing the <custom-element-outer> element:

  1. The template contents document-fragment uses the appropriate template contents owner document which has a null custom element registry.
  2. Therefore the <custom-element-inner> element also gets a null custom element registry.
  3. adopt node step 3.1.3.2 doesn't replace null custom element registries, so it stays null.
  4. So the <custom-element-inner> element never gets upgraded, because it can't find a definition if it has no registry.

I think the fix will probably be to copy what 3.1.2 does, and also check for a null registry for elements. However, we don't want to always replace a null registry, and there's no "keep null registries" flag on element.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: custom elementsRelates to custom elements (as defined in DOM and HTML)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions