@lwc/ssr-compiler 8.12.1 → 8.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile-js/errors.d.ts +4 -0
- package/dist/compile-js/lwc-import.d.ts +9 -1
- package/dist/compile-js/types.d.ts +0 -1
- package/dist/compile-template/ir-to-es.d.ts +1 -1
- package/dist/compile-template/transformers/legacyIf.d.ts +3 -0
- package/dist/compile-template/transformers/lwcIf.d.ts +3 -0
- package/dist/estree/validators.d.ts +0 -18
- package/dist/index.cjs.js +168 -82
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +169 -83
- package/dist/index.js.map +1 -1
- package/dist/shared.d.ts +1 -1
- package/package.json +5 -5
- package/dist/compile-template/transformers/if.d.ts +0 -4
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type LWCErrorInfo } from '@lwc/errors';
|
|
2
|
+
type ExtractArguments<T extends string, Numbers extends number = never, Args extends string[] = []> = T extends `${string}{${infer N extends number}}${infer R}` ? N extends Numbers ? ExtractArguments<R, Numbers, Args> : ExtractArguments<R, N | Numbers, [string, ...Args]> : Args;
|
|
3
|
+
export declare function generateError<const T extends LWCErrorInfo>(error: T, ...args: ExtractArguments<T['message']>): Error;
|
|
4
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ImportDeclaration } from 'estree';
|
|
1
|
+
import type { ImportDeclaration, ExportNamedDeclaration, ExportAllDeclaration } from 'estree';
|
|
2
2
|
import type { NodePath } from 'estree-toolkit';
|
|
3
3
|
import type { ComponentMetaState } from './types';
|
|
4
4
|
/**
|
|
@@ -8,3 +8,11 @@ import type { ComponentMetaState } from './types';
|
|
|
8
8
|
* 2. it makes note of the local var name associated with the `LightningElement` import
|
|
9
9
|
*/
|
|
10
10
|
export declare function replaceLwcImport(path: NodePath<ImportDeclaration>, state: ComponentMetaState): void;
|
|
11
|
+
/**
|
|
12
|
+
* This handles lwc barrel exports by replacing "lwc" with "@lwc/ssr-runtime"
|
|
13
|
+
*/
|
|
14
|
+
export declare function replaceNamedLwcExport(path: NodePath<ExportNamedDeclaration>): void;
|
|
15
|
+
/**
|
|
16
|
+
* This handles all lwc barrel exports by replacing "lwc" with "@lwc/ssr-runtime"
|
|
17
|
+
*/
|
|
18
|
+
export declare function replaceAllLwcExport(path: NodePath<ExportAllDeclaration>): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChildNode as IrChildNode, Node as IrNode } from '@lwc/template-compiler';
|
|
2
2
|
import type { Statement as EsStatement } from 'estree';
|
|
3
3
|
import type { TemplateOpts, TransformerContext } from './types';
|
|
4
|
-
export declare function irChildrenToEs(children: IrChildNode[], cxt: TransformerContext): EsStatement[];
|
|
4
|
+
export declare function irChildrenToEs(children: IrChildNode[], cxt: TransformerContext, cb?: (child: IrChildNode) => (() => void) | void): EsStatement[];
|
|
5
5
|
export declare function irToEs<T extends IrNode>(node: T, cxt: TransformerContext): EsStatement[];
|
|
6
6
|
export declare function templateIrToEsTree(node: IrNode, contextOpts: TemplateOpts): {
|
|
7
7
|
addImport: (imports: string | string[] | Record<string, string | undefined>, source?: string | undefined) => void;
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
import type { CallExpression, Identifier, MemberExpression } from 'estree';
|
|
2
1
|
import type { Checker } from 'estree-toolkit/dist/generated/is-type';
|
|
3
2
|
import type { Node } from 'estree-toolkit/dist/helpers';
|
|
4
|
-
/** Node representing an identifier named "render". */
|
|
5
|
-
type RenderIdentifier = Identifier & {
|
|
6
|
-
name: 'render';
|
|
7
|
-
};
|
|
8
|
-
/** Node representing a member expression `<something>.render`. */
|
|
9
|
-
type RenderMemberExpression = MemberExpression & {
|
|
10
|
-
property: RenderIdentifier;
|
|
11
|
-
};
|
|
12
|
-
/** Node representing a method call `<something>.render()`. */
|
|
13
|
-
type RenderCall = CallExpression & {
|
|
14
|
-
callee: RenderMemberExpression;
|
|
15
|
-
};
|
|
16
|
-
/** Returns `true` if the node is an identifier or `<something>.render()`. */
|
|
17
|
-
export declare const isIdentOrRenderCall: {
|
|
18
|
-
(node: Node | null | undefined): node is Identifier | RenderCall;
|
|
19
|
-
__debugName: string;
|
|
20
|
-
};
|
|
21
3
|
/** A validator that returns `true` if the node is `null`. */
|
|
22
4
|
type NullableChecker<T extends Node> = (node: Node | null | undefined) => node is T | null;
|
|
23
5
|
/** Extends a validator to return `true` if the node is `null`. */
|
package/dist/index.cjs.js
CHANGED
|
@@ -9,11 +9,11 @@ var shared = require('@lwc/shared');
|
|
|
9
9
|
var astring = require('astring');
|
|
10
10
|
var estreeToolkit = require('estree-toolkit');
|
|
11
11
|
var meriyah = require('meriyah');
|
|
12
|
+
var errors = require('@lwc/errors');
|
|
12
13
|
var immer = require('immer');
|
|
13
14
|
var node_path = require('node:path');
|
|
14
15
|
var acorn = require('acorn');
|
|
15
16
|
var templateCompiler = require('@lwc/template-compiler');
|
|
16
|
-
var errors = require('@lwc/errors');
|
|
17
17
|
var builders = require('estree-toolkit/dist/builders');
|
|
18
18
|
var types = require('@babel/types');
|
|
19
19
|
var util = require('util');
|
|
@@ -288,7 +288,7 @@ _ImportManager_map = new WeakMap();
|
|
|
288
288
|
* 2. it makes note of the local var name associated with the `LightningElement` import
|
|
289
289
|
*/
|
|
290
290
|
function replaceLwcImport(path, state) {
|
|
291
|
-
if (!path.node || path
|
|
291
|
+
if (!path.node || !isLwcSource(path)) {
|
|
292
292
|
return;
|
|
293
293
|
}
|
|
294
294
|
for (const specifier of path.node.specifiers) {
|
|
@@ -299,7 +299,31 @@ function replaceLwcImport(path, state) {
|
|
|
299
299
|
break;
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
|
-
path.replaceWith(estreeToolkit.builders.importDeclaration(path.node.specifiers, estreeToolkit.builders.literal('@lwc/ssr-runtime')));
|
|
302
|
+
path.replaceWith(estreeToolkit.builders.importDeclaration(structuredClone(path.node.specifiers), estreeToolkit.builders.literal('@lwc/ssr-runtime')));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* This handles lwc barrel exports by replacing "lwc" with "@lwc/ssr-runtime"
|
|
306
|
+
*/
|
|
307
|
+
function replaceNamedLwcExport(path) {
|
|
308
|
+
if (!path.node || !isLwcSource(path)) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
path.replaceWith(estreeToolkit.builders.exportNamedDeclaration(structuredClone(path.node.declaration), structuredClone(path.node.specifiers), estreeToolkit.builders.literal('@lwc/ssr-runtime')));
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* This handles all lwc barrel exports by replacing "lwc" with "@lwc/ssr-runtime"
|
|
315
|
+
*/
|
|
316
|
+
function replaceAllLwcExport(path) {
|
|
317
|
+
if (!path.node || !isLwcSource(path)) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
path.replaceWith(estreeToolkit.builders.exportAllDeclaration(estreeToolkit.builders.literal('@lwc/ssr-runtime'), structuredClone(path.node.exported)));
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Utility to determine if a node source is 'lwc'
|
|
324
|
+
*/
|
|
325
|
+
function isLwcSource(path) {
|
|
326
|
+
return path.node?.source?.value === 'lwc';
|
|
303
327
|
}
|
|
304
328
|
|
|
305
329
|
/*
|
|
@@ -518,36 +542,13 @@ function esTemplateWithYield(javascriptSegments, ...validators) {
|
|
|
518
542
|
}
|
|
519
543
|
|
|
520
544
|
/*
|
|
521
|
-
* Copyright (c) 2024,
|
|
545
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
522
546
|
* All rights reserved.
|
|
523
547
|
* SPDX-License-Identifier: MIT
|
|
524
548
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
525
549
|
*/
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
return (estreeToolkit.is.identifier(node) ||
|
|
529
|
-
(estreeToolkit.is.callExpression(node) &&
|
|
530
|
-
estreeToolkit.is.memberExpression(node.callee) &&
|
|
531
|
-
estreeToolkit.is.identifier(node.callee.property) &&
|
|
532
|
-
node.callee.property.name === 'render'));
|
|
533
|
-
};
|
|
534
|
-
isIdentOrRenderCall.__debugName = 'identifier or .render() call';
|
|
535
|
-
/** Extends a validator to return `true` if the node is `null`. */
|
|
536
|
-
function isNullableOf(validator) {
|
|
537
|
-
const nullableValidator = (node) => {
|
|
538
|
-
return node === null || validator(node);
|
|
539
|
-
};
|
|
540
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
541
|
-
nullableValidator.__debugName = `nullable(${validator.__debugName || validator.name || 'unknown validator'})`;
|
|
542
|
-
}
|
|
543
|
-
return nullableValidator;
|
|
544
|
-
}
|
|
545
|
-
isNullableOf.__debugName = 'isNullableOf';
|
|
546
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
547
|
-
// Modifying another package's exports is a code smell!
|
|
548
|
-
for (const [key, val] of shared.entries(estreeToolkit.is)) {
|
|
549
|
-
val.__debugName = key;
|
|
550
|
-
}
|
|
550
|
+
function generateError(error, ...args) {
|
|
551
|
+
return new Error(errors.generateErrorMessage(error, args));
|
|
551
552
|
}
|
|
552
553
|
|
|
553
554
|
/*
|
|
@@ -567,8 +568,7 @@ function bMemberExpressionChain(props) {
|
|
|
567
568
|
function getWireParams(node) {
|
|
568
569
|
const { decorators } = node;
|
|
569
570
|
if (decorators.length > 1) {
|
|
570
|
-
|
|
571
|
-
throw new Error('todo - multiple decorators at once');
|
|
571
|
+
throw generateError(errors.DecoratorErrors.ONE_WIRE_DECORATOR_ALLOWED);
|
|
572
572
|
}
|
|
573
573
|
// validate the parameters
|
|
574
574
|
const wireDecorator = decorators[0].expression;
|
|
@@ -611,8 +611,7 @@ function validateWireId(id, path) {
|
|
|
611
611
|
}
|
|
612
612
|
// This is not the exact same validation done in @lwc/babel-plugin-component but it accomplishes the same thing
|
|
613
613
|
if (path.scope?.getBinding(wireAdapterVar)?.kind !== 'module') {
|
|
614
|
-
|
|
615
|
-
throw new Error('todo - WIRE_ADAPTER_SHOULD_BE_IMPORTED');
|
|
614
|
+
throw generateError(errors.DecoratorErrors.COMPUTED_PROPERTY_MUST_BE_CONSTANT_OR_LITERAL);
|
|
616
615
|
}
|
|
617
616
|
}
|
|
618
617
|
function validateWireConfig(config, path) {
|
|
@@ -648,8 +647,10 @@ function validateWireConfig(config, path) {
|
|
|
648
647
|
continue;
|
|
649
648
|
}
|
|
650
649
|
}
|
|
651
|
-
|
|
652
|
-
|
|
650
|
+
else if (estreeToolkit.is.templateLiteral(key)) {
|
|
651
|
+
throw generateError(errors.DecoratorErrors.COMPUTED_PROPERTY_CANNOT_BE_TEMPLATE_LITERAL);
|
|
652
|
+
}
|
|
653
|
+
throw generateError(errors.DecoratorErrors.COMPUTED_PROPERTY_MUST_BE_CONSTANT_OR_LITERAL);
|
|
653
654
|
}
|
|
654
655
|
}
|
|
655
656
|
function catalogWireAdapters(path, state) {
|
|
@@ -754,7 +755,10 @@ const bGenerateMarkup = (esTemplate `
|
|
|
754
755
|
instance.connectedCallback();
|
|
755
756
|
__mutationTracker.disable(instance);
|
|
756
757
|
}
|
|
757
|
-
|
|
758
|
+
// If a render() function is defined on the class or any of its superclasses, then that takes priority.
|
|
759
|
+
// Next, if the class or any of its superclasses has an implicitly-associated template, then that takes
|
|
760
|
+
// second priority (e.g. a foo.html file alongside a foo.js file). Finally, there is a fallback empty template.
|
|
761
|
+
const tmplFn = instance.render?.() ?? ${ /*component class*/3}[__SYMBOL__DEFAULT_TEMPLATE] ?? __fallbackTmpl;
|
|
758
762
|
yield \`<\${tagName}\`;
|
|
759
763
|
|
|
760
764
|
const hostHasScopedStylesheets =
|
|
@@ -794,20 +798,17 @@ const bExposeTemplate = (esTemplate `
|
|
|
794
798
|
* - deferring to the template function for yielding child content
|
|
795
799
|
*/
|
|
796
800
|
function addGenerateMarkupFunction(program, state, tagName, filename) {
|
|
797
|
-
const {
|
|
801
|
+
const { privateFields, publicFields, tmplExplicitImports } = state;
|
|
798
802
|
// The default tag name represents the component name that's passed to the transformer.
|
|
799
803
|
// This is needed to generate markup for dynamic components which are invoked through
|
|
800
804
|
// the generateMarkup function on the constructor.
|
|
801
805
|
// At the time of generation, the invoker does not have reference to its tag name to pass as an argument.
|
|
802
806
|
const defaultTagName = estreeToolkit.builders.literal(tagName);
|
|
803
807
|
const classIdentifier = estreeToolkit.builders.identifier(state.lwcClassName);
|
|
804
|
-
const tmplVar = estreeToolkit.builders.identifier('tmpl');
|
|
805
|
-
const renderCall = hasRenderMethod
|
|
806
|
-
? estreeToolkit.builders.callExpression(estreeToolkit.builders.memberExpression(estreeToolkit.builders.identifier('instance'), estreeToolkit.builders.identifier('render')), [])
|
|
807
|
-
: tmplVar;
|
|
808
808
|
let exposeTemplateBlock = null;
|
|
809
809
|
if (!tmplExplicitImports) {
|
|
810
810
|
const defaultTmplPath = `./${node_path.parse(filename).name}.html`;
|
|
811
|
+
const tmplVar = estreeToolkit.builders.identifier('tmpl');
|
|
811
812
|
program.body.unshift(bImportDeclaration({ default: tmplVar.name }, defaultTmplPath));
|
|
812
813
|
program.body.unshift(bImportDeclaration({ SYMBOL__DEFAULT_TEMPLATE: '__SYMBOL__DEFAULT_TEMPLATE' }));
|
|
813
814
|
exposeTemplateBlock = bExposeTemplate(tmplVar, classIdentifier);
|
|
@@ -828,7 +829,7 @@ function addGenerateMarkupFunction(program, state, tagName, filename) {
|
|
|
828
829
|
SYMBOL__SET_INTERNALS: '__SYMBOL__SET_INTERNALS',
|
|
829
830
|
establishContextfulRelationship: '__establishContextfulRelationship',
|
|
830
831
|
}));
|
|
831
|
-
program.body.push(...bGenerateMarkup(defaultTagName, estreeToolkit.builders.arrayExpression(publicFields.map(estreeToolkit.builders.literal)), estreeToolkit.builders.arrayExpression(privateFields.map(estreeToolkit.builders.literal)), classIdentifier, connectWireAdapterCode
|
|
832
|
+
program.body.push(...bGenerateMarkup(defaultTagName, estreeToolkit.builders.arrayExpression(publicFields.map(estreeToolkit.builders.literal)), estreeToolkit.builders.arrayExpression(privateFields.map(estreeToolkit.builders.literal)), classIdentifier, connectWireAdapterCode));
|
|
832
833
|
if (exposeTemplateBlock) {
|
|
833
834
|
program.body.push(exposeTemplateBlock);
|
|
834
835
|
}
|
|
@@ -861,6 +862,12 @@ function removeDecoratorImport(path) {
|
|
|
861
862
|
*/
|
|
862
863
|
const visitors = {
|
|
863
864
|
$: { scope: true },
|
|
865
|
+
ExportNamedDeclaration(path) {
|
|
866
|
+
replaceNamedLwcExport(path);
|
|
867
|
+
},
|
|
868
|
+
ExportAllDeclaration(path) {
|
|
869
|
+
replaceAllLwcExport(path);
|
|
870
|
+
},
|
|
864
871
|
ImportDeclaration(path, state) {
|
|
865
872
|
if (!path.node || !path.node.source.value || typeof path.node.source.value !== 'string') {
|
|
866
873
|
return;
|
|
@@ -919,6 +926,7 @@ const visitors = {
|
|
|
919
926
|
return;
|
|
920
927
|
}
|
|
921
928
|
const { decorators } = node;
|
|
929
|
+
validateUniqueDecorator(decorators);
|
|
922
930
|
const decoratedExpression = decorators?.[0]?.expression;
|
|
923
931
|
if (estreeToolkit.is.identifier(decoratedExpression) && decoratedExpression.name === 'api') {
|
|
924
932
|
state.publicFields.push(node.key.name);
|
|
@@ -950,6 +958,7 @@ const visitors = {
|
|
|
950
958
|
return;
|
|
951
959
|
}
|
|
952
960
|
const { decorators } = node;
|
|
961
|
+
validateUniqueDecorator(decorators);
|
|
953
962
|
// The real type is a subset of `Expression`, which doesn't work with the `is` validators
|
|
954
963
|
const decoratedExpression = decorators?.[0]?.expression;
|
|
955
964
|
if (estreeToolkit.is.callExpression(decoratedExpression) &&
|
|
@@ -977,9 +986,6 @@ const visitors = {
|
|
|
977
986
|
case 'connectedCallback':
|
|
978
987
|
state.hasConnectedCallback = true;
|
|
979
988
|
break;
|
|
980
|
-
case 'render':
|
|
981
|
-
state.hasRenderMethod = true;
|
|
982
|
-
break;
|
|
983
989
|
case 'renderedCallback':
|
|
984
990
|
state.hadRenderedCallback = true;
|
|
985
991
|
path.remove();
|
|
@@ -1014,6 +1020,21 @@ const visitors = {
|
|
|
1014
1020
|
},
|
|
1015
1021
|
},
|
|
1016
1022
|
};
|
|
1023
|
+
function validateUniqueDecorator(decorators) {
|
|
1024
|
+
if (decorators.length < 2) {
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
const expressions = decorators.map(({ expression }) => expression);
|
|
1028
|
+
const hasWire = expressions.some((expr) => estreeToolkit.is.callExpression(expr) && estreeToolkit.is.identifier(expr.callee, { name: 'wire' }));
|
|
1029
|
+
const hasApi = expressions.some((expr) => estreeToolkit.is.identifier(expr, { name: 'api' }));
|
|
1030
|
+
if (hasWire && hasApi) {
|
|
1031
|
+
throw generateError(errors.DecoratorErrors.CONFLICT_WITH_ANOTHER_DECORATOR, 'api');
|
|
1032
|
+
}
|
|
1033
|
+
const hasTrack = expressions.some((expr) => estreeToolkit.is.identifier(expr, { name: 'track' }));
|
|
1034
|
+
if ((hasWire || hasApi) && hasTrack) {
|
|
1035
|
+
throw generateError(errors.DecoratorErrors.CONFLICT_WITH_ANOTHER_DECORATOR, 'track');
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1017
1038
|
function compileJS(src, filename, tagName, options, compilationMode) {
|
|
1018
1039
|
let ast = meriyah.parseModule(src, {
|
|
1019
1040
|
module: true,
|
|
@@ -1023,7 +1044,6 @@ function compileJS(src, filename, tagName, options, compilationMode) {
|
|
|
1023
1044
|
isLWC: false,
|
|
1024
1045
|
hasConstructor: false,
|
|
1025
1046
|
hasConnectedCallback: false,
|
|
1026
|
-
hasRenderMethod: false,
|
|
1027
1047
|
hadRenderedCallback: false,
|
|
1028
1048
|
hadDisconnectedCallback: false,
|
|
1029
1049
|
hadErrorCallback: false,
|
|
@@ -1321,6 +1341,30 @@ const Comment = function Comment(node, cxt) {
|
|
|
1321
1341
|
}
|
|
1322
1342
|
};
|
|
1323
1343
|
|
|
1344
|
+
/*
|
|
1345
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
1346
|
+
* All rights reserved.
|
|
1347
|
+
* SPDX-License-Identifier: MIT
|
|
1348
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
1349
|
+
*/
|
|
1350
|
+
/** Extends a validator to return `true` if the node is `null`. */
|
|
1351
|
+
function isNullableOf(validator) {
|
|
1352
|
+
const nullableValidator = (node) => {
|
|
1353
|
+
return node === null || validator(node);
|
|
1354
|
+
};
|
|
1355
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1356
|
+
nullableValidator.__debugName = `nullable(${validator.__debugName || validator.name || 'unknown validator'})`;
|
|
1357
|
+
}
|
|
1358
|
+
return nullableValidator;
|
|
1359
|
+
}
|
|
1360
|
+
isNullableOf.__debugName = 'isNullableOf';
|
|
1361
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1362
|
+
// Modifying another package's exports is a code smell!
|
|
1363
|
+
for (const [key, val] of shared.entries(estreeToolkit.is)) {
|
|
1364
|
+
val.__debugName = key;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1324
1368
|
/*
|
|
1325
1369
|
* Copyright (c) 2024, salesforce.com, inc.
|
|
1326
1370
|
* All rights reserved.
|
|
@@ -1366,6 +1410,18 @@ const bAddLightContent = (esTemplate `
|
|
|
1366
1410
|
${ /* slot content */false}
|
|
1367
1411
|
});
|
|
1368
1412
|
`);
|
|
1413
|
+
function getShadowSlottedContent(slottableChildren, cxt) {
|
|
1414
|
+
return optimizeAdjacentYieldStmts(irChildrenToEs(slottableChildren, cxt, (child) => {
|
|
1415
|
+
const { isSlotted } = cxt;
|
|
1416
|
+
if (child.type === 'ExternalComponent' || child.type === 'Element') {
|
|
1417
|
+
cxt.isSlotted = false;
|
|
1418
|
+
}
|
|
1419
|
+
// cleanup function
|
|
1420
|
+
return () => {
|
|
1421
|
+
cxt.isSlotted = isSlotted;
|
|
1422
|
+
};
|
|
1423
|
+
}));
|
|
1424
|
+
}
|
|
1369
1425
|
// Light DOM slots are a bit complex because of needing to handle slots _not_ at the top level
|
|
1370
1426
|
// At the non-top level, it matters what the ancestors are. These are relevant to slots:
|
|
1371
1427
|
// - If (`if:true`, `if:false`)
|
|
@@ -1414,7 +1470,10 @@ function getLightSlottedContent(rootNodes, cxt) {
|
|
|
1414
1470
|
leaf.attributes = leaf.attributes.filter((attr) => attr.name !== 'slot');
|
|
1415
1471
|
}
|
|
1416
1472
|
});
|
|
1473
|
+
const { isSlotted: originalIsSlotted } = cxt;
|
|
1474
|
+
cxt.isSlotted = ancestorIndices.length > 1 || clone.type === 'Slot';
|
|
1417
1475
|
const slotContent = irToEs(clone, cxt);
|
|
1476
|
+
cxt.isSlotted = originalIsSlotted;
|
|
1418
1477
|
results.push(estreeToolkit.builders.expressionStatement(bAddLightContent(slotName, null, slotContent)));
|
|
1419
1478
|
};
|
|
1420
1479
|
const traverse = (nodes, ancestorIndices) => {
|
|
@@ -1452,7 +1511,7 @@ function getSlottedContent(node, cxt) {
|
|
|
1452
1511
|
// Anything inside the slotted content is a normal slotted content except for `<template lwc:slot-data>` which is a scoped slot.
|
|
1453
1512
|
const slottableChildren = node.children.filter((child) => child.type !== 'ScopedSlotFragment');
|
|
1454
1513
|
const scopedSlottableChildren = node.children.filter((child) => child.type === 'ScopedSlotFragment');
|
|
1455
|
-
const shadowSlotContent =
|
|
1514
|
+
const shadowSlotContent = getShadowSlottedContent(slottableChildren, cxt);
|
|
1456
1515
|
const lightSlotContent = getLightSlottedContent(slottableChildren, cxt);
|
|
1457
1516
|
const scopedSlotContent = scopedSlottableChildren.map((child) => {
|
|
1458
1517
|
const boundVariableName = child.slotData.value.name;
|
|
@@ -1604,6 +1663,12 @@ const bYieldDynamicValue = (esTemplateWithYield `
|
|
|
1604
1663
|
attrValue = shouldNormalize ? 0 : attrValue;
|
|
1605
1664
|
}
|
|
1606
1665
|
|
|
1666
|
+
// Backwards compatibility with historical patchStyleAttribute() behavior:
|
|
1667
|
+
// https://github.com/salesforce/lwc/blob/59e2c6c/packages/%40lwc/engine-core/src/framework/modules/computed-style-attr.ts#L40
|
|
1668
|
+
if (attrName === 'style' && (typeof attrValue !== 'string' || attrValue === '')) {
|
|
1669
|
+
attrValue = undefined;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1607
1672
|
if (attrValue !== undefined && attrValue !== null) {
|
|
1608
1673
|
yield ' ' + attrName;
|
|
1609
1674
|
|
|
@@ -1834,36 +1899,14 @@ const ForOf = function ForEach(node, cxt) {
|
|
|
1834
1899
|
* SPDX-License-Identifier: MIT
|
|
1835
1900
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
1836
1901
|
*/
|
|
1837
|
-
function
|
|
1838
|
-
return estreeToolkit.builders.expressionStatement(estreeToolkit.builders.yieldExpression(estreeToolkit.builders.literal(`<!--${text}-->`)));
|
|
1839
|
-
}
|
|
1840
|
-
function bBlockStatement(childNodes, cxt, insertComments) {
|
|
1841
|
-
let statements = irChildrenToEs(childNodes, cxt);
|
|
1842
|
-
if (insertComments)
|
|
1843
|
-
statements = [bYieldComment(), ...statements, bYieldComment()];
|
|
1844
|
-
return estreeToolkit.builders.blockStatement(optimizeAdjacentYieldStmts(statements));
|
|
1845
|
-
}
|
|
1846
|
-
const If = function If(node, cxt) {
|
|
1902
|
+
const LegacyIf = function If(node, cxt) {
|
|
1847
1903
|
const { modifier: trueOrFalseAsStr, condition, children } = node;
|
|
1848
1904
|
const trueOrFalse = trueOrFalseAsStr === 'true';
|
|
1905
|
+
// FIXME: Does engine-server actually do triple-equals here?
|
|
1849
1906
|
const comparison = estreeToolkit.builders.binaryExpression('===', estreeToolkit.builders.literal(trueOrFalse), expressionIrToEs(condition, cxt));
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
const { children, condition, else: elseNode } = ifElseIfNode;
|
|
1854
|
-
let elseBlock = null;
|
|
1855
|
-
if (elseNode) {
|
|
1856
|
-
if (elseNode.type === 'ElseBlock') {
|
|
1857
|
-
elseBlock = bBlockStatement(elseNode.children, cxt, true);
|
|
1858
|
-
}
|
|
1859
|
-
else {
|
|
1860
|
-
elseBlock = bIfStatement(elseNode, cxt);
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
return estreeToolkit.builders.ifStatement(expressionIrToEs(condition, cxt), bBlockStatement(children, cxt, !cxt.isSlotted), elseBlock);
|
|
1864
|
-
}
|
|
1865
|
-
const IfBlock = function IfBlock(node, cxt) {
|
|
1866
|
-
return [bIfStatement(node, cxt)];
|
|
1907
|
+
const childStatements = irChildrenToEs(children, cxt);
|
|
1908
|
+
const block = estreeToolkit.builders.blockStatement(optimizeAdjacentYieldStmts(childStatements));
|
|
1909
|
+
return [estreeToolkit.builders.ifStatement(comparison, block)];
|
|
1867
1910
|
};
|
|
1868
1911
|
|
|
1869
1912
|
/*
|
|
@@ -1984,6 +2027,46 @@ function createNewContext(templateOptions) {
|
|
|
1984
2027
|
};
|
|
1985
2028
|
}
|
|
1986
2029
|
|
|
2030
|
+
/*
|
|
2031
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
2032
|
+
* All rights reserved.
|
|
2033
|
+
* SPDX-License-Identifier: MIT
|
|
2034
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
2035
|
+
*/
|
|
2036
|
+
// lwc:if/lwc:elseif/lwc:else use bookend comments due to VFragment vdom node using them
|
|
2037
|
+
// The bookends should surround the entire if/elseif/else series
|
|
2038
|
+
// Note: these should only be rendered if _something_ is rendered by a series of if/elseif/else's
|
|
2039
|
+
function bYieldBookendComment() {
|
|
2040
|
+
return estreeToolkit.builders.expressionStatement(estreeToolkit.builders.yieldExpression(estreeToolkit.builders.literal(`<!---->`)));
|
|
2041
|
+
}
|
|
2042
|
+
function bBlockStatement(childNodes, cxt) {
|
|
2043
|
+
const childStatements = irChildrenToEs(childNodes, cxt);
|
|
2044
|
+
// Due to `flattenFragmentsInChildren`, we have to remove bookends for all _top-level_ slotted
|
|
2045
|
+
// content. This applies to both light DOM and shadow DOM slots, although light DOM slots have
|
|
2046
|
+
// the additional wrinkle that they themselves are VFragments with their own bookends.
|
|
2047
|
+
// https://github.com/salesforce/lwc/blob/a33b390/packages/%40lwc/engine-core/src/framework/rendering.ts#L718-L753
|
|
2048
|
+
const statements = cxt.isSlotted
|
|
2049
|
+
? childStatements
|
|
2050
|
+
: [bYieldBookendComment(), ...childStatements, bYieldBookendComment()];
|
|
2051
|
+
return estreeToolkit.builders.blockStatement(optimizeAdjacentYieldStmts(statements));
|
|
2052
|
+
}
|
|
2053
|
+
function bIfStatement(ifElseIfNode, cxt) {
|
|
2054
|
+
const { children, condition, else: elseNode } = ifElseIfNode;
|
|
2055
|
+
let elseBlock = null;
|
|
2056
|
+
if (elseNode) {
|
|
2057
|
+
if (elseNode.type === 'ElseBlock') {
|
|
2058
|
+
elseBlock = bBlockStatement(elseNode.children, cxt);
|
|
2059
|
+
}
|
|
2060
|
+
else {
|
|
2061
|
+
elseBlock = bIfStatement(elseNode, cxt);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
return estreeToolkit.builders.ifStatement(expressionIrToEs(condition, cxt), bBlockStatement(children, cxt), elseBlock);
|
|
2065
|
+
}
|
|
2066
|
+
const IfBlock = function IfBlock(node, cxt) {
|
|
2067
|
+
return [bIfStatement(node, cxt)];
|
|
2068
|
+
};
|
|
2069
|
+
|
|
1987
2070
|
/*
|
|
1988
2071
|
* Copyright (c) 2024, salesforce.com, inc.
|
|
1989
2072
|
* All rights reserved.
|
|
@@ -2006,7 +2089,7 @@ const transformers = {
|
|
|
2006
2089
|
ExternalComponent: Element,
|
|
2007
2090
|
ForEach,
|
|
2008
2091
|
ForOf,
|
|
2009
|
-
If,
|
|
2092
|
+
If: LegacyIf,
|
|
2010
2093
|
IfBlock,
|
|
2011
2094
|
Root,
|
|
2012
2095
|
Text,
|
|
@@ -2018,12 +2101,15 @@ const transformers = {
|
|
|
2018
2101
|
Slot,
|
|
2019
2102
|
Lwc: LwcComponent,
|
|
2020
2103
|
};
|
|
2021
|
-
function irChildrenToEs(children, cxt) {
|
|
2022
|
-
const result =
|
|
2023
|
-
|
|
2024
|
-
cxt.
|
|
2025
|
-
|
|
2026
|
-
|
|
2104
|
+
function irChildrenToEs(children, cxt, cb) {
|
|
2105
|
+
const result = [];
|
|
2106
|
+
for (let i = 0; i < children.length; i++) {
|
|
2107
|
+
cxt.prevSibling = children[i - 1];
|
|
2108
|
+
cxt.nextSibling = children[i + 1];
|
|
2109
|
+
const cleanUp = cb?.(children[i]);
|
|
2110
|
+
result.push(...irToEs(children[i], cxt));
|
|
2111
|
+
cleanUp?.();
|
|
2112
|
+
}
|
|
2027
2113
|
cxt.prevSibling = undefined;
|
|
2028
2114
|
cxt.nextSibling = undefined;
|
|
2029
2115
|
return result;
|
|
@@ -2173,5 +2259,5 @@ function compileTemplateForSSR(src, filename, options, mode = shared.DEFAULT_SSR
|
|
|
2173
2259
|
|
|
2174
2260
|
exports.compileComponentForSSR = compileComponentForSSR;
|
|
2175
2261
|
exports.compileTemplateForSSR = compileTemplateForSSR;
|
|
2176
|
-
/** version: 8.12.
|
|
2262
|
+
/** version: 8.12.2 */
|
|
2177
2263
|
//# sourceMappingURL=index.cjs.js.map
|