Skip to content

Commit

Permalink
apply more changes from #5787
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-bromann committed Jun 4, 2024
1 parent 003164d commit 3793d00
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 14 deletions.
13 changes: 9 additions & 4 deletions src/runtime/bootstrap-custom-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ export const proxyCustomElement = (Cstr: any, compactMeta: d.ComponentRuntimeMet
},
__attachShadow() {
if (supportsShadow) {
/**
* Only attach shadow root if there isn't one already, e.g. when
* rendering a Declarative Shadow DOM.
*/
if (!this.shadowRoot) {
if (BUILD.shadowDelegatesFocus) {
this.attachShadow({
Expand All @@ -98,6 +94,15 @@ export const proxyCustomElement = (Cstr: any, compactMeta: d.ComponentRuntimeMet
} else {
this.attachShadow({ mode: 'open' });
}
} else {
// we want to check to make sure that the mode for the shadow
// root already attached to the element (i.e. created via DSD)
// is set to 'open' since that's the only mode we support
if (this.shadowRoot.mode !== 'open') {
throw new Error(
`Unable to re-use existing shadow root for ${cmpMeta.$tagName$}! Mode is set to ${this.shadowRoot.mode} but Stencil only supports open shadow roots.`,
);
}
}
} else {
(this as any).shadowRoot = this;
Expand Down
15 changes: 11 additions & 4 deletions src/runtime/bootstrap-lazy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,9 @@ export const bootstrapLazy = (lazyBundles: d.LazyBundlesRuntimeData, options: d.
// add the read-only property "shadowRoot" to the host element
// adding the shadow root build conditionals to minimize runtime
if (supportsShadow) {
/**
* Only attach shadow root if there isn't one already, e.g. when
* rendering a Declarative Shadow DOM.
*/
if (!self.shadowRoot) {
// we don't want to call `attachShadow` if there's already a shadow root
// attached to the
if (BUILD.shadowDelegatesFocus) {
self.attachShadow({
mode: 'open',
Expand All @@ -123,6 +121,15 @@ export const bootstrapLazy = (lazyBundles: d.LazyBundlesRuntimeData, options: d.
} else {
self.attachShadow({ mode: 'open' });
}
} else {
// we want to check to make sure that the mode for the shadow
// root already attached to the element (i.e. created via DSD)
// is set to 'open' since that's the only mode we support
if (self.shadowRoot.mode !== 'open') {
throw new Error(
`Unable to re-use existing shadow root for ${cmpMeta.$tagName$}! Mode is set to ${self.shadowRoot.mode} but Stencil only supports open shadow roots.`,
);
}
}
} else if (!BUILD.hydrateServerSide && !('shadowRoot' in self)) {
(self as any).shadowRoot = self;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/vdom/test/util.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toVNode } from '../util.js';
import { toVNode } from '../util';

describe('toVNode()', () => {
it('should create element w/ child elements and text nodes', () => {
Expand Down
11 changes: 6 additions & 5 deletions src/runtime/vdom/vdom-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,17 +653,18 @@ export const patch = (oldVNode: d.VNode, newVNode: d.VNode, isInitialRender = fa
const text = newVNode.$text$;
let defaultHolder: Comment;

if (BUILD.shadowDom && isInitialRender && oldVNode.$elm$.nodeType === NODE_TYPE.DocumentFragment) {
// TODO perhaps we should try to only do this when DSD has been used?
// although there may not be any harm in just doing it all the time.
//
// we need to create fake 'oldChildren' for any nodes that might be present
if (!BUILD.hydrateServerSide && BUILD.shadowDom && isInitialRender && oldVNode.$elm$.nodeType === NODE_TYPE.DocumentFragment) {
// We need to create fake 'oldChildren' for any nodes that might be present
// in the shadow root because of DSD. We want to do this when:
//
// 1. this is the first render
// 2. the `$elm$` for the current old vdom node is a document fragment,
// meaning the content node for a shadow root that was created by the
// browser based on a `<template>` tag in the HTML
//
// This will allow the component rendering lifecycle to boot up with vdom
// nodes for the DOM nodes already present in the shadow root, allowing the
// vdom to re-use these nodes (if they are suitable, of course).
for (const child of oldVNode.$elm$.children) {
// TODO be more fine-grained about this
// 1. can I tell whether the style tag was added client-side or not?
Expand Down

0 comments on commit 3793d00

Please sign in to comment.