Skip to content

[BUGFIX] Shadow DOM support — {{#in-element}} with ShadowRoot/DocumentFragment and declarative shadow DOM via compiler#21217

Open
Copilot wants to merge 15 commits intomainfrom
copilot/quest-proper-shadowdom-support
Open

[BUGFIX] Shadow DOM support — {{#in-element}} with ShadowRoot/DocumentFragment and declarative shadow DOM via compiler#21217
Copilot wants to merge 15 commits intomainfrom
copilot/quest-proper-shadowdom-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 12, 2026

  • Fix Prettier formatting issue in shadow-dom.ts
  • Remove unnecessary attachShadow guards from ShadowDOMSuite tests
  • Add in-element-shadow-root.ts / in-element-document-fragment.ts test suites
  • Improve element-builder.ts comment explaining the extra pop for shadow roots
  • Fix querySelector('template') assertions in shadow-dom.ts
  • Remove double cast in dom.ts
  • Remove dead @tracked count = 0 from Counter class in shadow-dom.ts test 5
  • Add true → false → true round-trip test that directly exercises the existingShadowRoot.replaceChildren() path in VM_ATTACH_SHADOW_ROOT_OP
  • Add test for shadow root re-render driven by a component-owned @tracked property (no data passed to render()/rerender())
  • Add re-render isolation test: two sibling components each with internal @tracked state rendered into the same shadow root; uses assert.step/assert.verifySteps to prove only the component whose state changed re-renders
Original prompt

This section details on the original issue you should resolve

<issue_title>[Quest]: Proper ShadowDOM support</issue_title>
<issue_description>Goal:

  • support rending in to a shadow-dom
  • be able to render in to a shadow-dom in a single render pass (the current way to get around limitations in ember/glimmer to render in to a shadow requires an extra render pass as well as an extra couple elements)

Potentially make this work:

const Shadowed = 
  <template shadowmoderoot="open">

  </template>;

export default
  <template>
    <Shadowed>
      
    </Shadowed>
  </template>;

or, we update our content-tag parser to allow:

export default
  <template>
    <template shadowmoderoot="open">
      shadow dom!
    </template>
  </template>;

// representation:
template(`
   <template shadowmoderoot="open">
      shadow dom!
   </template>
`)

Currently, <template shadowrootmode="open"> is not allowed in template-tag:

GlimmerVM doesn't render directly in to a shadow:

Related

Regressions?

<agent_instructions>Explore ways to address some of the ergonomics issues presented in this issue</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Copilot AI changed the title [WIP] [Quest] Add proper ShadowDOM support for rendering feat: Shadow DOM support — fix {{#in-element}} with ShadowRoot/DocumentFragment and enable declarative shadow DOM Mar 12, 2026
@NullVoxPopuli

This comment was marked as resolved.

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>

This comment was marked as resolved.

@NullVoxPopuli NullVoxPopuli changed the title feat: Shadow DOM support — fix {{#in-element}} with ShadowRoot/DocumentFragment and enable declarative shadow DOM [BUGFIX] Shadow DOM support — {{#in-element}} with ShadowRoot/DocumentFragment and enable declarative shadow DOM Mar 14, 2026
…add new tests

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
…d document fragment suite

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>

This comment was marked as resolved.

@NullVoxPopuli

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these tests are all good

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are good

@NullVoxPopuli

This comment was marked as resolved.

…uous test assertions

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/72b301d3-7084-474d-8483-18367cfc2fe6
Copilot AI and others added 2 commits March 26, 2026 12:26
…uite (jitSuite is browser-only)

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/b893cd15-386a-4913-8907-af52f66f8772
…for existingShadowRoot path

Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/423b5a29-b3fe-40d7-b47f-bf00050510c5

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>

@test
'<template shadowrootmode="open"> as component root with tracked state re-renders into same shadow root'() {
class Counter extends GlimmerishComponent {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot since this test is changing state via rerender, we'll need another test that actually uses a tracked count + button that increments the property. no data should be passed in to render/rerender

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in afb21ff. Added '<template shadowrootmode="open"> as component root re-renders via internal @tracked property (no rerender args)' — the Counter class owns @tracked count = 0, the template uses {{this.count}}, nothing is passed to render() or rerender(). The test captures the instance, mutates instance.captured.count = 1, calls this.rerender() with no args, and asserts both the updated content and that the same shadow root instance is reused.

…ng assert.step

Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/3810a6db-ae5e-4396-9f63-baf5a7164f82

Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
@NullVoxPopuli
Copy link
Copy Markdown
Contributor

I extracted fragment support to here: #21253

because I want this PR more focused and easier to review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Quest]: Proper ShadowDOM support

3 participants