@lwc/template-compiler 6.6.2 → 7.0.0-alpha.0
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/LICENSE.md +21 -1
- package/README.md +5 -0
- package/dist/codegen/codegen.d.ts +2 -0
- package/dist/config.d.ts +9 -1
- package/dist/index.cjs.js +180 -15
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +180 -15
- package/dist/index.js.map +1 -1
- package/dist/scopeTokens.d.ts +6 -0
- package/dist/shared/constants.d.ts +4 -0
- package/dist/shared/estree.d.ts +2 -0
- package/dist/shared/types.d.ts +1 -0
- package/dist/state.d.ts +11 -2
- package/package.json +5 -5
package/LICENSE.md
CHANGED
|
@@ -15,7 +15,27 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
15
15
|
|
|
16
16
|
## @parse5/tools
|
|
17
17
|
|
|
18
|
-
MIT
|
|
18
|
+
The MIT License (MIT)
|
|
19
|
+
|
|
20
|
+
Copyright © 2024 James Garbutt
|
|
21
|
+
|
|
22
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
23
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
24
|
+
in the Software without restriction, including without limitation the rights
|
|
25
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
26
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
27
|
+
furnished to do so, subject to the following conditions:
|
|
28
|
+
|
|
29
|
+
The above copyright notice and this permission notice shall be included in
|
|
30
|
+
all copies or substantial portions of the Software.
|
|
31
|
+
|
|
32
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
33
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
34
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
35
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
36
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
37
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
38
|
+
THE SOFTWARE.
|
|
19
39
|
|
|
20
40
|
## entities
|
|
21
41
|
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ yarn add --dev @lwc/template-compiler
|
|
|
13
13
|
```js
|
|
14
14
|
import { compile } from '@lwc/template-compiler';
|
|
15
15
|
|
|
16
|
+
const filename = 'component.html';
|
|
16
17
|
const options = {};
|
|
17
18
|
const { code, warnings } = compile(
|
|
18
19
|
`
|
|
@@ -20,6 +21,7 @@ const { code, warnings } = compile(
|
|
|
20
21
|
<h1>Hello World!</h1>
|
|
21
22
|
</template>
|
|
22
23
|
`,
|
|
24
|
+
filename,
|
|
23
25
|
options
|
|
24
26
|
);
|
|
25
27
|
|
|
@@ -44,10 +46,13 @@ const { code, warnings } = compile(`<template><h1>Hello World!</h1></template>`,
|
|
|
44
46
|
**Parameters:**
|
|
45
47
|
|
|
46
48
|
- `source` (string, required) - the HTML template source to compile.
|
|
49
|
+
- `filename` (string, required) - the source filename with extension.
|
|
47
50
|
- `options` (object, required) - the options to used to compile the HTML template source.
|
|
48
51
|
|
|
49
52
|
**Options:**
|
|
50
53
|
|
|
54
|
+
- `name` (type: `string`, optional, `undefined` by default) - name of the component, e.g. `foo` in `x/foo`.
|
|
55
|
+
- `namespace` (type: `string`, optional, `undefined` by default) - namespace of the component, e.g. `x` in `x/foo`.
|
|
51
56
|
- `experimentalComputedMemberExpression` (boolean, optional, `false` by default) - set to `true` to enable computed member expression in the template, eg: `{list[0].name}`.
|
|
52
57
|
- `experimentalComplexExpressions` (boolean, optional, `false` by default) - set to `true` to enable use of (a subset of) JavaScript expressions in place of template bindings.
|
|
53
58
|
- `experimentalDynamicDirective` (boolean, optional, `false` by default) - set to `true` to allow the usage of `lwc:dynamic` directives in the template.
|
|
@@ -68,6 +68,8 @@ export default class CodeGen {
|
|
|
68
68
|
genFlatten(children: t.Expression[]): import("estree").CallExpression;
|
|
69
69
|
genScopedId(id: string | t.Expression): t.CallExpression;
|
|
70
70
|
genScopedFragId(id: string | t.Expression): t.CallExpression;
|
|
71
|
+
genClassExpression(value: Expression): import("estree").Expression;
|
|
72
|
+
genNormalizeClassName(className: t.Expression): t.CallExpression;
|
|
71
73
|
/**
|
|
72
74
|
* Generates childs vnodes when slot content is static.
|
|
73
75
|
* @param slotName
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { InstrumentationObject } from '@lwc/errors';
|
|
2
2
|
import { CustomRendererConfig } from './shared/renderer-hooks';
|
|
3
3
|
export interface Config {
|
|
4
|
+
/** The name of the component. For example, the name in `<my-component>` is `"component"`. */
|
|
5
|
+
name?: string;
|
|
6
|
+
/** The namespace of the component. For example, the namespace in `<my-component>` is `"my"`. */
|
|
7
|
+
namespace?: string;
|
|
4
8
|
/**
|
|
5
9
|
* Specification to use to determine which nodes in the template require custom renderer hooks.
|
|
6
10
|
*/
|
|
@@ -61,5 +65,9 @@ export interface Config {
|
|
|
61
65
|
*/
|
|
62
66
|
apiVersion?: number;
|
|
63
67
|
}
|
|
64
|
-
|
|
68
|
+
type OptionalConfigNames = 'customRendererConfig' | 'instrumentation' | 'namespace' | 'name';
|
|
69
|
+
type RequiredConfigOptions = Required<Omit<Config, OptionalConfigNames>>;
|
|
70
|
+
type OptionalConfigOptions = Partial<Pick<Config, OptionalConfigNames>>;
|
|
71
|
+
export type NormalizedConfig = RequiredConfigOptions & OptionalConfigOptions;
|
|
65
72
|
export declare function normalizeConfig(config: Config): NormalizedConfig;
|
|
73
|
+
export {};
|
package/dist/index.cjs.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
7
7
|
|
|
8
8
|
var errors = require('@lwc/errors');
|
|
9
|
+
var path = require('path');
|
|
9
10
|
var shared = require('@lwc/shared');
|
|
10
11
|
var he = require('he');
|
|
11
12
|
var acorn = require('acorn');
|
|
@@ -31,6 +32,70 @@ function _interopNamespaceDefault(e) {
|
|
|
31
32
|
var he__namespace = /*#__PURE__*/_interopNamespaceDefault(he);
|
|
32
33
|
var astring__namespace = /*#__PURE__*/_interopNamespaceDefault(astring);
|
|
33
34
|
|
|
35
|
+
/*
|
|
36
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
37
|
+
* All rights reserved.
|
|
38
|
+
* SPDX-License-Identifier: MIT
|
|
39
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
40
|
+
*/
|
|
41
|
+
// The reason this hash code implementation [1] is chosen is because:
|
|
42
|
+
// 1. It has a very low hash collision rate - testing a list of 466,551 English words [2], it generates no collisions
|
|
43
|
+
// 2. It is fast - it can hash those 466k words in 70ms (Node 16, 2020 MacBook Pro)
|
|
44
|
+
// 3. The output size is reasonable (32-bit - this can be base-32 encoded at 10-11 characters)
|
|
45
|
+
//
|
|
46
|
+
// Also note that the reason we're hashing rather than generating a random number is because
|
|
47
|
+
// we want the output to be predictable given the input, which helps with caching.
|
|
48
|
+
//
|
|
49
|
+
// [1]: https://stackoverflow.com/a/52171480
|
|
50
|
+
// [2]: https://github.com/dwyl/english-words/blob/a77cb15f4f5beb59c15b945f2415328a6b33c3b0/words.txt
|
|
51
|
+
function generateHashCode(str) {
|
|
52
|
+
const seed = 0;
|
|
53
|
+
let h1 = 0xdeadbeef ^ seed;
|
|
54
|
+
let h2 = 0x41c6ce57 ^ seed;
|
|
55
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
56
|
+
ch = str.charCodeAt(i);
|
|
57
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
58
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
59
|
+
}
|
|
60
|
+
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
|
|
61
|
+
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
|
62
|
+
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
|
|
63
|
+
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
|
64
|
+
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
65
|
+
}
|
|
66
|
+
function escapeScopeToken(input) {
|
|
67
|
+
// Minimal escape for strings containing the "@" and "#" characters, which are disallowed
|
|
68
|
+
// in certain cases in attribute names
|
|
69
|
+
return input.replace(/@/g, '___at___').replace(/#/g, '___hash___');
|
|
70
|
+
}
|
|
71
|
+
function generateScopeTokens(filename, namespace, name) {
|
|
72
|
+
const uniqueToken = `${namespace}-${name}_${path.basename(filename, path.extname(filename))}`;
|
|
73
|
+
// This scope token is all lowercase so that it works correctly in case-sensitive namespaces (e.g. SVG).
|
|
74
|
+
// It is deliberately designed to discourage people from relying on it by appearing somewhat random.
|
|
75
|
+
// (But not totally random, because it's nice to have stable scope tokens for our own tests.)
|
|
76
|
+
// Base-32 is chosen because it is not case-sensitive (0-v), and generates short strings with the given hash
|
|
77
|
+
// code implementation (10-11 characters).
|
|
78
|
+
const hashCode = generateHashCode(uniqueToken);
|
|
79
|
+
const scopeToken = `lwc-${hashCode.toString(32)}`;
|
|
80
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
81
|
+
// This scope token is based on the namespace and name, and contains a mix of uppercase/lowercase chars
|
|
82
|
+
const legacyScopeToken = escapeScopeToken(uniqueToken);
|
|
83
|
+
const cssScopeTokens = [
|
|
84
|
+
scopeToken,
|
|
85
|
+
`${scopeToken}-host`, // implicit scope token created by `makeHostToken()` in `@lwc/engine-core`
|
|
86
|
+
// The legacy tokens must be returned as well since we technically don't know what we're going to render
|
|
87
|
+
// This is not strictly required since this is only used for Jest serialization (as of this writing),
|
|
88
|
+
// and people are unlikely to set runtime flags in Jest, but it is technically correct to include this.
|
|
89
|
+
legacyScopeToken,
|
|
90
|
+
`${legacyScopeToken}-host`,
|
|
91
|
+
];
|
|
92
|
+
return {
|
|
93
|
+
scopeToken,
|
|
94
|
+
legacyScopeToken,
|
|
95
|
+
cssScopeTokens,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
34
99
|
/*
|
|
35
100
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
36
101
|
* All rights reserved.
|
|
@@ -38,7 +103,7 @@ var astring__namespace = /*#__PURE__*/_interopNamespaceDefault(astring);
|
|
|
38
103
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
39
104
|
*/
|
|
40
105
|
let State$1 = class State {
|
|
41
|
-
constructor(config) {
|
|
106
|
+
constructor(config, filename) {
|
|
42
107
|
this.config = config;
|
|
43
108
|
this.crElmToConfigMap = config.customRendererConfig
|
|
44
109
|
? Object.fromEntries(config.customRendererConfig.elements.map((element) => {
|
|
@@ -48,6 +113,8 @@ let State$1 = class State {
|
|
|
48
113
|
: {};
|
|
49
114
|
this.crDirectives = new Set(config.customRendererConfig?.directives);
|
|
50
115
|
this.crCheckedElements = new Map();
|
|
116
|
+
this.filename = filename;
|
|
117
|
+
this.scopeTokens = generateScopeTokens(filename, config.namespace, config.name);
|
|
51
118
|
}
|
|
52
119
|
};
|
|
53
120
|
|
|
@@ -56,6 +123,10 @@ const PARSE_FRAGMENT_METHOD_NAME = 'parseFragment';
|
|
|
56
123
|
const PARSE_SVG_FRAGMENT_METHOD_NAME = 'parseSVGFragment';
|
|
57
124
|
const RENDERER = 'renderer';
|
|
58
125
|
const LWC_MODULE_NAME = 'lwc';
|
|
126
|
+
const FREEZE_TEMPLATE = 'freezeTemplate';
|
|
127
|
+
const IMPLICIT_STYLESHEETS = '_implicitStylesheets';
|
|
128
|
+
const IMPLICIT_SCOPED_STYLESHEETS = '_implicitScopedStylesheets';
|
|
129
|
+
const IMPLICIT_STYLESHEET_IMPORTS = [IMPLICIT_STYLESHEETS, IMPLICIT_SCOPED_STYLESHEETS];
|
|
59
130
|
const TEMPLATE_FUNCTION_NAME = 'tmpl';
|
|
60
131
|
const TEMPLATE_PARAMS = {
|
|
61
132
|
INSTANCE: '$cmp',
|
|
@@ -137,6 +208,8 @@ const AVAILABLE_OPTION_NAMES = new Set([
|
|
|
137
208
|
'enableDynamicComponents',
|
|
138
209
|
'preserveHtmlComments',
|
|
139
210
|
'instrumentation',
|
|
211
|
+
'namespace',
|
|
212
|
+
'name',
|
|
140
213
|
]);
|
|
141
214
|
function normalizeCustomRendererConfig(config) {
|
|
142
215
|
const tagNames = [];
|
|
@@ -8826,6 +8899,14 @@ function functionDeclaration(id, params, body, config) {
|
|
|
8826
8899
|
...config,
|
|
8827
8900
|
};
|
|
8828
8901
|
}
|
|
8902
|
+
function ifStatement(test, consequent, alternate) {
|
|
8903
|
+
return {
|
|
8904
|
+
type: 'IfStatement',
|
|
8905
|
+
test,
|
|
8906
|
+
consequent,
|
|
8907
|
+
alternate,
|
|
8908
|
+
};
|
|
8909
|
+
}
|
|
8829
8910
|
function blockStatement(body, config) {
|
|
8830
8911
|
return {
|
|
8831
8912
|
type: 'BlockStatement',
|
|
@@ -12792,8 +12873,6 @@ function generateTemplateMetadata(codeGen) {
|
|
|
12792
12873
|
const slotsMetadata = assignmentExpression('=', slotsProperty, slotsArray);
|
|
12793
12874
|
metadataExpressions.push(expressionStatement(slotsMetadata));
|
|
12794
12875
|
}
|
|
12795
|
-
const stylesheetsMetadata = assignmentExpression('=', memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier('stylesheets')), arrayExpression([]));
|
|
12796
|
-
metadataExpressions.push(expressionStatement(stylesheetsMetadata));
|
|
12797
12876
|
// ignore when shadow because we don't want to modify template unnecessarily
|
|
12798
12877
|
if (codeGen.renderMode === exports.LWCDirectiveRenderMode.light) {
|
|
12799
12878
|
const renderModeMetadata = assignmentExpression('=', memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier('renderMode')), literal$1('light'));
|
|
@@ -12803,8 +12882,57 @@ function generateTemplateMetadata(codeGen) {
|
|
|
12803
12882
|
const refsMetadata = assignmentExpression('=', memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier('hasRefs')), literal$1(true));
|
|
12804
12883
|
metadataExpressions.push(expressionStatement(refsMetadata));
|
|
12805
12884
|
}
|
|
12885
|
+
const stylesheetsMetadata = assignmentExpression('=', memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier('stylesheets')), arrayExpression([]));
|
|
12886
|
+
metadataExpressions.push(expressionStatement(stylesheetsMetadata));
|
|
12887
|
+
const stylesheetTokens = generateStylesheetTokens(codeGen);
|
|
12888
|
+
metadataExpressions.push(...stylesheetTokens);
|
|
12889
|
+
const implicitStylesheetImports = generateImplicitStylesheetImports();
|
|
12890
|
+
metadataExpressions.push(...implicitStylesheetImports);
|
|
12806
12891
|
return metadataExpressions;
|
|
12807
12892
|
}
|
|
12893
|
+
// Generates conditional statements to insert stylesheets into the
|
|
12894
|
+
// tmpl.stylesheets metadata.
|
|
12895
|
+
function generateImplicitStylesheetImports() {
|
|
12896
|
+
// tmpl.stylesheets
|
|
12897
|
+
const tmplStylesheetsExpr = memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier('stylesheets'));
|
|
12898
|
+
// tmpl.stylesheets.push.apply
|
|
12899
|
+
const tmplStylesheetPushApplyExpr = memberExpression(memberExpression(tmplStylesheetsExpr, identifier('push')), identifier('apply'));
|
|
12900
|
+
// Generates conditional logic to the imported styleSheet, ex:
|
|
12901
|
+
// if (_implicitStylesheets) {
|
|
12902
|
+
// tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitStylesheets);
|
|
12903
|
+
// }
|
|
12904
|
+
const implicitStyleSheets = IMPLICIT_STYLESHEET_IMPORTS.map((styleSheetName) => ifStatement(identifier(styleSheetName), blockStatement([
|
|
12905
|
+
expressionStatement(callExpression(tmplStylesheetPushApplyExpr, [
|
|
12906
|
+
tmplStylesheetsExpr,
|
|
12907
|
+
identifier(styleSheetName),
|
|
12908
|
+
])),
|
|
12909
|
+
])));
|
|
12910
|
+
return implicitStyleSheets;
|
|
12911
|
+
}
|
|
12912
|
+
function generateStylesheetTokens(codeGen) {
|
|
12913
|
+
const { apiVersion, state: { scopeTokens: { scopeToken, legacyScopeToken }, }, } = codeGen;
|
|
12914
|
+
const generateStyleTokenAssignmentExpr = (styleToken, styleTokenName) => {
|
|
12915
|
+
// tmpl.stylesheetToken | tmpl.legacyStylesheetToken
|
|
12916
|
+
const styleTokenExpr = memberExpression(identifier(TEMPLATE_FUNCTION_NAME), identifier(styleToken));
|
|
12917
|
+
return expressionStatement(assignmentExpression('=', styleTokenExpr, literal$1(styleTokenName)));
|
|
12918
|
+
};
|
|
12919
|
+
const styleTokens = [];
|
|
12920
|
+
if (shared.isAPIFeatureEnabled(0 /* APIFeature.LOWERCASE_SCOPE_TOKENS */, apiVersion)) {
|
|
12921
|
+
// Include both the new and legacy tokens, so that the runtime can decide based on a flag whether
|
|
12922
|
+
// we need to render the legacy one. This is designed for cases where the legacy one is required
|
|
12923
|
+
// for backwards compat (e.g. global stylesheets that rely on the legacy format for a CSS selector).
|
|
12924
|
+
// tmpl.stylesheetToken = "{scopeToken}"
|
|
12925
|
+
styleTokens.push(generateStyleTokenAssignmentExpr('stylesheetToken', scopeToken));
|
|
12926
|
+
// tmpl.legacyStylesheetToken = "{legacyScopeToken}"
|
|
12927
|
+
styleTokens.push(generateStyleTokenAssignmentExpr('legacyStylesheetToken', legacyScopeToken));
|
|
12928
|
+
}
|
|
12929
|
+
else {
|
|
12930
|
+
// In old API versions, we can just keep doing what we always did
|
|
12931
|
+
// tmpl.stylesheetToken = "{legacyScopeToken}"
|
|
12932
|
+
styleTokens.push(generateStyleTokenAssignmentExpr('stylesheetToken', legacyScopeToken));
|
|
12933
|
+
}
|
|
12934
|
+
return styleTokens;
|
|
12935
|
+
}
|
|
12808
12936
|
const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
|
|
12809
12937
|
const PROPERTY_DELIMITER = /:(.+)/;
|
|
12810
12938
|
// Borrowed from Vue template compiler.
|
|
@@ -13355,6 +13483,7 @@ const RENDER_APIS = {
|
|
|
13355
13483
|
staticPart: { name: 'sp', alias: 'api_static_part' },
|
|
13356
13484
|
tabindex: { name: 'ti', alias: 'api_tab_index' },
|
|
13357
13485
|
text: { name: 't', alias: 'api_text' },
|
|
13486
|
+
normalizeClassName: { name: 'ncls', alias: 'api_normalize_class_name' },
|
|
13358
13487
|
};
|
|
13359
13488
|
class CodeGen {
|
|
13360
13489
|
constructor({ root, state, scopeFragmentId, }) {
|
|
@@ -13464,6 +13593,17 @@ class CodeGen {
|
|
|
13464
13593
|
}
|
|
13465
13594
|
return this._renderApiCall(RENDER_APIS.scopedFragId, [id]);
|
|
13466
13595
|
}
|
|
13596
|
+
genClassExpression(value) {
|
|
13597
|
+
let classExpression = this.bindExpression(value);
|
|
13598
|
+
const isClassNameObjectBindingEnabled = shared.isAPIFeatureEnabled(9 /* APIFeature.TEMPLATE_CLASS_NAME_OBJECT_BINDING */, this.state.config.apiVersion);
|
|
13599
|
+
if (isClassNameObjectBindingEnabled) {
|
|
13600
|
+
classExpression = this.genNormalizeClassName(classExpression);
|
|
13601
|
+
}
|
|
13602
|
+
return classExpression;
|
|
13603
|
+
}
|
|
13604
|
+
genNormalizeClassName(className) {
|
|
13605
|
+
return this._renderApiCall(RENDER_APIS.normalizeClassName, [className]);
|
|
13606
|
+
}
|
|
13467
13607
|
/**
|
|
13468
13608
|
* Generates childs vnodes when slot content is static.
|
|
13469
13609
|
* @param slotName
|
|
@@ -13745,7 +13885,7 @@ class CodeGen {
|
|
|
13745
13885
|
}
|
|
13746
13886
|
else if (name === 'class') {
|
|
13747
13887
|
partToken = `${"c" /* STATIC_PART_TOKEN_ID.CLASS */}${partId}`;
|
|
13748
|
-
databag.push(property$1(identifier('className'), this.
|
|
13888
|
+
databag.push(property$1(identifier('className'), this.genClassExpression(value)));
|
|
13749
13889
|
}
|
|
13750
13890
|
else {
|
|
13751
13891
|
partToken = `${"a" /* STATIC_PART_TOKEN_ID.ATTRIBUTE */}${partId}:${name}`;
|
|
@@ -13919,13 +14059,21 @@ function generateComponentImports(codeGen) {
|
|
|
13919
14059
|
});
|
|
13920
14060
|
}
|
|
13921
14061
|
function generateLwcApisImport(codeGen) {
|
|
13922
|
-
|
|
13923
|
-
|
|
13924
|
-
.map((name) => {
|
|
14062
|
+
// freezeTemplate will always be needed and is called once it has been created.
|
|
14063
|
+
const imports = [...codeGen.usedLwcApis, FREEZE_TEMPLATE].sort().map((name) => {
|
|
13925
14064
|
return importSpecifier(identifier(name), identifier(name));
|
|
13926
14065
|
});
|
|
13927
14066
|
return importDeclaration(imports, literal$1(LWC_MODULE_NAME));
|
|
13928
14067
|
}
|
|
14068
|
+
function generateStylesheetImports(codeGen) {
|
|
14069
|
+
const { state: { filename }, } = codeGen;
|
|
14070
|
+
const relPath = `./${path.basename(filename, path.extname(filename))}`;
|
|
14071
|
+
const imports = IMPLICIT_STYLESHEET_IMPORTS.map((stylesheet) => {
|
|
14072
|
+
const extension = stylesheet === IMPLICIT_STYLESHEETS ? '.css' : '.scoped.css?scoped=true';
|
|
14073
|
+
return importDeclaration([importDefaultSpecifier(identifier(stylesheet))], literal$1(`${relPath}${extension}`));
|
|
14074
|
+
});
|
|
14075
|
+
return imports;
|
|
14076
|
+
}
|
|
13929
14077
|
function generateHoistedNodes(codegen) {
|
|
13930
14078
|
return codegen.hoistedNodes.map(({ identifier, expr }) => {
|
|
13931
14079
|
return variableDeclaration('const', [variableDeclarator(identifier, expr)]);
|
|
@@ -13953,7 +14101,11 @@ function generateHoistedNodes(codegen) {
|
|
|
13953
14101
|
*/
|
|
13954
14102
|
function format(templateFn, codeGen) {
|
|
13955
14103
|
codeGen.usedLwcApis.add(SECURE_REGISTER_TEMPLATE_METHOD_NAME);
|
|
13956
|
-
const imports = [
|
|
14104
|
+
const imports = [
|
|
14105
|
+
...generateStylesheetImports(codeGen),
|
|
14106
|
+
...generateComponentImports(codeGen),
|
|
14107
|
+
generateLwcApisImport(codeGen),
|
|
14108
|
+
];
|
|
13957
14109
|
const hoistedNodes = generateHoistedNodes(codeGen);
|
|
13958
14110
|
const metadata = generateTemplateMetadata(codeGen);
|
|
13959
14111
|
const optimizedTemplateDeclarations = optimizeStaticExpressions(templateFn);
|
|
@@ -13963,7 +14115,15 @@ function format(templateFn, codeGen) {
|
|
|
13963
14115
|
identifier(TEMPLATE_FUNCTION_NAME),
|
|
13964
14116
|
])),
|
|
13965
14117
|
];
|
|
13966
|
-
|
|
14118
|
+
const freezeTemplate = expressionStatement(callExpression(identifier(FREEZE_TEMPLATE), [identifier(TEMPLATE_FUNCTION_NAME)]));
|
|
14119
|
+
return program([
|
|
14120
|
+
...imports,
|
|
14121
|
+
...hoistedNodes,
|
|
14122
|
+
...templateBody,
|
|
14123
|
+
...metadata,
|
|
14124
|
+
// At this point, no more expando props should be added to `tmpl`.
|
|
14125
|
+
freezeTemplate,
|
|
14126
|
+
]);
|
|
13967
14127
|
}
|
|
13968
14128
|
|
|
13969
14129
|
/*
|
|
@@ -14290,8 +14450,7 @@ function transform(codeGen) {
|
|
|
14290
14450
|
// - string values are parsed and turned into a `classMap` object associating
|
|
14291
14451
|
// each individual class name with a `true` boolean.
|
|
14292
14452
|
if (isExpression$1(value)) {
|
|
14293
|
-
|
|
14294
|
-
data.push(property$1(identifier('className'), classExpression));
|
|
14453
|
+
data.push(property$1(identifier('className'), codeGen.genClassExpression(value)));
|
|
14295
14454
|
}
|
|
14296
14455
|
else if (isStringLiteral(value)) {
|
|
14297
14456
|
const classNames = parseClassNames(value.value);
|
|
@@ -14449,18 +14608,22 @@ function generate (root, state) {
|
|
|
14449
14608
|
*/
|
|
14450
14609
|
function parse(source, config = {}) {
|
|
14451
14610
|
const options = normalizeConfig(config);
|
|
14452
|
-
|
|
14611
|
+
// The file name is never used in this function, defaulting it to an empty string.
|
|
14612
|
+
const state = new State$1(options, '');
|
|
14453
14613
|
return parse$1(source, state);
|
|
14454
14614
|
}
|
|
14455
14615
|
/**
|
|
14456
14616
|
* Compiles a LWC template to JavaScript source code consumable by the engine.
|
|
14457
14617
|
* @param source HTML markup to compile
|
|
14618
|
+
* @param filename HTML filename
|
|
14458
14619
|
* @param config HTML template compilation config
|
|
14459
14620
|
* @returns Object containing the compiled code and any warnings that occurred.
|
|
14460
14621
|
*/
|
|
14461
|
-
function compile(source, config) {
|
|
14622
|
+
function compile(source, filename, config) {
|
|
14462
14623
|
const options = normalizeConfig(config);
|
|
14463
|
-
|
|
14624
|
+
// Note the file name is required to generate implicit css imports and style tokens.
|
|
14625
|
+
// It is not part of the config because all values in the config are optional by convention.
|
|
14626
|
+
const state = new State$1(options, filename);
|
|
14464
14627
|
let code = '';
|
|
14465
14628
|
let root;
|
|
14466
14629
|
const warnings = [];
|
|
@@ -14478,10 +14641,12 @@ function compile(source, config) {
|
|
|
14478
14641
|
diagnostic.message = `Unexpected compilation error: ${diagnostic.message}`;
|
|
14479
14642
|
warnings.push(diagnostic);
|
|
14480
14643
|
}
|
|
14644
|
+
const { scopeTokens: { cssScopeTokens }, } = state;
|
|
14481
14645
|
return {
|
|
14482
14646
|
code,
|
|
14483
14647
|
root,
|
|
14484
14648
|
warnings,
|
|
14649
|
+
cssScopeTokens,
|
|
14485
14650
|
};
|
|
14486
14651
|
}
|
|
14487
14652
|
|
|
@@ -14490,5 +14655,5 @@ exports.default = compile;
|
|
|
14490
14655
|
exports.kebabcaseToCamelcase = kebabcaseToCamelcase;
|
|
14491
14656
|
exports.parse = parse;
|
|
14492
14657
|
exports.toPropertyName = toPropertyName;
|
|
14493
|
-
/** version:
|
|
14658
|
+
/** version: 7.0.0-alpha.0 */
|
|
14494
14659
|
//# sourceMappingURL=index.cjs.js.map
|