Skip to content

Commit

Permalink
fix(ssr): extra bookends for light dom forwarded slots @W-17363666 (#…
Browse files Browse the repository at this point in the history
…5005)

* fix(ssr): extra bookends for light dom forwarded slots

* fix(ssr): extra bookens for scoped slots

* fix(ssr): extra bookends for if directive

* chore: revert unneeded change

* test(ssr): slotted-content-nested

* fix(ssr): extra bookends in nested slotted content

* Update packages/@lwc/engine-server/src/__tests__/fixtures/slotted-content-nested/modules/x/slots/slots.js

Co-authored-by: Nolan Lawson <[email protected]>

* Update packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts

Co-authored-by: Nolan Lawson <[email protected]>

* Update packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts

Co-authored-by: Nolan Lawson <[email protected]>

* test(ssr): expect failure slot-not-at-top-level/advanced/lwcIf/shadow/index.js

---------

Co-authored-by: Nolan Lawson <[email protected]>
  • Loading branch information
cardoso and nolanlawson authored Dec 10, 2024
1 parent 3d28140 commit b8362b5
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 16 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<x-slots>
<template shadowrootmode="open">
<x-receiver>
<template shadowrootmode="open">
<slot>
</slot>
</template>
<x-another>
<template shadowrootmode="open">
<slot>
</slot>
</template>
<div>
hello
</div>
</x-another>
<div>
world
</div>
</x-receiver>
</template>
</x-slots>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const tagName = 'x-slots';
export { default } from 'x/slots';
export * from 'x/slots';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<slot></slot>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { LightningElement } from 'lwc';
export default class extends LightningElement {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<slot></slot>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { LightningElement } from 'lwc';
export default class extends LightningElement {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<x-receiver>
<x-another>
<template lwc:if={isTrue}>
<div>hello</div>
</template>
</x-another>
<template lwc:if={isTrue}>
<div>world</div>
</template>
</x-receiver>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { LightningElement } from 'lwc';
export default class extends LightningElement {
isTrue = true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@ export const expectedFailures = new Set([
'scoped-slots/expression/index.js',
'scoped-slots/mixed-with-light-dom-slots-inside/index.js',
'scoped-slots/mixed-with-light-dom-slots-outside/index.js',
'slot-forwarding/scoped-slots/index.js',
'slot-forwarding/slots/mixed/index.js',
'slot-forwarding/slots/dangling/index.js',
'slot-forwarding/slots/light/index.js',
'slot-not-at-top-level/advanced/lwcIf/light/index.js',
'slot-not-at-top-level/advanced/lwcIf/shadow/index.js',
'slot-not-at-top-level/lwcIf/light/index.js',
'slot-not-at-top-level/lwcIf/shadow/index.js',
'superclass/render-in-superclass/no-template-in-subclass/index.js',
'superclass/render-in-superclass/unused-default-in-subclass/index.js',
'superclass/render-in-superclass/unused-default-in-superclass/index.js',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ export function getSlottedContent(
node: IrLwcComponent | IrComponent,
cxt: TransformerContext
): EsStatement[] {
const { isSlotted } = cxt;

cxt.isSlotted = true;

// Anything inside the slotted content is a normal slotted content except for `<template lwc:slot-data>` which is a scoped slot.
const slottableChildren = node.children.filter((child) => child.type !== 'ScopedSlotFragment');
const scopedSlottableChildren = node.children.filter(
Expand Down Expand Up @@ -199,6 +203,8 @@ export function getSlottedContent(
lightSlotContent.length > 0 || scopedSlotContent.length > 0
);

cxt.isSlotted = isSlotted;

return bGenerateSlottedContent(
hasShadowSlottedContent,
shadowSlotContent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function bIfStatement(

return b.ifStatement(
expressionIrToEs(condition, cxt),
bBlockStatement(children, cxt, true),
bBlockStatement(children, cxt, !cxt.isSlotted),
elseBlock
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ import type { Transformer } from '../types';
const bConditionalSlot = esTemplateWithYield`
if (isLightDom) {
const isScopedSlot = ${/* isScopedSlot */ is.literal};
const isSlotted = ${/* isSlotted */ is.literal};
// start bookend HTML comment for light DOM slot vfragment
yield '<!---->';
// scoped slot factory has its own vfragment hence its own bookend
if (isScopedSlot) {
if (!isSlotted) {
yield '<!---->';
// scoped slot factory has its own vfragment hence its own bookend
if (isScopedSlot) {
yield '<!---->';
}
}
const generators = lightSlottedContent?.[${/* slotName */ is.expression} ?? ""];
Expand All @@ -45,14 +48,16 @@ const bConditionalSlot = esTemplateWithYield`
// TODO: default/fallback slot content
${/* slot fallback content */ is.statement}
}
// scoped slot factory has its own vfragment hence its own bookend
if (isScopedSlot) {
yield '<!---->';
}
// end bookend HTML comment for light DOM slot vfragment
yield '<!---->';
if (!isSlotted) {
yield '<!---->';
// scoped slot factory has its own vfragment hence its own bookend
if (isScopedSlot) {
yield '<!---->';
}
}
} else {
${/* slot element AST */ is.statement}
}
Expand All @@ -68,5 +73,6 @@ export const Slot: Transformer<IrSlot> = function Slot(node, ctx): EsStatement[]
const slotAst = Element(node, ctx);
const slotChildren = irChildrenToEs(node.children, ctx);
const isScopedSlot = b.literal(Boolean(slotBound));
return [bConditionalSlot(isScopedSlot, slotName, slotBound, slotChildren, slotAst)];
const isSlotted = b.literal(Boolean(ctx.isSlotted));
return [bConditionalSlot(isScopedSlot, isSlotted, slotName, slotBound, slotChildren, slotAst)];
};
1 change: 1 addition & 0 deletions packages/@lwc/ssr-compiler/src/compile-template/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface TransformerContext {
templateOptions: TemplateOpts;
prevSibling?: IrNode;
nextSibling?: IrNode;
isSlotted?: boolean;
import: (
imports: string | string[] | Record<string, string | undefined>,
source?: string
Expand Down

0 comments on commit b8362b5

Please sign in to comment.