Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ssr): reduce duplicated text rendering logic #4991

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { esTemplateWithYield } from '../../estemplate';
import { expressionIrToEs } from '../expression';

import { bYieldTextContent, isLastConcatenatedNode } from '../adjacent-text-nodes';
import type { Statement as EsStatement } from 'estree';
import type {
Statement as EsStatement,
ExpressionStatement as EsExpressionStatement,
} from 'estree';
import type {
ComplexExpression as IrComplexExpression,
Expression as IrExpression,
Expand All @@ -21,20 +24,15 @@ import type { Transformer } from '../types';

const bBufferTextContent = esTemplateWithYield`
didBufferTextContent = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Could we make the buffer state part of the context object that we pass around? Might help address this repetition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't be fully at compile time, because directives like lwc:if are unknown until runtime. But maybe it could mitigate it?

{
const value = ${/* string value */ is.expression};
// Using non strict equality to align with original implementation (ex. undefined == null)
// See: https://github.com/salesforce/lwc/blob/348130f/packages/%40lwc/engine-core/src/framework/api.ts#L548
textContentBuffer += value == null ? '' : String(value);
}
`<EsStatement[]>;
textContentBuffer += renderTextContent(${/* 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');
cxt.import(['htmlEscape', 'renderTextContent']);

const isLastInSeries = isLastConcatenatedNode(cxt);

Expand Down
1 change: 1 addition & 0 deletions packages/@lwc/ssr-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export {
// renderComponent is an alias for serverSideRenderComponent
serverSideRenderComponent as renderComponent,
} from './render';
export { renderTextContent } from './render-text-content';
export { hasScopedStaticStylesheets, renderStylesheets } from './styles';
export { toIteratorDirective } from './to-iterator-directive';
export { validateStyleTextContents } from './validate-style-text-contents';
Expand Down
16 changes: 16 additions & 0 deletions packages/@lwc/ssr-runtime/src/render-text-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2024, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

/**
* Given an object, render it for use as a text content node.
* @param value
*/
export function renderTextContent(value: any): string {
nolanlawson marked this conversation as resolved.
Show resolved Hide resolved
// Using non strict equality to align with original implementation (ex. undefined == null)
// See: https://github.com/salesforce/lwc/blob/348130f/packages/%40lwc/engine-core/src/framework/api.ts#L548
return value == null ? '' : String(value);
}