@lwc/template-compiler 7.0.3 → 7.0.5
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/codegen/codegen.d.ts +1 -1
- package/dist/index.cjs.js +59 -49
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +59 -49
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -69,7 +69,7 @@ export default class CodeGen {
|
|
|
69
69
|
genScopedId(id: string | t.Expression): t.CallExpression;
|
|
70
70
|
genScopedFragId(id: string | t.Expression): t.CallExpression;
|
|
71
71
|
genClassExpression(value: Expression): import("estree").Expression;
|
|
72
|
-
genNormalizeClassName(className: t.Expression): t.CallExpression
|
|
72
|
+
genNormalizeClassName(className: t.Expression): t.CallExpression;
|
|
73
73
|
/**
|
|
74
74
|
* Generates childs vnodes when slot content is static.
|
|
75
75
|
* @param slotName
|
package/dist/index.cjs.js
CHANGED
|
@@ -12996,7 +12996,7 @@ const STATIC_ELEMENT_WITH_DYNAMIC_TEXT_SET = new WeakSet();
|
|
|
12996
12996
|
const STATIC_ELEMENT_TO_DYNAMIC_TEXT_CHILDREN_CACHE = new WeakMap();
|
|
12997
12997
|
function isStaticNode(node, apiVersion) {
|
|
12998
12998
|
let result = true;
|
|
12999
|
-
const {
|
|
12999
|
+
const { namespace = '', attributes, directives, properties } = node;
|
|
13000
13000
|
// SVG is excluded from static content optimization in older API versions due to issues with case sensitivity
|
|
13001
13001
|
// in CSS scope tokens. See https://github.com/salesforce/lwc/issues/3313
|
|
13002
13002
|
if (!shared.isAPIFeatureEnabled(0 /* APIFeature.LOWERCASE_SCOPE_TOKENS */, apiVersion) &&
|
|
@@ -13007,20 +13007,10 @@ function isStaticNode(node, apiVersion) {
|
|
|
13007
13007
|
result &&= isElement(node);
|
|
13008
13008
|
// all attrs are static-safe
|
|
13009
13009
|
// the criteria to determine safety can be found in computeAttrValue
|
|
13010
|
-
result &&= attributes.every(({ name
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
!isSvgUseHref(nodeName, name, namespace) &&
|
|
13015
|
-
// Check for ScopedFragId
|
|
13016
|
-
!(isAllowedFragOnlyUrlsXHTML(nodeName, name, namespace) &&
|
|
13017
|
-
isFragmentOnlyUrl(value.value));
|
|
13018
|
-
const isStaticSafeExpression = isExpression$1(value) &&
|
|
13019
|
-
name !== 'slot' &&
|
|
13020
|
-
// TODO [#3624]: Revisit whether svgs can be included in static content optimization
|
|
13021
|
-
// svg href needs sanitization.
|
|
13022
|
-
!isSvgUseHref(nodeName, name, namespace);
|
|
13023
|
-
return isStaticSafeLiteral || isStaticSafeExpression;
|
|
13010
|
+
result &&= attributes.every(({ name }) => {
|
|
13011
|
+
// Slots are not safe because the VDOM handles them specially in synthetic shadow and light DOM mode
|
|
13012
|
+
// TODO [#4351]: `disableSyntheticShadowSupport` should allow slots to be static-optimized
|
|
13013
|
+
return name !== 'slot';
|
|
13024
13014
|
});
|
|
13025
13015
|
// all directives are static-safe
|
|
13026
13016
|
result &&= !directives.some((directive) => !STATIC_SAFE_DIRECTIVES.has(directive.name));
|
|
@@ -13158,7 +13148,7 @@ function serializeAttrs(element, codeGen) {
|
|
|
13158
13148
|
*/
|
|
13159
13149
|
const attrs = [];
|
|
13160
13150
|
let hasClassAttr = false;
|
|
13161
|
-
const collector = ({ name, value, hasExpression,
|
|
13151
|
+
const collector = ({ name, value, hasExpression, hasIdOrIdRef, hasSvgUseHref, hasScopedFragmentRef, }) => {
|
|
13162
13152
|
let v = typeof value === 'string' ? templateStringEscape(value) : value;
|
|
13163
13153
|
if (name === 'class') {
|
|
13164
13154
|
hasClassAttr = true;
|
|
@@ -13184,7 +13174,7 @@ function serializeAttrs(element, codeGen) {
|
|
|
13184
13174
|
// Note that, to maintain backwards compatibility with the non-static output, we treat the valueless
|
|
13185
13175
|
// "boolean" format (e.g. `<div id>`) as the empty string, which is semantically equivalent.
|
|
13186
13176
|
// TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
|
|
13187
|
-
const needsPlaceholder = hasExpression ||
|
|
13177
|
+
const needsPlaceholder = hasExpression || hasIdOrIdRef || hasSvgUseHref || hasScopedFragmentRef;
|
|
13188
13178
|
// Inject a placeholder where the staticPartId will go when an expression occurs.
|
|
13189
13179
|
// This is only needed for SSR to inject the expression value during serialization.
|
|
13190
13180
|
attrs.push(needsPlaceholder ? `\${"${v}"}` : ` ${name}="${shared.htmlEscape(v, true)}"`);
|
|
@@ -13200,13 +13190,22 @@ function serializeAttrs(element, codeGen) {
|
|
|
13200
13190
|
// IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
|
|
13201
13191
|
// Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
|
|
13202
13192
|
// TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
|
|
13203
|
-
const
|
|
13204
|
-
|
|
13193
|
+
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
|
+
// `<a href="#foo">` and `<area href="#foo">` must be dynamic due to synthetic shadow scoping
|
|
13197
|
+
// Note this only applies if there is an `id` attribute somewhere in the template
|
|
13198
|
+
const hasScopedFragmentRef = codeGen.scopeFragmentId &&
|
|
13199
|
+
isStringLiteral(value) &&
|
|
13200
|
+
isAllowedFragOnlyUrlsXHTML(element.name, name, element.namespace) &&
|
|
13201
|
+
isFragmentOnlyUrl(value.value);
|
|
13205
13202
|
return {
|
|
13206
13203
|
hasExpression,
|
|
13207
|
-
|
|
13204
|
+
hasIdOrIdRef,
|
|
13205
|
+
hasSvgUseHref,
|
|
13206
|
+
hasScopedFragmentRef,
|
|
13208
13207
|
name,
|
|
13209
|
-
value: hasExpression ||
|
|
13208
|
+
value: hasExpression || hasIdOrIdRef || hasSvgUseHref || hasScopedFragmentRef
|
|
13210
13209
|
? codeGen.getStaticExpressionToken(attr)
|
|
13211
13210
|
: value.value,
|
|
13212
13211
|
};
|
|
@@ -13462,16 +13461,21 @@ function bindAttributeExpression(attr, element, codeGen, addLegacySanitizationHo
|
|
|
13462
13461
|
return codeGen.genScopedFragId(expression);
|
|
13463
13462
|
}
|
|
13464
13463
|
if (isSvgUseHref(elmName, attrName, namespace)) {
|
|
13464
|
+
// Apply the fragment id scoping transformation if necessary.
|
|
13465
|
+
// This scoping can be skipped if the value is a string literal that doesn't start with a "#"
|
|
13466
|
+
const value = isStringLiteral(attrValue) && !isFragmentOnlyUrl(attrValue.value)
|
|
13467
|
+
? literal$1(attrValue.value)
|
|
13468
|
+
: codeGen.genScopedFragId(expression);
|
|
13465
13469
|
if (addLegacySanitizationHook) {
|
|
13466
13470
|
codeGen.usedLwcApis.add('sanitizeAttribute');
|
|
13467
13471
|
return callExpression(identifier('sanitizeAttribute'), [
|
|
13468
13472
|
literal$1(elmName),
|
|
13469
13473
|
literal$1(namespace),
|
|
13470
13474
|
literal$1(attrName),
|
|
13471
|
-
|
|
13475
|
+
value,
|
|
13472
13476
|
]);
|
|
13473
13477
|
}
|
|
13474
|
-
return
|
|
13478
|
+
return value;
|
|
13475
13479
|
}
|
|
13476
13480
|
return expression;
|
|
13477
13481
|
}
|
|
@@ -13628,7 +13632,7 @@ class CodeGen {
|
|
|
13628
13632
|
return classExpression;
|
|
13629
13633
|
}
|
|
13630
13634
|
genNormalizeClassName(className) {
|
|
13631
|
-
return this._renderApiCall(RENDER_APIS.normalizeClassName, [className]
|
|
13635
|
+
return this._renderApiCall(RENDER_APIS.normalizeClassName, [className]);
|
|
13632
13636
|
}
|
|
13633
13637
|
/**
|
|
13634
13638
|
* Generates childs vnodes when slot content is static.
|
|
@@ -13726,19 +13730,13 @@ class CodeGen {
|
|
|
13726
13730
|
// usage of the lwc:inner-html, and in an iteration, usages are dynamically generated.
|
|
13727
13731
|
return conditionalExpression(binaryExpression('!==', memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), identifier(`_rawHtml$${instance}`)), assignmentExpression('=', memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), identifier(`_rawHtml$${instance}`)), expr)), assignmentExpression('=', memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), identifier(`_sanitizedHtml$${instance}`)), this.genSanitizeHtmlContent(expr)), memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), identifier(`_sanitizedHtml$${instance}`)));
|
|
13728
13732
|
}
|
|
13729
|
-
_renderApiCall(primitive, params
|
|
13733
|
+
_renderApiCall(primitive, params) {
|
|
13730
13734
|
const { name, alias } = primitive;
|
|
13731
13735
|
let identifier$1 = this.usedApis[name];
|
|
13732
13736
|
if (!identifier$1) {
|
|
13733
13737
|
identifier$1 = this.usedApis[name] = identifier(alias);
|
|
13734
13738
|
}
|
|
13735
|
-
|
|
13736
|
-
// Check if the property actually exists before calling, to allow
|
|
13737
|
-
// for older engines to work with newer compilers
|
|
13738
|
-
// TODO [#4313]: remove temporary logic to support v7 compiler + v6 engine
|
|
13739
|
-
return fallbackForCompilerEngineVersionMismatch
|
|
13740
|
-
? conditionalExpression(identifier$1, callExpression$1, fallbackForCompilerEngineVersionMismatch)
|
|
13741
|
-
: callExpression$1;
|
|
13739
|
+
return callExpression(identifier$1, params);
|
|
13742
13740
|
}
|
|
13743
13741
|
beginScope() {
|
|
13744
13742
|
this.scope = this.createScope(this.scope);
|
|
@@ -13877,13 +13875,13 @@ class CodeGen {
|
|
|
13877
13875
|
};
|
|
13878
13876
|
// Depth-first traversal. We assign a partId to each element, which is an integer based on traversal order.
|
|
13879
13877
|
while (stack.length > 0) {
|
|
13880
|
-
const
|
|
13878
|
+
const currentNode = stack.shift();
|
|
13881
13879
|
// Skip comment nodes in parts count, as they will be stripped in production, unless when `lwc:preserve-comments` is enabled
|
|
13882
|
-
if (isContiguousText(
|
|
13880
|
+
if (isContiguousText(currentNode) || !isComment(currentNode) || this.preserveComments) {
|
|
13883
13881
|
partId++;
|
|
13884
13882
|
}
|
|
13885
|
-
if (isContiguousText(
|
|
13886
|
-
const textNodes =
|
|
13883
|
+
if (isContiguousText(currentNode)) {
|
|
13884
|
+
const textNodes = currentNode;
|
|
13887
13885
|
if (hasDynamicText(textNodes)) {
|
|
13888
13886
|
const partToken = `${"t" /* STATIC_PART_TOKEN_ID.TEXT */}${partId}`;
|
|
13889
13887
|
// Use the first text node as the key.
|
|
@@ -13893,30 +13891,38 @@ class CodeGen {
|
|
|
13893
13891
|
setPartIdText(concatenatedText);
|
|
13894
13892
|
}
|
|
13895
13893
|
}
|
|
13896
|
-
else if (isElement(
|
|
13897
|
-
const elm = current;
|
|
13894
|
+
else if (isElement(currentNode)) {
|
|
13898
13895
|
const databag = [];
|
|
13899
13896
|
// has event listeners
|
|
13900
|
-
if (
|
|
13901
|
-
databag.push(this.genEventListeners(
|
|
13897
|
+
if (currentNode.listeners.length) {
|
|
13898
|
+
databag.push(this.genEventListeners(currentNode.listeners));
|
|
13902
13899
|
}
|
|
13903
13900
|
// See STATIC_SAFE_DIRECTIVES for what's allowed here.
|
|
13904
13901
|
// Also note that we don't generate the 'key' here, because we only support it at the top level
|
|
13905
13902
|
// directly passed into the `api_static_fragment` function, not as a part.
|
|
13906
|
-
for (const directive of
|
|
13903
|
+
for (const directive of currentNode.directives) {
|
|
13907
13904
|
if (directive.name === 'Ref') {
|
|
13908
13905
|
databag.push(this.genRef(directive));
|
|
13909
13906
|
}
|
|
13910
13907
|
}
|
|
13911
13908
|
const attributeExpressions = [];
|
|
13912
|
-
for (const attribute of
|
|
13909
|
+
for (const attribute of currentNode.attributes) {
|
|
13913
13910
|
const { name, value } = attribute;
|
|
13914
13911
|
// IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
|
|
13915
13912
|
// Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
|
|
13916
13913
|
// TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
|
|
13917
13914
|
const isIdOrIdRef = (name === 'id' || isIdReferencingAttribute(name)) &&
|
|
13918
|
-
(
|
|
13919
|
-
|
|
13915
|
+
!isBooleanLiteral(value);
|
|
13916
|
+
// For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
|
|
13917
|
+
const isSvgHref = isSvgUseHref(currentNode.name, name, currentNode.namespace) &&
|
|
13918
|
+
!isBooleanLiteral(value);
|
|
13919
|
+
// `<a href="#foo">` and `<area href="#foo">` must be dynamic due to synthetic shadow scoping
|
|
13920
|
+
// Note this only applies if there is an `id` attribute somewhere in the template
|
|
13921
|
+
const isScopedFragmentRef = this.scopeFragmentId &&
|
|
13922
|
+
isStringLiteral(value) &&
|
|
13923
|
+
isAllowedFragOnlyUrlsXHTML(currentNode.name, name, currentNode.namespace) &&
|
|
13924
|
+
isFragmentOnlyUrl(value.value);
|
|
13925
|
+
if (isExpression$1(value) || isIdOrIdRef || isSvgHref || isScopedFragmentRef) {
|
|
13920
13926
|
let partToken = '';
|
|
13921
13927
|
if (name === 'style') {
|
|
13922
13928
|
partToken = `${"s" /* STATIC_PART_TOKEN_ID.STYLE */}${partId}`;
|
|
@@ -13927,9 +13933,12 @@ class CodeGen {
|
|
|
13927
13933
|
databag.push(property$1(identifier('className'), this.genClassExpression(value)));
|
|
13928
13934
|
}
|
|
13929
13935
|
else {
|
|
13930
|
-
// non-class, non-style (i.e. generic attribute or ID/IDRef)
|
|
13936
|
+
// non-class, non-style (i.e. generic attribute or ID/IDRef or svg use href)
|
|
13931
13937
|
partToken = `${"a" /* STATIC_PART_TOKEN_ID.ATTRIBUTE */}${partId}:${name}`;
|
|
13932
|
-
attributeExpressions.push(property$1(literal$1(name), bindAttributeExpression(attribute,
|
|
13938
|
+
attributeExpressions.push(property$1(literal$1(name), bindAttributeExpression(attribute, currentNode, this,
|
|
13939
|
+
// `addLegacySanitizationHook` is true because `isCustomRendererHookRequired`
|
|
13940
|
+
// being false is a precondition for static nodes.
|
|
13941
|
+
true)));
|
|
13933
13942
|
}
|
|
13934
13943
|
this.staticExpressionMap.set(attribute, partToken);
|
|
13935
13944
|
}
|
|
@@ -13943,7 +13952,7 @@ class CodeGen {
|
|
|
13943
13952
|
// For depth-first traversal, children must be prepended in order, so that they are processed before
|
|
13944
13953
|
// siblings. Note that this is consistent with the order used in the diffing algo as well as
|
|
13945
13954
|
// `traverseAndSetElements` in @lwc/engine-core.
|
|
13946
|
-
stack.unshift(...transformStaticChildren(
|
|
13955
|
+
stack.unshift(...transformStaticChildren(currentNode, this.preserveComments));
|
|
13947
13956
|
}
|
|
13948
13957
|
}
|
|
13949
13958
|
if (partIdsToArgs.size === 0) {
|
|
@@ -14447,7 +14456,8 @@ function transform(codeGen) {
|
|
|
14447
14456
|
return codeGen.genScopedFragId(attrValue.value);
|
|
14448
14457
|
}
|
|
14449
14458
|
if (isSvgUseHref(elmName, attrName, namespace)) {
|
|
14450
|
-
//
|
|
14459
|
+
// Apply the fragment id scoping transformation if necessary.
|
|
14460
|
+
// This scoping can be skipped if the value is a string literal that doesn't start with a "#"
|
|
14451
14461
|
const value = isFragmentOnlyUrl(attrValue.value)
|
|
14452
14462
|
? codeGen.genScopedFragId(attrValue.value)
|
|
14453
14463
|
: literal$1(attrValue.value);
|
|
@@ -14696,5 +14706,5 @@ exports.default = compile;
|
|
|
14696
14706
|
exports.kebabcaseToCamelcase = kebabcaseToCamelcase;
|
|
14697
14707
|
exports.parse = parse;
|
|
14698
14708
|
exports.toPropertyName = toPropertyName;
|
|
14699
|
-
/** version: 7.0.
|
|
14709
|
+
/** version: 7.0.5 */
|
|
14700
14710
|
//# sourceMappingURL=index.cjs.js.map
|