@lwc/template-compiler 7.2.0 → 7.2.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/index.js CHANGED
@@ -186,6 +186,7 @@ const AVAILABLE_OPTION_NAMES = new Set([
186
186
  'instrumentation',
187
187
  'namespace',
188
188
  'name',
189
+ 'disableSyntheticShadowSupport',
189
190
  ]);
190
191
  function normalizeCustomRendererConfig(config) {
191
192
  const tagNames = [];
@@ -237,6 +238,7 @@ function normalizeConfig(config) {
237
238
  enableDynamicComponents: false,
238
239
  enableStaticContentOptimization: true,
239
240
  enableLwcSpread: true,
241
+ disableSyntheticShadowSupport: false,
240
242
  ...config,
241
243
  apiVersion, // overrides the config apiVersion
242
244
  ...{ customRendererConfig },
@@ -11901,7 +11903,7 @@ function getTemplateRoot(ctx, documentFragment) {
11901
11903
  (isTextNode$1(child) && child.value.trim().length));
11902
11904
  if (validRoots.length > 1) {
11903
11905
  const duplicateRoot = validRoots[1].sourceCodeLocation ?? undefined;
11904
- ctx.throw(ParserDiagnostics.MULTIPLE_ROOTS_FOUND, [], duplicateRoot ? sourceLocation(duplicateRoot) : duplicateRoot ?? undefined);
11906
+ ctx.throw(ParserDiagnostics.MULTIPLE_ROOTS_FOUND, [], duplicateRoot ? sourceLocation(duplicateRoot) : (duplicateRoot ?? undefined));
11905
11907
  }
11906
11908
  const [root] = validRoots;
11907
11909
  if (!root || !isElementNode(root)) {
@@ -13124,7 +13126,7 @@ function serializeAttrs(element, codeGen) {
13124
13126
  */
13125
13127
  const attrs = [];
13126
13128
  let hasClassAttr = false;
13127
- const collector = ({ name, value, hasExpression, hasIdOrIdRef, hasSvgUseHref, hasScopedFragmentRef, }) => {
13129
+ const collector = ({ name, value, hasExpression, hasSvgUseHref, needsScoping, }) => {
13128
13130
  let v = typeof value === 'string' ? templateStringEscape(value) : value;
13129
13131
  if (name === 'class') {
13130
13132
  hasClassAttr = true;
@@ -13149,8 +13151,7 @@ function serializeAttrs(element, codeGen) {
13149
13151
  // Skip serializing here and handle it as if it were a dynamic attribute instead.
13150
13152
  // Note that, to maintain backwards compatibility with the non-static output, we treat the valueless
13151
13153
  // "boolean" format (e.g. `<div id>`) as the empty string, which is semantically equivalent.
13152
- // TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
13153
- const needsPlaceholder = hasExpression || hasIdOrIdRef || hasSvgUseHref || hasScopedFragmentRef;
13154
+ const needsPlaceholder = hasExpression || hasSvgUseHref || needsScoping;
13154
13155
  // Inject a placeholder where the staticPartId will go when an expression occurs.
13155
13156
  // This is only needed for SSR to inject the expression value during serialization.
13156
13157
  attrs.push(needsPlaceholder ? `\${"${v}"}` : ` ${name}="${htmlEscape(v, true)}"`);
@@ -13163,25 +13164,26 @@ function serializeAttrs(element, codeGen) {
13163
13164
  .map((attr) => {
13164
13165
  const { name, value } = attr;
13165
13166
  const hasExpression = isExpression$1(value);
13167
+ // For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
13168
+ const hasSvgUseHref = isSvgUseHref(element.name, name, element.namespace) && !isBooleanLiteral(value);
13166
13169
  // IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
13167
13170
  // Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
13168
- // TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
13169
13171
  const hasIdOrIdRef = (name === 'id' || isIdReferencingAttribute(name)) && !isBooleanLiteral(value);
13170
- // For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
13171
- const hasSvgUseHref = isSvgUseHref(element.name, name, element.namespace) && !isBooleanLiteral(value);
13172
13172
  // `<a href="#foo">` and `<area href="#foo">` must be dynamic due to synthetic shadow scoping
13173
13173
  // Note this only applies if there is an `id` attribute somewhere in the template
13174
13174
  const hasScopedFragmentRef = codeGen.scopeFragmentId &&
13175
13175
  isStringLiteral(value) &&
13176
13176
  isAllowedFragOnlyUrlsXHTML(element.name, name, element.namespace) &&
13177
13177
  isFragmentOnlyUrl(value.value);
13178
+ // If we're not running in synthetic shadow mode (light or shadow+disableSyntheticShadowSupport),
13179
+ // then static IDs/IDrefs/fragment refs will be rendered directly into HTML strings.
13180
+ const needsScoping = codeGen.isSyntheticShadow && (hasIdOrIdRef || hasScopedFragmentRef);
13178
13181
  return {
13179
13182
  hasExpression,
13180
- hasIdOrIdRef,
13181
13183
  hasSvgUseHref,
13182
- hasScopedFragmentRef,
13184
+ needsScoping,
13183
13185
  name,
13184
- value: hasExpression || hasIdOrIdRef || hasSvgUseHref || hasScopedFragmentRef
13186
+ value: hasExpression || hasSvgUseHref || needsScoping
13185
13187
  ? codeGen.getStaticExpressionToken(attr)
13186
13188
  : value.value,
13187
13189
  };
@@ -13520,6 +13522,9 @@ class CodeGen {
13520
13522
  this.scope = this.createScope();
13521
13523
  this.state = state;
13522
13524
  this.apiVersion = getAPIVersionFromNumber(state.config.apiVersion);
13525
+ this.isSyntheticShadow =
13526
+ this.renderMode !== LWCDirectiveRenderMode.light &&
13527
+ !this.state.config.disableSyntheticShadowSupport;
13523
13528
  }
13524
13529
  generateKey() {
13525
13530
  return this.currentKey++;
@@ -13588,16 +13593,14 @@ class CodeGen {
13588
13593
  return this._renderApiCall(RENDER_APIS.flatten, children);
13589
13594
  }
13590
13595
  genScopedId(id) {
13591
- if (typeof id === 'string') {
13592
- return this._renderApiCall(RENDER_APIS.scopedId, [literal$1(id)]);
13593
- }
13594
- return this._renderApiCall(RENDER_APIS.scopedId, [id]);
13596
+ const value = typeof id === 'string' ? literal$1(id) : id;
13597
+ return this.isSyntheticShadow ? this._renderApiCall(RENDER_APIS.scopedId, [value]) : value;
13595
13598
  }
13596
13599
  genScopedFragId(id) {
13597
- if (typeof id === 'string') {
13598
- return this._renderApiCall(RENDER_APIS.scopedFragId, [literal$1(id)]);
13599
- }
13600
- return this._renderApiCall(RENDER_APIS.scopedFragId, [id]);
13600
+ const value = typeof id === 'string' ? literal$1(id) : id;
13601
+ return this.isSyntheticShadow
13602
+ ? this._renderApiCall(RENDER_APIS.scopedFragId, [value])
13603
+ : value;
13601
13604
  }
13602
13605
  genClassExpression(value) {
13603
13606
  let classExpression = this.bindExpression(value);
@@ -13886,7 +13889,6 @@ class CodeGen {
13886
13889
  const { name, value } = attribute;
13887
13890
  // IDs/IDRefs must be handled dynamically at runtime due to synthetic shadow scoping.
13888
13891
  // Note that for backwards compat we only consider non-booleans to be dynamic IDs/IDRefs
13889
- // TODO [#3658]: `disableSyntheticShadowSupport` should also disable this dynamic behavior
13890
13892
  const isIdOrIdRef = (name === 'id' || isIdReferencingAttribute(name)) &&
13891
13893
  !isBooleanLiteral(value);
13892
13894
  // For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
@@ -13898,7 +13900,10 @@ class CodeGen {
13898
13900
  isStringLiteral(value) &&
13899
13901
  isAllowedFragOnlyUrlsXHTML(currentNode.name, name, currentNode.namespace) &&
13900
13902
  isFragmentOnlyUrl(value.value);
13901
- if (isExpression$1(value) || isIdOrIdRef || isSvgHref || isScopedFragmentRef) {
13903
+ // If we're not running in synthetic shadow mode (light or shadow+disableSyntheticShadowSupport),
13904
+ // then static IDs/IDrefs/fragment refs will be rendered directly into HTML strings.
13905
+ const needsScoping = this.isSyntheticShadow && (isIdOrIdRef || isScopedFragmentRef);
13906
+ if (isExpression$1(value) || isSvgHref || needsScoping) {
13902
13907
  let partToken = '';
13903
13908
  if (name === 'style') {
13904
13909
  partToken = `${"s" /* STATIC_PART_TOKEN_ID.STYLE */}${partId}`;
@@ -14678,5 +14683,5 @@ function compile(source, filename, config) {
14678
14683
  }
14679
14684
 
14680
14685
  export { ElementDirectiveName, LWCDirectiveDomMode, LWCDirectiveRenderMode, LwcTagName, RootDirectiveName, TemplateDirectiveName, compile, compile as default, kebabcaseToCamelcase, parse, toPropertyName };
14681
- /** version: 7.2.0 */
14686
+ /** version: 7.2.2 */
14682
14687
  //# sourceMappingURL=index.js.map