Skip to content

Commit

Permalink
chore: wip. Working proto
Browse files Browse the repository at this point in the history
  • Loading branch information
John Jenkins committed Dec 18, 2024
1 parent 8592315 commit 2e4f53e
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 19 deletions.
5 changes: 4 additions & 1 deletion src/runtime/client-hydrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ const clientHydrate = (
shadowRootNodes,
slottedNodes,
);
childVNode.$tag$ = 'slot';
childVNode.$name$ = slotName;
}
childVNode.$elm$['s-sn'] = slotName;
childVNode.$elm$.removeAttribute('s-sn');
Expand Down Expand Up @@ -388,7 +390,8 @@ const clientHydrate = (
childVNode.$tag$ = 'slot';

// Add the slot name
const slotName = (node['s-sn'] = childVNode.$name$ = childIdSplt[5] || '');
const slotName = (node['s-sn'] = childIdSplt[5] || '');
childVNode.$name$ = slotName || null;
// add the `<slot>` node to the VNode tree and prepare any slotted any child nodes
addSlot(
slotName,
Expand Down
10 changes: 7 additions & 3 deletions src/runtime/vdom/set-accessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ export const setAccessor = (
const classList = elm.classList;
const oldClasses = parseClassList(oldValue);
const newClasses = parseClassList(newValue);
// for `scoped: true` components, new nodes after initial hydration
// from SSR don't have the slotted class added. Let's add that now

if (elm['s-si'] && newClasses.indexOf(elm['s-si']) < 0) {
newClasses.push(elm['s-si']);
// for `scoped: true` components, new nodes after initial hydration
// from SSR don't have the slotted class added. Let's add that now
oldClasses.forEach((c) => {
if (c.startsWith(elm['s-si'])) newClasses.push(c);
});
elm['s-si'] = undefined;
}
classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
Expand Down
22 changes: 7 additions & 15 deletions src/runtime/vdom/vdom-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,19 +620,6 @@ export const isSameVnode = (leftVNode: d.VNode, rightVNode: d.VNode, isInitialRe
// need to have the same element tag, and same key to be the same
if (leftVNode.$tag$ === rightVNode.$tag$) {
if (BUILD.slotRelocation && leftVNode.$tag$ === 'slot') {
// We are not considering the same node if:
if (
// The component gets hydrated and no VDOM has been initialized.
// Here the comparison can't happen as $name$ property is not set for `leftNode`.
'$nodeId$' in leftVNode &&
isInitialRender &&
// `leftNode` is not from type HTMLComment which would cause many
// hydration comments to be removed
leftVNode.$elm$.nodeType !== 8
) {
return false;
}

return leftVNode.$name$ === rightVNode.$name$;
}
// this will be set if JSX tags in the build have `key` attrs set on them
Expand All @@ -643,6 +630,11 @@ export const isSameVnode = (leftVNode: d.VNode, rightVNode: d.VNode, isInitialRe
if (BUILD.vdomKey && !isInitialRender) {
return leftVNode.$key$ === rightVNode.$key$;
}
// if we're comparing the same node and it's the initial render,
// let's set the $key$ property to the rightVNode so we don't cause re-renders
if (isInitialRender && !leftVNode.$key$ && rightVNode.$key$) {
leftVNode.$key$ = rightVNode.$key$;
}
return true;
}
return false;
Expand Down Expand Up @@ -957,7 +949,7 @@ export const insertBefore = (parent: Node, newNode: Node, reference?: Node): Nod
const inserted = parent?.insertBefore(newNode, reference);

if (BUILD.scoped) {
updateElementScopeIds(newNode as d.RenderNode, parent as d.RenderNode);
// updateElementScopeIds(newNode as d.RenderNode, parent as d.RenderNode);
}

return inserted;
Expand Down Expand Up @@ -986,7 +978,7 @@ const findScopeIds = (element: d.RenderNode): string[] => {
* @param iterateChildNodes iterate child nodes
*/
const updateElementScopeIds = (element: d.RenderNode, parent: d.RenderNode, iterateChildNodes = false) => {
if (element && parent && element.nodeType === NODE_TYPE.ElementNode) {
if (element && parent && element.nodeType === NODE_TYPE.ElementNode && typeof element['s-sn'] === 'undefined') {
const scopeIds = new Set(findScopeIds(parent).filter(Boolean));
if (scopeIds.size) {
element.classList?.add(...(element['s-scs'] = Array.from(scopeIds)));
Expand Down
28 changes: 28 additions & 0 deletions test/end-to-end/src/scoped-hydration/colots.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Component, h } from '@stencil/core';

@Component({
tag: 'non-shadow-multi-slots',
scoped: true,
styles: `
:host * {
color: red;
}
::slotted(*) {
color: blue;
}
`,
})
export class NonShadowMultiSlots {
render() {
return (
<div class="wrap">
<div>Internal: BEFORE DEFAULT SLOT</div>
<slot />
<div>Internal: AFTER DEFAULT SLOT</div>
<div>Internal: BEFORE SECOND SLOT</div>
<slot name="second-slot">Second slot fallback text</slot>
<div>Internal: AFTER SECOND SLOT</div>
</div>
);
}
}

0 comments on commit 2e4f53e

Please sign in to comment.