Skip to content

Commit

Permalink
fix: rendering slots with non-literal names (#5003)
Browse files Browse the repository at this point in the history
* fix: rendering slot when name is not a literal

* fix: remove expected failure

* fix: missing fixture exclusion
  • Loading branch information
jhefferman-sfdc authored Dec 10, 2024
1 parent ee2edae commit d10cdb0
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const expectedFailures = new Set([
'render-dynamic-value/index.js',
'scoped-slots/advanced/index.js',
'scoped-slots/default-slot/index.js',
'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/slots/mixed/index.js',
Expand Down
13 changes: 13 additions & 0 deletions packages/@lwc/ssr-compiler/src/compile-template/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import type {
Property as EsProperty,
Statement as EsStatement,
} from 'estree';
import type {
ComplexExpression as IrComplexExpression,
Expression as IrExpression,
Literal as IrLiteral,
} from '@lwc/template-compiler';

export function optimizeAdjacentYieldStmts(statements: EsStatement[]): EsStatement[] {
let prevStmt: EsStatement | null = null;
Expand Down Expand Up @@ -172,3 +177,11 @@ export function getChildAttrsOrProps(

return b.objectExpression(objectAttrsOrProps);
}

/**
* Determine if the provided node is of type Literal
* @param node
*/
export function isLiteral(node: IrLiteral | IrExpression | IrComplexExpression): node is IrLiteral {
return node.type === 'Literal';
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { builders as b, is } from 'estree-toolkit';
import { bAttributeValue, optimizeAdjacentYieldStmts } from '../../shared';
import { esTemplate, esTemplateWithYield } from '../../../estemplate';
import { irChildrenToEs, irToEs } from '../../ir-to-es';
import { isLiteral } from '../../shared';
import { expressionIrToEs } from '../../expression';
import { isNullableOf } from '../../../estree/validators';
import type { CallExpression as EsCallExpression, Expression as EsExpression } from 'estree';

Expand Down Expand Up @@ -186,13 +188,14 @@ export function getSlottedContent(
const boundVariableName = child.slotData.value.name;
const boundVariable = b.identifier(boundVariableName);
cxt.pushLocalVars([boundVariableName]);

const slotName = isLiteral(child.slotName)
? b.literal(child.slotName.value)
: expressionIrToEs(child.slotName, cxt);

// TODO [#4768]: what if the bound variable is `generateMarkup` or some framework-specific identifier?
const addLightContentExpr = b.expressionStatement(
bAddLightContent(
child.slotName as EsExpression,
boundVariable,
irChildrenToEs(child.children, cxt)
)
bAddLightContent(slotName, boundVariable, irChildrenToEs(child.children, cxt))
);
cxt.popLocalVars();
return addLightContentExpr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,21 @@
import { builders as b, is } from 'estree-toolkit';
import { esTemplateWithYield } from '../../estemplate';
import { expressionIrToEs } from '../expression';
import { isLiteral } from '../shared';

import { bYieldTextContent, isLastConcatenatedNode } from '../adjacent-text-nodes';
import type {
Statement as EsStatement,
ExpressionStatement as EsExpressionStatement,
} from 'estree';
import type {
ComplexExpression as IrComplexExpression,
Expression as IrExpression,
Literal as IrLiteral,
Text as IrText,
} from '@lwc/template-compiler';
import type { Text as IrText } from '@lwc/template-compiler';
import type { Transformer } from '../types';

const bBufferTextContent = esTemplateWithYield`
didBufferTextContent = true;
textContentBuffer += massageTextContent(${/* string value */ is.expression});
`<EsExpressionStatement[]>;

function isLiteral(node: IrLiteral | IrExpression | IrComplexExpression): node is IrLiteral {
return node.type === 'Literal';
}

export const Text: Transformer<IrText> = function Text(node, cxt): EsStatement[] {
cxt.import(['htmlEscape', 'massageTextContent']);

Expand Down

0 comments on commit d10cdb0

Please sign in to comment.