Skip to content

fix(runtime): re-attach removed style elements#6646

Open
saudademjj wants to merge 1 commit intostenciljs:mainfrom
saudademjj:saudademjj/fix-style-reinsertion-6637
Open

fix(runtime): re-attach removed style elements#6646
saudademjj wants to merge 1 commit intostenciljs:mainfrom
saudademjj:saudademjj/fix-style-reinsertion-6637

Conversation

@saudademjj
Copy link

@saudademjj saudademjj commented Mar 19, 2026

Summary

  • re-attach removed head style elements on later renders
  • re-attach removed shared shadow-root style containers without merging into unrelated <style> tags
  • preserve slot-fb CSS and constructable stylesheet window selection
  • avoid redundant style rewrites for later component instances

Testing

  • npm run ts scripts/index.ts -- --prod --ci
  • npm run test.jest -- src/runtime/test/style.spec.tsx src/runtime/test/styles.spec.ts src/runtime/test/shadow.spec.tsx src/runtime/test/hydrate-style-element.spec.tsx src/runtime/test/hydrate-scoped.spec.tsx src/runtime/test/hydrate-shadow.spec.tsx src/runtime/test/hydrate-shadow-child.spec.tsx src/runtime/test/hydrate-shadow-parent.spec.tsx src/runtime/test/hydrate-shadow-in-shadow.spec.tsx src/runtime/test/hydrate-slot-fallback.spec.tsx src/runtime/test/hydrate-slotted-content-order.spec.tsx --runInBand

Closes #6637

@saudademjj saudademjj requested a review from a team as a code owner March 19, 2026 11:07
Copilot AI review requested due to automatic review settings March 19, 2026 11:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses runtime style loss when a third-party framework removes Stencil-managed <style> tags from the DOM, by tracking the concrete style element per scope and re-attaching styles on subsequent renders. It also adds a regression test to ensure removed styles are re-inserted.

Changes:

  • Track the actual <style> element used per scopeId to detect stale cache entries when style nodes are manually removed.
  • Clear the new tracked style-element cache on disconnect alongside the existing applied-style cache.
  • Add a runtime regression test that removes a component’s style tag and verifies it is re-attached on the next render.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/runtime/styles.ts Adds tracking of per-scope style elements and re-attachment logic when cached styles are removed from the DOM.
src/runtime/disconnected-callback.ts Clears the new per-scope style-element tracking cache on disconnect.
src/runtime/test/style.spec.tsx Adds a regression test ensuring removed styles are re-attached on subsequent renders.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from d06da48 to 8b89e1f Compare March 19, 2026 11:22
Copilot AI review requested due to automatic review settings March 19, 2026 14:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Copilot AI review requested due to automatic review settings March 19, 2026 16:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Copilot AI review requested due to automatic review settings March 19, 2026 17:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a runtime issue where component styles can disappear if a third-party framework removes Stencil-injected <style> elements from the DOM, by tracking the actual style elements per scope and allowing styles to be re-attached on subsequent renders.

Changes:

  • Track the concrete <style> element associated with each applied scope to detect stale cache entries after DOM removal.
  • Clear the new style-element tracking cache alongside the existing applied-style cache during disconnect.
  • Add runtime regression tests covering re-attaching removed styles and preserving slot-fallback CSS in shared shadow-root style containers.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/runtime/styles.ts Adds style-element tracking per scopeId, staleness detection, and consolidates slot-fallback CSS concatenation logic.
src/runtime/disconnected-callback.ts Clears the new style-element WeakMap caches on disconnect (mirroring existing applied-style cleanup).
src/runtime/test/style.spec.tsx Adds regression tests for re-attaching removed head styles and for shared shadow-root style container behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a runtime edge case where Stencil-managed <style> elements can be manually removed from the DOM (e.g. by third-party frameworks) and then fail to reappear, by tracking the concrete style element used per scope so stale cache entries can be detected and corrected.

Changes:

  • Track the concrete <style> element per applied scope to detect when it has been removed from its container and re-attach/recreate it as needed.
  • Clear the new style-element tracking cache alongside the existing applied-style cache during disconnectedCallback.
  • Add regression tests covering re-attachment in document.head and shared shadow-root style containers (including slot fallback CSS).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/runtime/styles.ts Adds per-scope style element tracking and re-attachment logic in addStyle.
src/runtime/disconnected-callback.ts Clears the new rootAppliedStyleElms cache on disconnect (element + shadowRoot).
src/runtime/test/style.spec.tsx Adds regression tests for re-attaching removed style elements in head and shadow roots.
src/declarations/stencil-private.ts Updates runtime typings to allow ShadowRoot as a style container key.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a runtime styling regression where component-generated <style> tags can be removed from the DOM by external frameworks (e.g., SvelteKit head management) and were not re-inserted on subsequent renders. It does so by tracking the actual style element instance used per scope and validating that the tracked element is still attached to the expected container.

Changes:

  • Track concrete <style> elements per applied scope (including shared shadow-root style containers) and re-attach or invalidate stale entries if the DOM node is removed.
  • Clear the new tracked-style-element cache alongside existing applied-style caches on disconnect.
  • Add regression tests covering removed head <style> tags and removed shared shadow-root style containers, plus tests for constructable stylesheet window selection.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/runtime/styles.ts Adds per-container tracking of applied style elements, stale-entry detection, re-attachment behavior, and a helper for shadow-root constructable stylesheets.
src/runtime/disconnected-callback.ts Clears the new rootAppliedStyleElms cache on host/shadow-root disconnect to match existing cache cleanup patterns.
src/runtime/test/style.spec.tsx Adds runtime regression tests ensuring removed style tags/containers are re-attached on subsequent renders.
src/runtime/test/styles.spec.ts Adds unit tests for createShadowRootConstructableStylesheet to ensure the correct window is used (or safely falls back).
src/declarations/stencil-private.ts Expands the applied-style container typing to include ShadowRoot to reflect runtime usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a runtime robustness issue where component <style> tags can be removed from the DOM by external frameworks (e.g. SvelteKit head management) and not get re-inserted, causing styles to disappear until a full reload.

Changes:

  • Track the concrete HTMLStyleElement used per scopeId so stale cache entries can be detected and styles can be re-attached when removed from the DOM.
  • Clear the new tracked style-element cache on disconnect alongside the existing applied-style cache.
  • Add regression tests covering removed style re-attachment and shared shadow-root style-container behavior (including slot fallback styles).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/runtime/styles.ts Tracks applied style elements per root container; reattaches removed styles; refactors constructable stylesheet creation.
src/runtime/disconnected-callback.ts Clears the new rootAppliedStyleElms cache on host/shadowRoot disconnect.
src/runtime/test/style.spec.tsx Adds runtime regression tests for reattaching removed styles and shared shadow-root style containers.
src/runtime/test/styles.spec.ts Adds unit tests for createShadowRootConstructableStylesheet window selection/fallback behavior.
src/declarations/stencil-private.ts Updates runtime typing for the applied-style root/container map.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 20, 2026 12:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from 0ba7eab to 6bf65f4 Compare March 20, 2026 12:27
Copilot AI review requested due to automatic review settings March 20, 2026 12:37
@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from 6bf65f4 to 6931d06 Compare March 20, 2026 12:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from 6931d06 to f4ff1de Compare March 20, 2026 12:50
Copilot AI review requested due to automatic review settings March 20, 2026 13:09
@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from f4ff1de to 570c646 Compare March 20, 2026 13:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from 570c646 to 898fbfc Compare March 20, 2026 13:21
stenciljs#6637)

Track style elements in rootAppliedStyles Map and verify DOM presence
before skipping re-injection. Frameworks like SvelteKit may remove
Stencil-injected <style> elements from <head> during hydration.

- Change RootAppliedStyleMap from Set<string> to Map<string, HTMLStyleElement | null>
- Verify tracked element parentNode before treating style as applied
- null value indicates constructable stylesheet (cannot be externally removed)
- Add regression test for style re-attachment after removal
Copilot AI review requested due to automatic review settings March 20, 2026 13:26
@saudademjj saudademjj force-pushed the saudademjj/fix-style-reinsertion-6637 branch from 898fbfc to f4af543 Compare March 20, 2026 13:26
@saudademjj
Copy link
Author

Force-pushed a rewrite that strips this down to the minimum needed for #66373 files, +63/−15 (previously +528/−53).

What changed

rootAppliedStyles now stores Map<string, HTMLStyleElement | null> instead of Set<string>. Before skipping style injection, we verify the tracked <style> element is still in the DOM:

  • HTMLStyleElement — check parentNode === styleContainerNode. If the element was removed (e.g. by SvelteKit during hydration), clear the entry and re-inject.
  • null — constructable stylesheet via adoptedStyleSheets. These can't be stripped by external DOM manipulation, so we always skip.

This keeps the hot path fast (one Map lookup + one property check) while catching the exact scenario described in #6637.

Other details

  • Scoped-in-shadow-root components that use constructable stylesheets are tracked as null, matching the behavior of the main constructable CSS branch.
  • HMR is preserved — when BUILD.hotModuleReplacement is true and the tracked element is still present but its textContent differs from the registered style, we update it in place before returning.
  • SLOT_FB_CSS behavior is unchanged from main. Whether slot fallback styles should be added to shadow roots is a separate question (happy to open an issue if needed).

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

bug: Styles not rendered, gone from the DOM due to 3rd party framework interference (svelte/sveltekit)

3 participants