@lwc/engine-core 2.35.2 → 2.36.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.
@@ -33,7 +33,6 @@ if (process.env.NODE_ENV === 'test-karma-lwc') {
33
33
  * SPDX-License-Identifier: MIT
34
34
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
35
35
  */
36
- /** Callbacks to invoke when reporting is enabled **/
37
36
  const onReportingEnabledCallbacks = [];
38
37
  /** The currently assigned reporting dispatcher. */
39
38
  let currentDispatcher$1 = shared.noop;
@@ -91,11 +90,11 @@ function onReportingEnabled(callback) {
91
90
  /**
92
91
  * Report to the current dispatcher, if there is one.
93
92
  * @param reportingEventId
94
- * @param vm
93
+ * @param payload - data to report
95
94
  */
96
- function report(reportingEventId, vm) {
95
+ function report(reportingEventId, payload) {
97
96
  if (enabled$1) {
98
- currentDispatcher$1(reportingEventId, vm.tagName, vm.idx);
97
+ currentDispatcher$1(reportingEventId, payload);
99
98
  }
100
99
  }
101
100
 
@@ -384,7 +383,7 @@ function parseStyleText(cssText) {
384
383
  // Make a shallow copy of an object but omit the given key
385
384
  function cloneAndOmitKey(object, keyToOmit) {
386
385
  const result = {};
387
- for (const key of Object.keys(object)) {
386
+ for (const key of shared.keys(object)) {
388
387
  if (key !== keyToOmit) {
389
388
  result[key] = object[key];
390
389
  }
@@ -394,7 +393,7 @@ function cloneAndOmitKey(object, keyToOmit) {
394
393
  function flattenStylesheets(stylesheets) {
395
394
  const list = [];
396
395
  for (const stylesheet of stylesheets) {
397
- if (!Array.isArray(stylesheet)) {
396
+ if (!shared.isArray(stylesheet)) {
398
397
  list.push(stylesheet);
399
398
  }
400
399
  else {
@@ -2673,6 +2672,10 @@ function checkVersionMismatch(func, type) {
2673
2672
  // stylesheets and templates do not have user-meaningful names, but components do
2674
2673
  const friendlyName = type === 'component' ? `${type} ${func.name}` : type;
2675
2674
  logError(`LWC WARNING: current engine is v${shared.LWC_VERSION}, but ${friendlyName} was compiled with v${version}.\nPlease update your compiled code or LWC engine so that the versions match.\nNo further warnings will appear.`);
2675
+ report(1 /* ReportingEventId.CompilerRuntimeVersionMismatch */, {
2676
+ compilerVersion: version,
2677
+ runtimeVersion: shared.LWC_VERSION,
2678
+ });
2676
2679
  }
2677
2680
  }
2678
2681
  }
@@ -4412,7 +4415,12 @@ function allocateInSlot(vm, children, owner) {
4412
4415
  } else if (isVScopedSlotFragment(vnode)) {
4413
4416
  slotName = vnode.slotName;
4414
4417
  }
4415
- const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
4418
+ // Can't use toString here because Symbol(1).toString() is 'Symbol(1)'
4419
+ // but elm.setAttribute('slot', Symbol(1)) is an error.
4420
+ // the following line also throws same error for symbols
4421
+ // Similar for Object.create(null)
4422
+ const normalizedSlotName = '' + slotName;
4423
+ const vnodes = cmpSlotsMapping[normalizedSlotName] = cmpSlotsMapping[normalizedSlotName] || [];
4416
4424
  shared.ArrayPush.call(vnodes, vnode);
4417
4425
  }
4418
4426
  vm.cmpSlots = {
@@ -5478,6 +5486,8 @@ function registerComponent(
5478
5486
  Ctor, { tmpl }) {
5479
5487
  if (shared.isFunction(Ctor)) {
5480
5488
  if (process.env.NODE_ENV !== 'production') {
5489
+ // There is no point in running this in production, because the version mismatch check relies
5490
+ // on code comments which are stripped out in production by minifiers
5481
5491
  checkVersionMismatch(Ctor, 'component');
5482
5492
  }
5483
5493
  signedTemplateMap.set(Ctor, tmpl);
@@ -5743,6 +5753,7 @@ function validateComponentStylesheets(vm, stylesheets) {
5743
5753
  // Validate and flatten any stylesheets defined as `static stylesheets`
5744
5754
  function computeStylesheets(vm, ctor) {
5745
5755
  if (features.lwcRuntimeFlags.ENABLE_PROGRAMMATIC_STYLESHEETS) {
5756
+ warnOnStylesheetsMutation(ctor);
5746
5757
  const {
5747
5758
  stylesheets
5748
5759
  } = ctor;
@@ -5757,6 +5768,24 @@ function computeStylesheets(vm, ctor) {
5757
5768
  }
5758
5769
  return null;
5759
5770
  }
5771
+ function warnOnStylesheetsMutation(ctor) {
5772
+ if (process.env.NODE_ENV !== 'production') {
5773
+ let {
5774
+ stylesheets
5775
+ } = ctor;
5776
+ shared.defineProperty(ctor, 'stylesheets', {
5777
+ enumerable: true,
5778
+ configurable: true,
5779
+ get() {
5780
+ return stylesheets;
5781
+ },
5782
+ set(newValue) {
5783
+ logWarnOnce(`Dynamically setting the "stylesheets" static property on ${ctor.name} ` + 'will not affect the stylesheets injected.');
5784
+ stylesheets = newValue;
5785
+ }
5786
+ });
5787
+ }
5788
+ }
5760
5789
  function computeShadowMode(vm, renderer) {
5761
5790
  const {
5762
5791
  def
@@ -6139,7 +6168,7 @@ const querySelectorAll = shared.globalThis[shared.KEY__NATIVE_QUERY_SELECTOR_ALL
6139
6168
  function isSyntheticShadowRootInstance(rootNode) {
6140
6169
  return rootNode !== document && shared.isTrue(rootNode.synthetic);
6141
6170
  }
6142
- function reportViolation(source, target, attrName) {
6171
+ function reportViolation$1(source, target, attrName) {
6143
6172
  // The vm is either for the source, the target, or both. Either one or both must be using synthetic
6144
6173
  // shadow for a violation to be detected.
6145
6174
  let vm = getAssociatedVMIfPresent(source.getRootNode().host);
@@ -6150,7 +6179,10 @@ function reportViolation(source, target, attrName) {
6150
6179
  // vm should never be undefined here, but just to be safe, bail out and don't report
6151
6180
  return;
6152
6181
  }
6153
- report(0 /* ReportingEventId.CrossRootAriaInSyntheticShadow */, vm);
6182
+ report(0 /* ReportingEventId.CrossRootAriaInSyntheticShadow */, {
6183
+ tagName: vm.tagName,
6184
+ attributeName: attrName,
6185
+ });
6154
6186
  if (process.env.NODE_ENV !== 'production') {
6155
6187
  // Avoid excessively logging to the console in the case of duplicates.
6156
6188
  logWarnOnce(`Element <${source.tagName.toLowerCase()}> uses attribute "${attrName}" to reference element ` +
@@ -6182,7 +6214,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6182
6214
  const sourceElement = sourceElements[i];
6183
6215
  const sourceRoot = sourceElement.getRootNode();
6184
6216
  if (sourceRoot !== root) {
6185
- reportViolation(sourceElement, elm, idRefAttrName);
6217
+ reportViolation$1(sourceElement, elm, idRefAttrName);
6186
6218
  break;
6187
6219
  }
6188
6220
  }
@@ -6197,7 +6229,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6197
6229
  const targetRoot = target.getRootNode();
6198
6230
  if (targetRoot !== root) {
6199
6231
  // target element's shadow root is not the same as ours
6200
- reportViolation(elm, target, attrName);
6232
+ reportViolation$1(elm, target, attrName);
6201
6233
  }
6202
6234
  }
6203
6235
  }
@@ -6206,7 +6238,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6206
6238
  let enabled = false;
6207
6239
  // We want to avoid patching globals whenever possible, so this should be tree-shaken out in prod-mode and if
6208
6240
  // reporting is not enabled. It should also only run once
6209
- function enableDetection() {
6241
+ function enableDetection$1() {
6210
6242
  if (enabled) {
6211
6243
  return; // don't double-apply the patches
6212
6244
  }
@@ -6258,14 +6290,112 @@ function isSyntheticShadowLoaded() {
6258
6290
  if (process.env.IS_BROWSER && supportsCssEscape() && isSyntheticShadowLoaded()) {
6259
6291
  // Always run detection in dev mode, so we can at least print to the console
6260
6292
  if (process.env.NODE_ENV !== 'production') {
6261
- enableDetection();
6293
+ enableDetection$1();
6262
6294
  }
6263
6295
  else {
6264
6296
  // In prod mode, only enable detection if reporting is enabled
6265
- onReportingEnabled(enableDetection);
6297
+ onReportingEnabled(enableDetection$1);
6266
6298
  }
6267
6299
  }
6268
6300
 
6301
+ /*
6302
+ * Copyright (c) 2018, salesforce.com, inc.
6303
+ * All rights reserved.
6304
+ * SPDX-License-Identifier: MIT
6305
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6306
+ */
6307
+ //
6308
+ // The goal of this code is to detect usages of non-standard reflected ARIA properties. These are caused by
6309
+ // legacy non-standard Element.prototype extensions added by the @lwc/aria-reflection package.
6310
+ //
6311
+ // See the README for @lwc/aria-reflection
6312
+ const NON_STANDARD_ARIA_PROPS = ['ariaActiveDescendant', 'ariaControls', 'ariaDescribedBy', 'ariaDetails', 'ariaErrorMessage', 'ariaFlowTo', 'ariaLabelledBy', 'ariaOwns'];
6313
+ function isLightningElement(elm) {
6314
+ // The former case is for `this.prop` (inside component) and the latter is for `element.prop` (outside component).
6315
+ // In both cases, we apply the non-standard prop even when the global polyfill is disabled, so this is kosher.
6316
+ return elm instanceof LightningElement || elm instanceof BaseBridgeElement;
6317
+ }
6318
+ function findVM(elm) {
6319
+ // If it's a shadow DOM component, then it has a host
6320
+ const {
6321
+ host
6322
+ } = elm.getRootNode();
6323
+ const vm = shared.isUndefined(host) ? undefined : getAssociatedVMIfPresent(host);
6324
+ if (!shared.isUndefined(vm)) {
6325
+ return vm;
6326
+ }
6327
+ // Else it might be a light DOM component. Walk up the tree trying to find the owner
6328
+ let parentElement = elm;
6329
+ while (!shared.isNull(parentElement = parentElement.parentElement)) {
6330
+ if (isLightningElement(parentElement)) {
6331
+ const vm = getAssociatedVMIfPresent(parentElement);
6332
+ if (!shared.isUndefined(vm)) {
6333
+ return vm;
6334
+ }
6335
+ }
6336
+ }
6337
+ // If we return undefined, it's because the element was rendered wholly outside a LightningElement
6338
+ }
6339
+
6340
+ function checkAndReportViolation(elm, prop) {
6341
+ if (!isLightningElement(elm)) {
6342
+ const vm = findVM(elm);
6343
+ if (process.env.NODE_ENV !== 'production') {
6344
+ logWarnOnce(`Element <${elm.tagName.toLowerCase()}> ` + (shared.isUndefined(vm) ? '' : `owned by <${vm.elm.tagName.toLowerCase()}> `) + `uses non-standard property "${prop}". This will be removed in a future version of LWC. ` + `See https://lwc.dev/guide/accessibility#deprecated-aria-reflected-properties`);
6345
+ }
6346
+ report(2 /* ReportingEventId.NonStandardAriaReflection */, {
6347
+ tagName: vm === null || vm === void 0 ? void 0 : vm.tagName,
6348
+ propertyName: prop
6349
+ });
6350
+ }
6351
+ }
6352
+ function enableDetection() {
6353
+ const {
6354
+ prototype
6355
+ } = Element;
6356
+ for (const prop of NON_STANDARD_ARIA_PROPS) {
6357
+ const descriptor = shared.getOwnPropertyDescriptor(prototype, prop);
6358
+ // The descriptor should exist because the @lwc/aria-reflection polyfill has run by now.
6359
+ // This happens automatically because of the ordering of imports.
6360
+ if (process.env.NODE_ENV !== 'production') {
6361
+ /* istanbul ignore if */
6362
+ if (shared.isUndefined(descriptor) || shared.isUndefined(descriptor.get) || shared.isUndefined(descriptor.set)) {
6363
+ // should never happen
6364
+ throw new Error('detect-non-standard-aria.ts loaded before @lwc/aria-reflection');
6365
+ }
6366
+ }
6367
+ // @ts-ignore
6368
+ const {
6369
+ get,
6370
+ set
6371
+ } = descriptor;
6372
+ shared.defineProperty(prototype, prop, {
6373
+ get() {
6374
+ checkAndReportViolation(this, prop);
6375
+ return get.call(this);
6376
+ },
6377
+ set(val) {
6378
+ checkAndReportViolation(this, prop);
6379
+ return set.call(this, val);
6380
+ },
6381
+ configurable: true,
6382
+ enumerable: true
6383
+ });
6384
+ }
6385
+ }
6386
+ // No point in running this code if we're not in a browser, or if the global polyfill is not loaded
6387
+ if (process.env.IS_BROWSER) {
6388
+ if (!features.lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
6389
+ // Always run detection in dev mode, so we can at least print to the console
6390
+ if (process.env.NODE_ENV !== 'production') {
6391
+ enableDetection();
6392
+ } else {
6393
+ // In prod mode, only enable detection if reporting is enabled
6394
+ onReportingEnabled(enableDetection);
6395
+ }
6396
+ }
6397
+ }
6398
+
6269
6399
  /*
6270
6400
  * Copyright (c) 2018, salesforce.com, inc.
6271
6401
  * All rights reserved.
@@ -6750,12 +6880,13 @@ function setHooks(hooks) {
6750
6880
  */
6751
6881
  // See @lwc/engine-core/src/framework/template.ts
6752
6882
  const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6753
- // Via https://www.npmjs.com/package/object-observer
6754
- const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6755
6883
  // Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
6756
- const STYLESHEET_FUNCTION_EXPANDOS = [
6884
+ const STYLESHEET_PROPS = [
6757
6885
  // SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
6758
6886
  '$scoped$'];
6887
+ // Via https://www.npmjs.com/package/object-observer
6888
+ const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6889
+ let mutationTrackingDisabled = false;
6759
6890
  function getOriginalArrayMethod(prop) {
6760
6891
  switch (prop) {
6761
6892
  case 'pop':
@@ -6778,7 +6909,20 @@ function getOriginalArrayMethod(prop) {
6778
6909
  return shared.ArrayCopyWithin;
6779
6910
  }
6780
6911
  }
6781
- let mutationWarningsSilenced = false;
6912
+ function reportViolation(type, eventId, prop) {
6913
+ if (process.env.NODE_ENV !== 'production') {
6914
+ logWarnOnce(`Mutating the "${prop}" property on a ${type} ` + `is deprecated and will be removed in a future version of LWC. ` + `See: https://lwc.dev/guide/css#deprecated-template-mutation`);
6915
+ }
6916
+ report(eventId, {
6917
+ propertyName: prop
6918
+ });
6919
+ }
6920
+ function reportTemplateViolation(prop) {
6921
+ reportViolation('template', 3 /* ReportingEventId.TemplateMutation */, prop);
6922
+ }
6923
+ function reportStylesheetViolation(prop) {
6924
+ reportViolation('stylesheet', 4 /* ReportingEventId.StylesheetMutation */, prop);
6925
+ }
6782
6926
  // Warn if the user tries to mutate a stylesheets array, e.g.:
6783
6927
  // `tmpl.stylesheets.push(someStylesheetFunction)`
6784
6928
  function warnOnArrayMutation(stylesheets) {
@@ -6787,7 +6931,7 @@ function warnOnArrayMutation(stylesheets) {
6787
6931
  for (const prop of ARRAY_MUTATION_METHODS) {
6788
6932
  const originalArrayMethod = getOriginalArrayMethod(prop);
6789
6933
  stylesheets[prop] = function arrayMutationWarningWrapper() {
6790
- logError(`Mutating the "stylesheets" array on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6934
+ reportTemplateViolation('stylesheets');
6791
6935
  // @ts-ignore
6792
6936
  return originalArrayMethod.apply(this, arguments);
6793
6937
  };
@@ -6796,8 +6940,7 @@ function warnOnArrayMutation(stylesheets) {
6796
6940
  // Warn if the user tries to mutate a stylesheet factory function, e.g.:
6797
6941
  // `stylesheet.$scoped$ = true`
6798
6942
  function warnOnStylesheetFunctionMutation(stylesheet) {
6799
- // We could warn on other properties, but in practice only certain expandos are meaningful to LWC at runtime
6800
- for (const prop of STYLESHEET_FUNCTION_EXPANDOS) {
6943
+ for (const prop of STYLESHEET_PROPS) {
6801
6944
  let value = stylesheet[prop];
6802
6945
  shared.defineProperty(stylesheet, prop, {
6803
6946
  enumerable: true,
@@ -6806,14 +6949,14 @@ function warnOnStylesheetFunctionMutation(stylesheet) {
6806
6949
  return value;
6807
6950
  },
6808
6951
  set(newValue) {
6809
- logError(`Dynamically setting the "${prop}" property on a stylesheet function ` + `is deprecated and may be removed in a future version of LWC.`);
6952
+ reportStylesheetViolation(prop);
6810
6953
  value = newValue;
6811
6954
  }
6812
6955
  });
6813
6956
  }
6814
6957
  }
6815
6958
  // Warn on either array or stylesheet (function) mutation, in a deeply-nested array
6816
- function warnOnStylesheetsMutation(stylesheets) {
6959
+ function trackStylesheetsMutation(stylesheets) {
6817
6960
  traverseStylesheets(stylesheets, subStylesheets => {
6818
6961
  if (shared.isArray(subStylesheets)) {
6819
6962
  warnOnArrayMutation(subStylesheets);
@@ -6840,7 +6983,70 @@ function traverseStylesheets(stylesheets, callback) {
6840
6983
  }
6841
6984
  }
6842
6985
  }
6986
+ function trackMutations(tmpl) {
6987
+ if (!shared.isUndefined(tmpl.stylesheets)) {
6988
+ trackStylesheetsMutation(tmpl.stylesheets);
6989
+ }
6990
+ for (const prop of TEMPLATE_PROPS) {
6991
+ let value = tmpl[prop];
6992
+ shared.defineProperty(tmpl, prop, {
6993
+ enumerable: true,
6994
+ configurable: true,
6995
+ get() {
6996
+ return value;
6997
+ },
6998
+ set(newValue) {
6999
+ if (!mutationTrackingDisabled) {
7000
+ reportTemplateViolation(prop);
7001
+ }
7002
+ value = newValue;
7003
+ }
7004
+ });
7005
+ }
7006
+ const originalDescriptor = shared.getOwnPropertyDescriptor(tmpl, 'stylesheetTokens');
7007
+ shared.defineProperty(tmpl, 'stylesheetTokens', {
7008
+ enumerable: true,
7009
+ configurable: true,
7010
+ get: originalDescriptor.get,
7011
+ set(value) {
7012
+ reportTemplateViolation('stylesheetTokens');
7013
+ // Avoid logging/reporting twice (for both stylesheetToken and stylesheetTokens)
7014
+ mutationTrackingDisabled = true;
7015
+ originalDescriptor.set.call(this, value);
7016
+ mutationTrackingDisabled = false;
7017
+ }
7018
+ });
7019
+ }
7020
+ function addLegacyStylesheetTokensShim(tmpl) {
7021
+ // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
7022
+ // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
7023
+ shared.defineProperty(tmpl, 'stylesheetTokens', {
7024
+ enumerable: true,
7025
+ configurable: true,
7026
+ get() {
7027
+ const {
7028
+ stylesheetToken
7029
+ } = this;
7030
+ if (shared.isUndefined(stylesheetToken)) {
7031
+ return stylesheetToken;
7032
+ }
7033
+ // Shim for the old `stylesheetTokens` property
7034
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
7035
+ return {
7036
+ hostAttribute: `${stylesheetToken}-host`,
7037
+ shadowAttribute: stylesheetToken
7038
+ };
7039
+ },
7040
+ set(value) {
7041
+ // If the value is null or some other exotic object, you would be broken anyway in the past
7042
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
7043
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
7044
+ this.stylesheetToken = shared.isUndefined(value) ? undefined : value.shadowAttribute;
7045
+ }
7046
+ });
7047
+ }
6843
7048
  function freezeTemplate(tmpl) {
7049
+ // TODO [#2782]: remove this flag and delete the legacy behavior
6844
7050
  if (features.lwcRuntimeFlags.ENABLE_FROZEN_TEMPLATE) {
6845
7051
  // Deep freeze the template
6846
7052
  shared.freeze(tmpl);
@@ -6848,66 +7054,16 @@ function freezeTemplate(tmpl) {
6848
7054
  deepFreeze(tmpl.stylesheets);
6849
7055
  }
6850
7056
  } else {
6851
- // TODO [#2782]: remove this flag and delete the legacy behavior
6852
- // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6853
- // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
6854
- shared.defineProperty(tmpl, 'stylesheetTokens', {
6855
- enumerable: true,
6856
- configurable: true,
6857
- get() {
6858
- const {
6859
- stylesheetToken
6860
- } = this;
6861
- if (shared.isUndefined(stylesheetToken)) {
6862
- return stylesheetToken;
6863
- }
6864
- // Shim for the old `stylesheetTokens` property
6865
- // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
6866
- return {
6867
- hostAttribute: `${stylesheetToken}-host`,
6868
- shadowAttribute: stylesheetToken
6869
- };
6870
- },
6871
- set(value) {
6872
- // If the value is null or some other exotic object, you would be broken anyway in the past
6873
- // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
6874
- // However it may be undefined in newer versions of LWC, so we need to guard against that case.
6875
- this.stylesheetToken = shared.isUndefined(value) ? undefined : value.shadowAttribute;
6876
- }
6877
- });
6878
- // When ENABLE_FROZEN_TEMPLATE is false, warn in dev mode whenever someone is mutating the template
7057
+ // template is not frozen - shim, report, and warn
7058
+ // this shim should be applied in both dev and prod
7059
+ addLegacyStylesheetTokensShim(tmpl);
7060
+ // When ENABLE_FROZEN_TEMPLATE is false, we want to warn in dev mode whenever someone is mutating the template
6879
7061
  if (process.env.NODE_ENV !== 'production') {
6880
- if (!shared.isUndefined(tmpl.stylesheets)) {
6881
- warnOnStylesheetsMutation(tmpl.stylesheets);
6882
- }
6883
- for (const prop of TEMPLATE_PROPS) {
6884
- let value = tmpl[prop];
6885
- shared.defineProperty(tmpl, prop, {
6886
- enumerable: true,
6887
- configurable: true,
6888
- get() {
6889
- return value;
6890
- },
6891
- set(newValue) {
6892
- if (!mutationWarningsSilenced) {
6893
- logError(`Dynamically setting the "${prop}" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6894
- }
6895
- value = newValue;
6896
- }
6897
- });
6898
- }
6899
- const originalDescriptor = shared.getOwnPropertyDescriptor(tmpl, 'stylesheetTokens');
6900
- shared.defineProperty(tmpl, 'stylesheetTokens', {
6901
- enumerable: true,
6902
- configurable: true,
6903
- get: originalDescriptor.get,
6904
- set(value) {
6905
- logError(`Dynamically setting the "stylesheetTokens" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6906
- // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6907
- mutationWarningsSilenced = true;
6908
- originalDescriptor.set.call(this, value);
6909
- mutationWarningsSilenced = false;
6910
- }
7062
+ trackMutations(tmpl);
7063
+ } else {
7064
+ // In prod mode, we only track mutations if reporting is enabled
7065
+ onReportingEnabled(() => {
7066
+ trackMutations(tmpl);
6911
7067
  });
6912
7068
  }
6913
7069
  }
@@ -6974,4 +7130,4 @@ exports.swapTemplate = swapTemplate;
6974
7130
  exports.track = track;
6975
7131
  exports.unwrap = unwrap;
6976
7132
  exports.wire = wire;
6977
- /* version: 2.35.2 */
7133
+ /* version: 2.36.0 */
@@ -1,7 +1,7 @@
1
1
  /* proxy-compat-disable */
2
2
  import { lwcRuntimeFlags } from '@lwc/features';
3
3
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
4
- import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isFunction as isFunction$1, hasOwnProperty as hasOwnProperty$1, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, assign, isObject, assert, freeze, KEY__SYNTHETIC_MODE, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, htmlAttributeToProperty, isString, StringSlice, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, ArrayPop, isNumber, StringReplace, ArrayUnshift, globalThis as globalThis$1, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, ID_REFERENCING_ATTRIBUTES_SET, KEY__SHADOW_TOKEN, ArrayFilter, StringSplit, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift } from '@lwc/shared';
4
+ import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isArray as isArray$1, isFunction as isFunction$1, keys, hasOwnProperty as hasOwnProperty$1, forEach, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, assign, isObject, assert, freeze, KEY__SYNTHETIC_MODE, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, htmlPropertyToAttribute, ArraySlice, ArrayMap, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, htmlAttributeToProperty, isString, StringSlice, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, ArrayPop, isNumber, StringReplace, ArrayUnshift, globalThis as globalThis$1, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, ID_REFERENCING_ATTRIBUTES_SET, KEY__SHADOW_TOKEN, ArrayFilter, StringSplit, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift } from '@lwc/shared';
5
5
  import { applyAriaReflection } from '@lwc/aria-reflection';
6
6
 
7
7
  /*
@@ -32,7 +32,6 @@ if (process.env.NODE_ENV === 'test-karma-lwc') {
32
32
  * SPDX-License-Identifier: MIT
33
33
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
34
34
  */
35
- /** Callbacks to invoke when reporting is enabled **/
36
35
  const onReportingEnabledCallbacks = [];
37
36
  /** The currently assigned reporting dispatcher. */
38
37
  let currentDispatcher$1 = noop;
@@ -90,11 +89,11 @@ function onReportingEnabled(callback) {
90
89
  /**
91
90
  * Report to the current dispatcher, if there is one.
92
91
  * @param reportingEventId
93
- * @param vm
92
+ * @param payload - data to report
94
93
  */
95
- function report(reportingEventId, vm) {
94
+ function report(reportingEventId, payload) {
96
95
  if (enabled$1) {
97
- currentDispatcher$1(reportingEventId, vm.tagName, vm.idx);
96
+ currentDispatcher$1(reportingEventId, payload);
98
97
  }
99
98
  }
100
99
 
@@ -383,7 +382,7 @@ function parseStyleText(cssText) {
383
382
  // Make a shallow copy of an object but omit the given key
384
383
  function cloneAndOmitKey(object, keyToOmit) {
385
384
  const result = {};
386
- for (const key of Object.keys(object)) {
385
+ for (const key of keys(object)) {
387
386
  if (key !== keyToOmit) {
388
387
  result[key] = object[key];
389
388
  }
@@ -393,7 +392,7 @@ function cloneAndOmitKey(object, keyToOmit) {
393
392
  function flattenStylesheets(stylesheets) {
394
393
  const list = [];
395
394
  for (const stylesheet of stylesheets) {
396
- if (!Array.isArray(stylesheet)) {
395
+ if (!isArray$1(stylesheet)) {
397
396
  list.push(stylesheet);
398
397
  }
399
398
  else {
@@ -2672,6 +2671,10 @@ function checkVersionMismatch(func, type) {
2672
2671
  // stylesheets and templates do not have user-meaningful names, but components do
2673
2672
  const friendlyName = type === 'component' ? `${type} ${func.name}` : type;
2674
2673
  logError(`LWC WARNING: current engine is v${LWC_VERSION}, but ${friendlyName} was compiled with v${version}.\nPlease update your compiled code or LWC engine so that the versions match.\nNo further warnings will appear.`);
2674
+ report(1 /* ReportingEventId.CompilerRuntimeVersionMismatch */, {
2675
+ compilerVersion: version,
2676
+ runtimeVersion: LWC_VERSION,
2677
+ });
2675
2678
  }
2676
2679
  }
2677
2680
  }
@@ -4411,7 +4414,12 @@ function allocateInSlot(vm, children, owner) {
4411
4414
  } else if (isVScopedSlotFragment(vnode)) {
4412
4415
  slotName = vnode.slotName;
4413
4416
  }
4414
- const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
4417
+ // Can't use toString here because Symbol(1).toString() is 'Symbol(1)'
4418
+ // but elm.setAttribute('slot', Symbol(1)) is an error.
4419
+ // the following line also throws same error for symbols
4420
+ // Similar for Object.create(null)
4421
+ const normalizedSlotName = '' + slotName;
4422
+ const vnodes = cmpSlotsMapping[normalizedSlotName] = cmpSlotsMapping[normalizedSlotName] || [];
4415
4423
  ArrayPush$1.call(vnodes, vnode);
4416
4424
  }
4417
4425
  vm.cmpSlots = {
@@ -5477,6 +5485,8 @@ function registerComponent(
5477
5485
  Ctor, { tmpl }) {
5478
5486
  if (isFunction$1(Ctor)) {
5479
5487
  if (process.env.NODE_ENV !== 'production') {
5488
+ // There is no point in running this in production, because the version mismatch check relies
5489
+ // on code comments which are stripped out in production by minifiers
5480
5490
  checkVersionMismatch(Ctor, 'component');
5481
5491
  }
5482
5492
  signedTemplateMap.set(Ctor, tmpl);
@@ -5742,6 +5752,7 @@ function validateComponentStylesheets(vm, stylesheets) {
5742
5752
  // Validate and flatten any stylesheets defined as `static stylesheets`
5743
5753
  function computeStylesheets(vm, ctor) {
5744
5754
  if (lwcRuntimeFlags.ENABLE_PROGRAMMATIC_STYLESHEETS) {
5755
+ warnOnStylesheetsMutation(ctor);
5745
5756
  const {
5746
5757
  stylesheets
5747
5758
  } = ctor;
@@ -5756,6 +5767,24 @@ function computeStylesheets(vm, ctor) {
5756
5767
  }
5757
5768
  return null;
5758
5769
  }
5770
+ function warnOnStylesheetsMutation(ctor) {
5771
+ if (process.env.NODE_ENV !== 'production') {
5772
+ let {
5773
+ stylesheets
5774
+ } = ctor;
5775
+ defineProperty(ctor, 'stylesheets', {
5776
+ enumerable: true,
5777
+ configurable: true,
5778
+ get() {
5779
+ return stylesheets;
5780
+ },
5781
+ set(newValue) {
5782
+ logWarnOnce(`Dynamically setting the "stylesheets" static property on ${ctor.name} ` + 'will not affect the stylesheets injected.');
5783
+ stylesheets = newValue;
5784
+ }
5785
+ });
5786
+ }
5787
+ }
5759
5788
  function computeShadowMode(vm, renderer) {
5760
5789
  const {
5761
5790
  def
@@ -6138,7 +6167,7 @@ const querySelectorAll = globalThis$1[KEY__NATIVE_QUERY_SELECTOR_ALL];
6138
6167
  function isSyntheticShadowRootInstance(rootNode) {
6139
6168
  return rootNode !== document && isTrue(rootNode.synthetic);
6140
6169
  }
6141
- function reportViolation(source, target, attrName) {
6170
+ function reportViolation$1(source, target, attrName) {
6142
6171
  // The vm is either for the source, the target, or both. Either one or both must be using synthetic
6143
6172
  // shadow for a violation to be detected.
6144
6173
  let vm = getAssociatedVMIfPresent(source.getRootNode().host);
@@ -6149,7 +6178,10 @@ function reportViolation(source, target, attrName) {
6149
6178
  // vm should never be undefined here, but just to be safe, bail out and don't report
6150
6179
  return;
6151
6180
  }
6152
- report(0 /* ReportingEventId.CrossRootAriaInSyntheticShadow */, vm);
6181
+ report(0 /* ReportingEventId.CrossRootAriaInSyntheticShadow */, {
6182
+ tagName: vm.tagName,
6183
+ attributeName: attrName,
6184
+ });
6153
6185
  if (process.env.NODE_ENV !== 'production') {
6154
6186
  // Avoid excessively logging to the console in the case of duplicates.
6155
6187
  logWarnOnce(`Element <${source.tagName.toLowerCase()}> uses attribute "${attrName}" to reference element ` +
@@ -6181,7 +6213,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6181
6213
  const sourceElement = sourceElements[i];
6182
6214
  const sourceRoot = sourceElement.getRootNode();
6183
6215
  if (sourceRoot !== root) {
6184
- reportViolation(sourceElement, elm, idRefAttrName);
6216
+ reportViolation$1(sourceElement, elm, idRefAttrName);
6185
6217
  break;
6186
6218
  }
6187
6219
  }
@@ -6196,7 +6228,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6196
6228
  const targetRoot = target.getRootNode();
6197
6229
  if (targetRoot !== root) {
6198
6230
  // target element's shadow root is not the same as ours
6199
- reportViolation(elm, target, attrName);
6231
+ reportViolation$1(elm, target, attrName);
6200
6232
  }
6201
6233
  }
6202
6234
  }
@@ -6205,7 +6237,7 @@ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6205
6237
  let enabled = false;
6206
6238
  // We want to avoid patching globals whenever possible, so this should be tree-shaken out in prod-mode and if
6207
6239
  // reporting is not enabled. It should also only run once
6208
- function enableDetection() {
6240
+ function enableDetection$1() {
6209
6241
  if (enabled) {
6210
6242
  return; // don't double-apply the patches
6211
6243
  }
@@ -6257,14 +6289,112 @@ function isSyntheticShadowLoaded() {
6257
6289
  if (process.env.IS_BROWSER && supportsCssEscape() && isSyntheticShadowLoaded()) {
6258
6290
  // Always run detection in dev mode, so we can at least print to the console
6259
6291
  if (process.env.NODE_ENV !== 'production') {
6260
- enableDetection();
6292
+ enableDetection$1();
6261
6293
  }
6262
6294
  else {
6263
6295
  // In prod mode, only enable detection if reporting is enabled
6264
- onReportingEnabled(enableDetection);
6296
+ onReportingEnabled(enableDetection$1);
6265
6297
  }
6266
6298
  }
6267
6299
 
6300
+ /*
6301
+ * Copyright (c) 2018, salesforce.com, inc.
6302
+ * All rights reserved.
6303
+ * SPDX-License-Identifier: MIT
6304
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6305
+ */
6306
+ //
6307
+ // The goal of this code is to detect usages of non-standard reflected ARIA properties. These are caused by
6308
+ // legacy non-standard Element.prototype extensions added by the @lwc/aria-reflection package.
6309
+ //
6310
+ // See the README for @lwc/aria-reflection
6311
+ const NON_STANDARD_ARIA_PROPS = ['ariaActiveDescendant', 'ariaControls', 'ariaDescribedBy', 'ariaDetails', 'ariaErrorMessage', 'ariaFlowTo', 'ariaLabelledBy', 'ariaOwns'];
6312
+ function isLightningElement(elm) {
6313
+ // The former case is for `this.prop` (inside component) and the latter is for `element.prop` (outside component).
6314
+ // In both cases, we apply the non-standard prop even when the global polyfill is disabled, so this is kosher.
6315
+ return elm instanceof LightningElement || elm instanceof BaseBridgeElement;
6316
+ }
6317
+ function findVM(elm) {
6318
+ // If it's a shadow DOM component, then it has a host
6319
+ const {
6320
+ host
6321
+ } = elm.getRootNode();
6322
+ const vm = isUndefined$1(host) ? undefined : getAssociatedVMIfPresent(host);
6323
+ if (!isUndefined$1(vm)) {
6324
+ return vm;
6325
+ }
6326
+ // Else it might be a light DOM component. Walk up the tree trying to find the owner
6327
+ let parentElement = elm;
6328
+ while (!isNull(parentElement = parentElement.parentElement)) {
6329
+ if (isLightningElement(parentElement)) {
6330
+ const vm = getAssociatedVMIfPresent(parentElement);
6331
+ if (!isUndefined$1(vm)) {
6332
+ return vm;
6333
+ }
6334
+ }
6335
+ }
6336
+ // If we return undefined, it's because the element was rendered wholly outside a LightningElement
6337
+ }
6338
+
6339
+ function checkAndReportViolation(elm, prop) {
6340
+ if (!isLightningElement(elm)) {
6341
+ const vm = findVM(elm);
6342
+ if (process.env.NODE_ENV !== 'production') {
6343
+ logWarnOnce(`Element <${elm.tagName.toLowerCase()}> ` + (isUndefined$1(vm) ? '' : `owned by <${vm.elm.tagName.toLowerCase()}> `) + `uses non-standard property "${prop}". This will be removed in a future version of LWC. ` + `See https://lwc.dev/guide/accessibility#deprecated-aria-reflected-properties`);
6344
+ }
6345
+ report(2 /* ReportingEventId.NonStandardAriaReflection */, {
6346
+ tagName: vm === null || vm === void 0 ? void 0 : vm.tagName,
6347
+ propertyName: prop
6348
+ });
6349
+ }
6350
+ }
6351
+ function enableDetection() {
6352
+ const {
6353
+ prototype
6354
+ } = Element;
6355
+ for (const prop of NON_STANDARD_ARIA_PROPS) {
6356
+ const descriptor = getOwnPropertyDescriptor$1(prototype, prop);
6357
+ // The descriptor should exist because the @lwc/aria-reflection polyfill has run by now.
6358
+ // This happens automatically because of the ordering of imports.
6359
+ if (process.env.NODE_ENV !== 'production') {
6360
+ /* istanbul ignore if */
6361
+ if (isUndefined$1(descriptor) || isUndefined$1(descriptor.get) || isUndefined$1(descriptor.set)) {
6362
+ // should never happen
6363
+ throw new Error('detect-non-standard-aria.ts loaded before @lwc/aria-reflection');
6364
+ }
6365
+ }
6366
+ // @ts-ignore
6367
+ const {
6368
+ get,
6369
+ set
6370
+ } = descriptor;
6371
+ defineProperty(prototype, prop, {
6372
+ get() {
6373
+ checkAndReportViolation(this, prop);
6374
+ return get.call(this);
6375
+ },
6376
+ set(val) {
6377
+ checkAndReportViolation(this, prop);
6378
+ return set.call(this, val);
6379
+ },
6380
+ configurable: true,
6381
+ enumerable: true
6382
+ });
6383
+ }
6384
+ }
6385
+ // No point in running this code if we're not in a browser, or if the global polyfill is not loaded
6386
+ if (process.env.IS_BROWSER) {
6387
+ if (!lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
6388
+ // Always run detection in dev mode, so we can at least print to the console
6389
+ if (process.env.NODE_ENV !== 'production') {
6390
+ enableDetection();
6391
+ } else {
6392
+ // In prod mode, only enable detection if reporting is enabled
6393
+ onReportingEnabled(enableDetection);
6394
+ }
6395
+ }
6396
+ }
6397
+
6268
6398
  /*
6269
6399
  * Copyright (c) 2018, salesforce.com, inc.
6270
6400
  * All rights reserved.
@@ -6749,12 +6879,13 @@ function setHooks(hooks) {
6749
6879
  */
6750
6880
  // See @lwc/engine-core/src/framework/template.ts
6751
6881
  const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6752
- // Via https://www.npmjs.com/package/object-observer
6753
- const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6754
6882
  // Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
6755
- const STYLESHEET_FUNCTION_EXPANDOS = [
6883
+ const STYLESHEET_PROPS = [
6756
6884
  // SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
6757
6885
  '$scoped$'];
6886
+ // Via https://www.npmjs.com/package/object-observer
6887
+ const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6888
+ let mutationTrackingDisabled = false;
6758
6889
  function getOriginalArrayMethod(prop) {
6759
6890
  switch (prop) {
6760
6891
  case 'pop':
@@ -6777,7 +6908,20 @@ function getOriginalArrayMethod(prop) {
6777
6908
  return ArrayCopyWithin;
6778
6909
  }
6779
6910
  }
6780
- let mutationWarningsSilenced = false;
6911
+ function reportViolation(type, eventId, prop) {
6912
+ if (process.env.NODE_ENV !== 'production') {
6913
+ logWarnOnce(`Mutating the "${prop}" property on a ${type} ` + `is deprecated and will be removed in a future version of LWC. ` + `See: https://lwc.dev/guide/css#deprecated-template-mutation`);
6914
+ }
6915
+ report(eventId, {
6916
+ propertyName: prop
6917
+ });
6918
+ }
6919
+ function reportTemplateViolation(prop) {
6920
+ reportViolation('template', 3 /* ReportingEventId.TemplateMutation */, prop);
6921
+ }
6922
+ function reportStylesheetViolation(prop) {
6923
+ reportViolation('stylesheet', 4 /* ReportingEventId.StylesheetMutation */, prop);
6924
+ }
6781
6925
  // Warn if the user tries to mutate a stylesheets array, e.g.:
6782
6926
  // `tmpl.stylesheets.push(someStylesheetFunction)`
6783
6927
  function warnOnArrayMutation(stylesheets) {
@@ -6786,7 +6930,7 @@ function warnOnArrayMutation(stylesheets) {
6786
6930
  for (const prop of ARRAY_MUTATION_METHODS) {
6787
6931
  const originalArrayMethod = getOriginalArrayMethod(prop);
6788
6932
  stylesheets[prop] = function arrayMutationWarningWrapper() {
6789
- logError(`Mutating the "stylesheets" array on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6933
+ reportTemplateViolation('stylesheets');
6790
6934
  // @ts-ignore
6791
6935
  return originalArrayMethod.apply(this, arguments);
6792
6936
  };
@@ -6795,8 +6939,7 @@ function warnOnArrayMutation(stylesheets) {
6795
6939
  // Warn if the user tries to mutate a stylesheet factory function, e.g.:
6796
6940
  // `stylesheet.$scoped$ = true`
6797
6941
  function warnOnStylesheetFunctionMutation(stylesheet) {
6798
- // We could warn on other properties, but in practice only certain expandos are meaningful to LWC at runtime
6799
- for (const prop of STYLESHEET_FUNCTION_EXPANDOS) {
6942
+ for (const prop of STYLESHEET_PROPS) {
6800
6943
  let value = stylesheet[prop];
6801
6944
  defineProperty(stylesheet, prop, {
6802
6945
  enumerable: true,
@@ -6805,14 +6948,14 @@ function warnOnStylesheetFunctionMutation(stylesheet) {
6805
6948
  return value;
6806
6949
  },
6807
6950
  set(newValue) {
6808
- logError(`Dynamically setting the "${prop}" property on a stylesheet function ` + `is deprecated and may be removed in a future version of LWC.`);
6951
+ reportStylesheetViolation(prop);
6809
6952
  value = newValue;
6810
6953
  }
6811
6954
  });
6812
6955
  }
6813
6956
  }
6814
6957
  // Warn on either array or stylesheet (function) mutation, in a deeply-nested array
6815
- function warnOnStylesheetsMutation(stylesheets) {
6958
+ function trackStylesheetsMutation(stylesheets) {
6816
6959
  traverseStylesheets(stylesheets, subStylesheets => {
6817
6960
  if (isArray$1(subStylesheets)) {
6818
6961
  warnOnArrayMutation(subStylesheets);
@@ -6839,7 +6982,70 @@ function traverseStylesheets(stylesheets, callback) {
6839
6982
  }
6840
6983
  }
6841
6984
  }
6985
+ function trackMutations(tmpl) {
6986
+ if (!isUndefined$1(tmpl.stylesheets)) {
6987
+ trackStylesheetsMutation(tmpl.stylesheets);
6988
+ }
6989
+ for (const prop of TEMPLATE_PROPS) {
6990
+ let value = tmpl[prop];
6991
+ defineProperty(tmpl, prop, {
6992
+ enumerable: true,
6993
+ configurable: true,
6994
+ get() {
6995
+ return value;
6996
+ },
6997
+ set(newValue) {
6998
+ if (!mutationTrackingDisabled) {
6999
+ reportTemplateViolation(prop);
7000
+ }
7001
+ value = newValue;
7002
+ }
7003
+ });
7004
+ }
7005
+ const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
7006
+ defineProperty(tmpl, 'stylesheetTokens', {
7007
+ enumerable: true,
7008
+ configurable: true,
7009
+ get: originalDescriptor.get,
7010
+ set(value) {
7011
+ reportTemplateViolation('stylesheetTokens');
7012
+ // Avoid logging/reporting twice (for both stylesheetToken and stylesheetTokens)
7013
+ mutationTrackingDisabled = true;
7014
+ originalDescriptor.set.call(this, value);
7015
+ mutationTrackingDisabled = false;
7016
+ }
7017
+ });
7018
+ }
7019
+ function addLegacyStylesheetTokensShim(tmpl) {
7020
+ // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
7021
+ // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
7022
+ defineProperty(tmpl, 'stylesheetTokens', {
7023
+ enumerable: true,
7024
+ configurable: true,
7025
+ get() {
7026
+ const {
7027
+ stylesheetToken
7028
+ } = this;
7029
+ if (isUndefined$1(stylesheetToken)) {
7030
+ return stylesheetToken;
7031
+ }
7032
+ // Shim for the old `stylesheetTokens` property
7033
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
7034
+ return {
7035
+ hostAttribute: `${stylesheetToken}-host`,
7036
+ shadowAttribute: stylesheetToken
7037
+ };
7038
+ },
7039
+ set(value) {
7040
+ // If the value is null or some other exotic object, you would be broken anyway in the past
7041
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
7042
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
7043
+ this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
7044
+ }
7045
+ });
7046
+ }
6842
7047
  function freezeTemplate(tmpl) {
7048
+ // TODO [#2782]: remove this flag and delete the legacy behavior
6843
7049
  if (lwcRuntimeFlags.ENABLE_FROZEN_TEMPLATE) {
6844
7050
  // Deep freeze the template
6845
7051
  freeze(tmpl);
@@ -6847,66 +7053,16 @@ function freezeTemplate(tmpl) {
6847
7053
  deepFreeze(tmpl.stylesheets);
6848
7054
  }
6849
7055
  } else {
6850
- // TODO [#2782]: remove this flag and delete the legacy behavior
6851
- // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6852
- // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
6853
- defineProperty(tmpl, 'stylesheetTokens', {
6854
- enumerable: true,
6855
- configurable: true,
6856
- get() {
6857
- const {
6858
- stylesheetToken
6859
- } = this;
6860
- if (isUndefined$1(stylesheetToken)) {
6861
- return stylesheetToken;
6862
- }
6863
- // Shim for the old `stylesheetTokens` property
6864
- // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
6865
- return {
6866
- hostAttribute: `${stylesheetToken}-host`,
6867
- shadowAttribute: stylesheetToken
6868
- };
6869
- },
6870
- set(value) {
6871
- // If the value is null or some other exotic object, you would be broken anyway in the past
6872
- // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
6873
- // However it may be undefined in newer versions of LWC, so we need to guard against that case.
6874
- this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
6875
- }
6876
- });
6877
- // When ENABLE_FROZEN_TEMPLATE is false, warn in dev mode whenever someone is mutating the template
7056
+ // template is not frozen - shim, report, and warn
7057
+ // this shim should be applied in both dev and prod
7058
+ addLegacyStylesheetTokensShim(tmpl);
7059
+ // When ENABLE_FROZEN_TEMPLATE is false, we want to warn in dev mode whenever someone is mutating the template
6878
7060
  if (process.env.NODE_ENV !== 'production') {
6879
- if (!isUndefined$1(tmpl.stylesheets)) {
6880
- warnOnStylesheetsMutation(tmpl.stylesheets);
6881
- }
6882
- for (const prop of TEMPLATE_PROPS) {
6883
- let value = tmpl[prop];
6884
- defineProperty(tmpl, prop, {
6885
- enumerable: true,
6886
- configurable: true,
6887
- get() {
6888
- return value;
6889
- },
6890
- set(newValue) {
6891
- if (!mutationWarningsSilenced) {
6892
- logError(`Dynamically setting the "${prop}" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6893
- }
6894
- value = newValue;
6895
- }
6896
- });
6897
- }
6898
- const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6899
- defineProperty(tmpl, 'stylesheetTokens', {
6900
- enumerable: true,
6901
- configurable: true,
6902
- get: originalDescriptor.get,
6903
- set(value) {
6904
- logError(`Dynamically setting the "stylesheetTokens" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6905
- // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6906
- mutationWarningsSilenced = true;
6907
- originalDescriptor.set.call(this, value);
6908
- mutationWarningsSilenced = false;
6909
- }
7061
+ trackMutations(tmpl);
7062
+ } else {
7063
+ // In prod mode, we only track mutations if reporting is enabled
7064
+ onReportingEnabled(() => {
7065
+ trackMutations(tmpl);
6910
7066
  });
6911
7067
  }
6912
7068
  }
@@ -6936,4 +7092,4 @@ function getComponentConstructor(elm) {
6936
7092
  }
6937
7093
 
6938
7094
  export { LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6939
- /* version: 2.35.2 */
7095
+ /* version: 2.36.0 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/engine-core",
3
- "version": "2.35.2",
3
+ "version": "2.36.0",
4
4
  "description": "Core LWC engine APIs.",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -24,9 +24,9 @@
24
24
  "types/"
25
25
  ],
26
26
  "dependencies": {
27
- "@lwc/aria-reflection": "2.35.2",
28
- "@lwc/features": "2.35.2",
29
- "@lwc/shared": "2.35.2"
27
+ "@lwc/aria-reflection": "2.36.0",
28
+ "@lwc/features": "2.36.0",
29
+ "@lwc/shared": "2.36.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "observable-membrane": "2.0.0"
@@ -1,7 +1,7 @@
1
1
  import { SlotSet } from './vm';
2
2
  import { LightningElementConstructor } from './base-lightning-element';
3
3
  import { VNode, VNodes, VElement, VText, VCustomElement, VComment, VElementData, VStatic, Key, VFragment, VScopedSlotFragment } from './vnodes';
4
- declare function ssf(slotName: string, factory: (value: any, key: any) => VFragment): VScopedSlotFragment;
4
+ declare function ssf(slotName: unknown, factory: (value: any, key: any) => VFragment): VScopedSlotFragment;
5
5
  declare function st(fragment: Element, key: Key): VStatic;
6
6
  declare function fr(key: Key, children: VNodes, stable: 0 | 1): VFragment;
7
7
  declare function h(sel: string, data: VElementData, children?: VNodes): VElement;
@@ -1,8 +1,38 @@
1
- import { VM } from './vm';
2
1
  export declare const enum ReportingEventId {
3
- CrossRootAriaInSyntheticShadow = 0
2
+ CrossRootAriaInSyntheticShadow = 0,
3
+ CompilerRuntimeVersionMismatch = 1,
4
+ NonStandardAriaReflection = 2,
5
+ TemplateMutation = 3,
6
+ StylesheetMutation = 4
4
7
  }
5
- type ReportingDispatcher = (reportingEventId: ReportingEventId, tagName: string, vmIndex: number) => void;
8
+ export interface BasePayload {
9
+ tagName?: string;
10
+ }
11
+ export interface CrossRootAriaInSyntheticShadowPayload extends BasePayload {
12
+ attributeName: string;
13
+ }
14
+ export interface CompilerRuntimeVersionMismatchPayload extends BasePayload {
15
+ compilerVersion: string;
16
+ runtimeVersion: string;
17
+ }
18
+ export interface NonStandardAriaReflectionPayload extends BasePayload {
19
+ propertyName: string;
20
+ }
21
+ export interface TemplateMutationPayload extends BasePayload {
22
+ propertyName: string;
23
+ }
24
+ export interface StylesheetMutationPayload extends BasePayload {
25
+ propertyName: string;
26
+ }
27
+ export type ReportingPayloadMapping = {
28
+ [ReportingEventId.CrossRootAriaInSyntheticShadow]: CrossRootAriaInSyntheticShadowPayload;
29
+ [ReportingEventId.CompilerRuntimeVersionMismatch]: CompilerRuntimeVersionMismatchPayload;
30
+ [ReportingEventId.NonStandardAriaReflection]: NonStandardAriaReflectionPayload;
31
+ [ReportingEventId.TemplateMutation]: TemplateMutationPayload;
32
+ [ReportingEventId.StylesheetMutation]: StylesheetMutationPayload;
33
+ };
34
+ export type ReportingDispatcher<T extends ReportingEventId = ReportingEventId> = (reportingEventId: T, payload: ReportingPayloadMapping[T]) => void;
35
+ /** Callbacks to invoke when reporting is enabled **/
6
36
  type OnReportingEnabledCallback = () => void;
7
37
  export declare const reportingControl: {
8
38
  /**
@@ -25,7 +55,7 @@ export declare function onReportingEnabled(callback: OnReportingEnabledCallback)
25
55
  /**
26
56
  * Report to the current dispatcher, if there is one.
27
57
  * @param reportingEventId
28
- * @param vm
58
+ * @param payload - data to report
29
59
  */
30
- export declare function report(reportingEventId: ReportingEventId, vm: VM): void;
60
+ export declare function report<T extends ReportingEventId>(reportingEventId: T, payload: ReportingPayloadMapping[T]): void;
31
61
  export {};
@@ -25,7 +25,7 @@ export interface BaseVNode {
25
25
  export interface VScopedSlotFragment extends BaseVNode {
26
26
  factory: (value: any, key: any) => VFragment;
27
27
  type: VNodeType.ScopedSlotFragment;
28
- slotName: string;
28
+ slotName: unknown;
29
29
  }
30
30
  export interface VStatic extends BaseVNode {
31
31
  type: VNodeType.Static;
package/types/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import './testFeatureFlag';
2
2
  import './patches/detect-synthetic-cross-root-aria';
3
+ import './patches/detect-non-standard-aria';
3
4
  export * from './framework/main';
@@ -0,0 +1 @@
1
+ export {};