@lwc/template-compiler 7.2.0 → 7.2.1
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/README.md +1 -0
- package/dist/codegen/codegen.d.ts +7 -2
- package/dist/config.d.ts +2 -0
- package/dist/index.cjs.js +25 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +25 -20
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ const { code, warnings } = compile(`<template><h1>Hello World!</h1></template>`,
|
|
|
62
62
|
- `enableLwcSpread` (boolean, optional, `true` by default) - Deprecated. Ignored by template-compiler. `lwc:spread` is always enabled.
|
|
63
63
|
- `customRendererConfig` (CustomRendererConfig, optional) - specifies a configuration to use to match elements. Matched elements will get a custom renderer hook in the generated template.
|
|
64
64
|
- `instrumentation` (InstrumentationObject, optional) - instrumentation object to gather metrics and non-error logs for internal use. See the `@lwc/errors` package for details on the interface.
|
|
65
|
+
- `disableSyntheticShadowSupport` (type: `boolean`, default: `false`) - Set to true if synthetic shadow DOM support is not needed, which can result in smaller/faster output.
|
|
65
66
|
|
|
66
67
|
- Example 1: Config to match `<use>` elements under the `svg` namespace and have `href` attribute set.
|
|
67
68
|
|
|
@@ -36,6 +36,11 @@ export default class CodeGen {
|
|
|
36
36
|
* State maintains information about the current compilation configs.
|
|
37
37
|
*/
|
|
38
38
|
readonly state: State;
|
|
39
|
+
/**
|
|
40
|
+
* True if this is a synthetic shadow template - otherwise, we may apply certain optimizations
|
|
41
|
+
* that only exist for native shadow and light DOM.
|
|
42
|
+
*/
|
|
43
|
+
readonly isSyntheticShadow: boolean;
|
|
39
44
|
currentId: number;
|
|
40
45
|
currentKey: number;
|
|
41
46
|
innerHtmlInstances: number;
|
|
@@ -66,8 +71,8 @@ export default class CodeGen {
|
|
|
66
71
|
genIterator(iterable: t.Expression, callback: t.FunctionExpression): import("estree").CallExpression;
|
|
67
72
|
genBind(handler: t.Expression): import("estree").CallExpression;
|
|
68
73
|
genFlatten(children: t.Expression[]): import("estree").CallExpression;
|
|
69
|
-
genScopedId(id: string | t.Expression): t.
|
|
70
|
-
genScopedFragId(id: string | t.Expression): t.
|
|
74
|
+
genScopedId(id: string | t.Expression): t.Expression | t.Literal;
|
|
75
|
+
genScopedFragId(id: string | t.Expression): t.Expression | t.Literal;
|
|
71
76
|
genClassExpression(value: Expression): import("estree").Expression;
|
|
72
77
|
genNormalizeClassName(className: t.Expression): t.CallExpression;
|
|
73
78
|
/**
|
package/dist/config.d.ts
CHANGED
|
@@ -64,6 +64,8 @@ export interface Config {
|
|
|
64
64
|
* The API version to associate with the compiled template
|
|
65
65
|
*/
|
|
66
66
|
apiVersion?: number;
|
|
67
|
+
/** Set to true if synthetic shadow DOM support is not needed, which can result in smaller/faster output. */
|
|
68
|
+
disableSyntheticShadowSupport?: boolean;
|
|
67
69
|
}
|
|
68
70
|
type OptionalConfigNames = 'customRendererConfig' | 'instrumentation' | 'namespace' | 'name';
|
|
69
71
|
type RequiredConfigOptions = Required<Omit<Config, OptionalConfigNames>>;
|
package/dist/index.cjs.js
CHANGED
|
@@ -210,6 +210,7 @@ const AVAILABLE_OPTION_NAMES = new Set([
|
|
|
210
210
|
'instrumentation',
|
|
211
211
|
'namespace',
|
|
212
212
|
'name',
|
|
213
|
+
'disableSyntheticShadowSupport',
|
|
213
214
|
]);
|
|
214
215
|
function normalizeCustomRendererConfig(config) {
|
|
215
216
|
const tagNames = [];
|
|
@@ -261,6 +262,7 @@ function normalizeConfig(config) {
|
|
|
261
262
|
enableDynamicComponents: false,
|
|
262
263
|
enableStaticContentOptimization: true,
|
|
263
264
|
enableLwcSpread: true,
|
|
265
|
+
disableSyntheticShadowSupport: false,
|
|
264
266
|
...config,
|
|
265
267
|
apiVersion, // overrides the config apiVersion
|
|
266
268
|
...{ customRendererConfig },
|
|
@@ -13148,7 +13150,7 @@ function serializeAttrs(element, codeGen) {
|
|
|
13148
13150
|
*/
|
|
13149
13151
|
const attrs = [];
|
|
13150
13152
|
let hasClassAttr = false;
|
|
13151
|
-
const collector = ({ name, value, hasExpression,
|
|
13153
|
+
const collector = ({ name, value, hasExpression, hasSvgUseHref, needsScoping, }) => {
|
|
13152
13154
|
let v = typeof value === 'string' ? templateStringEscape(value) : value;
|
|
13153
13155
|
if (name === 'class') {
|
|
13154
13156
|
hasClassAttr = true;
|
|
@@ -13173,8 +13175,7 @@ function serializeAttrs(element, codeGen) {
|
|
|
13173
13175
|
// Skip serializing here and handle it as if it were a dynamic attribute instead.
|
|
13174
13176
|
// Note that, to maintain backwards compatibility with the non-static output, we treat the valueless
|
|
13175
13177
|
// "boolean" format (e.g. `<div id>`) as the empty string, which is semantically equivalent.
|
|
13176
|
-
|
|
13177
|
-
const needsPlaceholder = hasExpression || hasIdOrIdRef || hasSvgUseHref || hasScopedFragmentRef;
|
|
13178
|
+
const needsPlaceholder = hasExpression || hasSvgUseHref || needsScoping;
|
|
13178
13179
|
// Inject a placeholder where the staticPartId will go when an expression occurs.
|
|
13179
13180
|
// This is only needed for SSR to inject the expression value during serialization.
|
|
13180
13181
|
attrs.push(needsPlaceholder ? `\${"${v}"}` : ` ${name}="${shared.htmlEscape(v, true)}"`);
|
|
@@ -13187,25 +13188,26 @@ function serializeAttrs(element, codeGen) {
|
|
|
13187
13188
|
.map((attr) => {
|
|
13188
13189
|
const { name, value } = attr;
|
|
13189
13190
|
const hasExpression = isExpression$1(value);
|
|
13191
|
+
// For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
|
|
13192
|
+
const hasSvgUseHref = isSvgUseHref(element.name, name, element.namespace) && !isBooleanLiteral(value);
|
|
13190
13193
|
// IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
|
|
13191
13194
|
// Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
|
|
13192
|
-
// TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
|
|
13193
13195
|
const hasIdOrIdRef = (name === 'id' || isIdReferencingAttribute(name)) && !isBooleanLiteral(value);
|
|
13194
|
-
// For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
|
|
13195
|
-
const hasSvgUseHref = isSvgUseHref(element.name, name, element.namespace) && !isBooleanLiteral(value);
|
|
13196
13196
|
// `<a href="#foo">` and `<area href="#foo">` must be dynamic due to synthetic shadow scoping
|
|
13197
13197
|
// Note this only applies if there is an `id` attribute somewhere in the template
|
|
13198
13198
|
const hasScopedFragmentRef = codeGen.scopeFragmentId &&
|
|
13199
13199
|
isStringLiteral(value) &&
|
|
13200
13200
|
isAllowedFragOnlyUrlsXHTML(element.name, name, element.namespace) &&
|
|
13201
13201
|
isFragmentOnlyUrl(value.value);
|
|
13202
|
+
// If we're not running in synthetic shadow mode (light or shadow+disableSyntheticShadowSupport),
|
|
13203
|
+
// then static IDs/IDrefs/fragment refs will be rendered directly into HTML strings.
|
|
13204
|
+
const needsScoping = codeGen.isSyntheticShadow && (hasIdOrIdRef || hasScopedFragmentRef);
|
|
13202
13205
|
return {
|
|
13203
13206
|
hasExpression,
|
|
13204
|
-
hasIdOrIdRef,
|
|
13205
13207
|
hasSvgUseHref,
|
|
13206
|
-
|
|
13208
|
+
needsScoping,
|
|
13207
13209
|
name,
|
|
13208
|
-
value: hasExpression ||
|
|
13210
|
+
value: hasExpression || hasSvgUseHref || needsScoping
|
|
13209
13211
|
? codeGen.getStaticExpressionToken(attr)
|
|
13210
13212
|
: value.value,
|
|
13211
13213
|
};
|
|
@@ -13544,6 +13546,9 @@ class CodeGen {
|
|
|
13544
13546
|
this.scope = this.createScope();
|
|
13545
13547
|
this.state = state;
|
|
13546
13548
|
this.apiVersion = shared.getAPIVersionFromNumber(state.config.apiVersion);
|
|
13549
|
+
this.isSyntheticShadow =
|
|
13550
|
+
this.renderMode !== exports.LWCDirectiveRenderMode.light &&
|
|
13551
|
+
!this.state.config.disableSyntheticShadowSupport;
|
|
13547
13552
|
}
|
|
13548
13553
|
generateKey() {
|
|
13549
13554
|
return this.currentKey++;
|
|
@@ -13612,16 +13617,14 @@ class CodeGen {
|
|
|
13612
13617
|
return this._renderApiCall(RENDER_APIS.flatten, children);
|
|
13613
13618
|
}
|
|
13614
13619
|
genScopedId(id) {
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
}
|
|
13618
|
-
return this._renderApiCall(RENDER_APIS.scopedId, [id]);
|
|
13620
|
+
const value = typeof id === 'string' ? literal$1(id) : id;
|
|
13621
|
+
return this.isSyntheticShadow ? this._renderApiCall(RENDER_APIS.scopedId, [value]) : value;
|
|
13619
13622
|
}
|
|
13620
13623
|
genScopedFragId(id) {
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13624
|
+
const value = typeof id === 'string' ? literal$1(id) : id;
|
|
13625
|
+
return this.isSyntheticShadow
|
|
13626
|
+
? this._renderApiCall(RENDER_APIS.scopedFragId, [value])
|
|
13627
|
+
: value;
|
|
13625
13628
|
}
|
|
13626
13629
|
genClassExpression(value) {
|
|
13627
13630
|
let classExpression = this.bindExpression(value);
|
|
@@ -13910,7 +13913,6 @@ class CodeGen {
|
|
|
13910
13913
|
const { name, value } = attribute;
|
|
13911
13914
|
// IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
|
|
13912
13915
|
// Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
|
|
13913
|
-
// TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
|
|
13914
13916
|
const isIdOrIdRef = (name === 'id' || isIdReferencingAttribute(name)) &&
|
|
13915
13917
|
!isBooleanLiteral(value);
|
|
13916
13918
|
// For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
|
|
@@ -13922,7 +13924,10 @@ class CodeGen {
|
|
|
13922
13924
|
isStringLiteral(value) &&
|
|
13923
13925
|
isAllowedFragOnlyUrlsXHTML(currentNode.name, name, currentNode.namespace) &&
|
|
13924
13926
|
isFragmentOnlyUrl(value.value);
|
|
13925
|
-
|
|
13927
|
+
// If we're not running in synthetic shadow mode (light or shadow+disableSyntheticShadowSupport),
|
|
13928
|
+
// then static IDs/IDrefs/fragment refs will be rendered directly into HTML strings.
|
|
13929
|
+
const needsScoping = this.isSyntheticShadow && (isIdOrIdRef || isScopedFragmentRef);
|
|
13930
|
+
if (isExpression$1(value) || isSvgHref || needsScoping) {
|
|
13926
13931
|
let partToken = '';
|
|
13927
13932
|
if (name === 'style') {
|
|
13928
13933
|
partToken = `${"s" /* STATIC_PART_TOKEN_ID.STYLE */}${partId}`;
|
|
@@ -14706,5 +14711,5 @@ exports.default = compile;
|
|
|
14706
14711
|
exports.kebabcaseToCamelcase = kebabcaseToCamelcase;
|
|
14707
14712
|
exports.parse = parse;
|
|
14708
14713
|
exports.toPropertyName = toPropertyName;
|
|
14709
|
-
/** version: 7.2.
|
|
14714
|
+
/** version: 7.2.1 */
|
|
14710
14715
|
//# sourceMappingURL=index.cjs.js.map
|