Skip to content

Commit

Permalink
fix(runtime): hydrate shadow dom first (#5911)
Browse files Browse the repository at this point in the history
* fix(runtime): hydrate shadow dom first

* prettier

* hydrate shadow first

* remove any

* don't remove vnodes that are about to be hydrated

* prettier
  • Loading branch information
christian-bromann authored Aug 1, 2024
1 parent 5dd4f7f commit ccf1a89
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
36 changes: 18 additions & 18 deletions src/runtime/client-hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,6 @@ const clientHydrate = (
}
}

// recursively drill down, end to start so we can remove nodes
for (i = node.childNodes.length - 1; i >= 0; i--) {
clientHydrate(
parentVNode,
childRenderNodes,
slotNodes,
shadowRootNodes,
hostElm,
node.childNodes[i] as any,
hostId,
);
}

if (node.shadowRoot) {
// keep drilling down through the shadow root nodes
for (i = node.shadowRoot.childNodes.length - 1; i >= 0; i--) {
Expand All @@ -181,6 +168,19 @@ const clientHydrate = (
);
}
}

// recursively drill down, end to start so we can remove nodes
for (i = node.childNodes.length - 1; i >= 0; i--) {
clientHydrate(
parentVNode,
childRenderNodes,
slotNodes,
shadowRootNodes,
hostElm,
node.childNodes[i] as any,
hostId,
);
}
} else if (node.nodeType === NODE_TYPE.CommentNode) {
// `${COMMENT_TYPE}.${hostId}.${nodeId}.${depth}.${index}`
childIdSplt = node.nodeValue.split('.');
Expand Down Expand Up @@ -293,14 +293,14 @@ const clientHydrate = (
export const initializeDocumentHydrate = (node: d.RenderNode, orgLocNodes: d.PlatformRuntime['$orgLocNodes$']) => {
if (node.nodeType === NODE_TYPE.ElementNode) {
let i = 0;
for (; i < node.childNodes.length; i++) {
initializeDocumentHydrate(node.childNodes[i] as any, orgLocNodes);
}
if (node.shadowRoot) {
for (i = 0; i < node.shadowRoot.childNodes.length; i++) {
initializeDocumentHydrate(node.shadowRoot.childNodes[i] as any, orgLocNodes);
for (; i < node.shadowRoot.childNodes.length; i++) {
initializeDocumentHydrate(node.shadowRoot.childNodes[i] as d.RenderNode, orgLocNodes);
}
}
for (i = 0; i < node.childNodes.length; i++) {
initializeDocumentHydrate(node.childNodes[i] as d.RenderNode, orgLocNodes);
}
} else if (node.nodeType === NODE_TYPE.CommentNode) {
const childIdSplt = node.nodeValue.split('.');
if (childIdSplt[0] === ORG_LOCATION_ID) {
Expand Down
7 changes: 6 additions & 1 deletion src/runtime/vdom/vdom-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,12 @@ export const patch = (oldVNode: d.VNode, newVNode: d.VNode, isInitialRender = fa
}
// add the new vnode children
addVnodes(elm, null, newVNode, newChildren, 0, newChildren.length - 1);
} else if (BUILD.updatable && oldChildren !== null) {
} else if (
// don't do this on initial render as it can cause non-hydrated content to be removed
!isInitialRender &&
BUILD.updatable &&
oldChildren !== null
) {
// no new child vnodes, but there are old child vnodes to remove
removeVnodes(oldChildren, 0, oldChildren.length - 1);
}
Expand Down
6 changes: 5 additions & 1 deletion test/end-to-end/src/declarative-shadow-dom/test.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ describe('renderToString', () => {
`,
{
serializeShadowRoot: true,
fullDocument: false,
fullDocument: true,
},
);

Expand Down Expand Up @@ -255,6 +255,10 @@ describe('renderToString', () => {
expect(html).toContain(
`<car-detail custom-hydrate-flag=\"\" c-id=\"2.4.2.0\" s-id=\"4\"><!--r.4--><section c-id=\"4.0.0.0\"><!--t.4.1.1.0-->2023 VW Beetle</section></car-detail>`,
);

const page = await newE2EPage({ html, url: 'https://stencil.com' });
const cars = await page.findAll('>>>car-detail');
expect(cars.map((car) => car.textContent)).toEqual(['2024 VW Vento', '2023 VW Beetle']);
});

it('calls beforeHydrate and afterHydrate function hooks', async () => {
Expand Down

0 comments on commit ccf1a89

Please sign in to comment.