lwc 2.3.4 → 2.5.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.
Files changed (41) hide show
  1. package/dist/engine-dom/esm/es2017/engine-dom.js +389 -174
  2. package/dist/engine-dom/iife/es2017/engine-dom.js +389 -174
  3. package/dist/engine-dom/iife/es2017/engine-dom.min.js +2 -2
  4. package/dist/engine-dom/iife/es2017/engine-dom_debug.js +359 -137
  5. package/dist/engine-dom/iife/es5/engine-dom.js +404 -198
  6. package/dist/engine-dom/iife/es5/engine-dom.min.js +2 -2
  7. package/dist/engine-dom/iife/es5/engine-dom_debug.js +372 -159
  8. package/dist/engine-dom/umd/es2017/engine-dom.js +389 -174
  9. package/dist/engine-dom/umd/es2017/engine-dom.min.js +2 -2
  10. package/dist/engine-dom/umd/es2017/engine-dom_debug.js +359 -137
  11. package/dist/engine-dom/umd/es5/engine-dom.js +404 -198
  12. package/dist/engine-dom/umd/es5/engine-dom.min.js +2 -2
  13. package/dist/engine-dom/umd/es5/engine-dom_debug.js +372 -159
  14. package/dist/engine-server/commonjs/es2017/engine-server.js +333 -181
  15. package/dist/engine-server/commonjs/es2017/engine-server.min.js +2 -2
  16. package/dist/engine-server/esm/es2017/engine-server.js +333 -181
  17. package/dist/synthetic-shadow/esm/es2017/synthetic-shadow.js +29 -16
  18. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow.js +29 -16
  19. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow.min.js +2 -2
  20. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow_debug.js +29 -16
  21. package/dist/synthetic-shadow/iife/es5/synthetic-shadow.js +31 -16
  22. package/dist/synthetic-shadow/iife/es5/synthetic-shadow.min.js +2 -2
  23. package/dist/synthetic-shadow/iife/es5/synthetic-shadow_debug.js +31 -16
  24. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow.js +29 -16
  25. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow.min.js +2 -2
  26. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow_debug.js +29 -16
  27. package/dist/synthetic-shadow/umd/es5/synthetic-shadow.js +31 -16
  28. package/dist/synthetic-shadow/umd/es5/synthetic-shadow.min.js +2 -2
  29. package/dist/synthetic-shadow/umd/es5/synthetic-shadow_debug.js +31 -16
  30. package/dist/wire-service/esm/es2017/wire-service.js +2 -2
  31. package/dist/wire-service/iife/es2017/wire-service.js +2 -2
  32. package/dist/wire-service/iife/es2017/wire-service_debug.js +2 -2
  33. package/dist/wire-service/iife/es5/wire-service.js +3 -3
  34. package/dist/wire-service/iife/es5/wire-service.min.js +1 -1
  35. package/dist/wire-service/iife/es5/wire-service_debug.js +3 -3
  36. package/dist/wire-service/umd/es2017/wire-service.js +2 -2
  37. package/dist/wire-service/umd/es2017/wire-service_debug.js +2 -2
  38. package/dist/wire-service/umd/es5/wire-service.js +3 -3
  39. package/dist/wire-service/umd/es5/wire-service.min.js +1 -1
  40. package/dist/wire-service/umd/es5/wire-service_debug.js +3 -3
  41. package/package.json +8 -8
@@ -104,6 +104,10 @@ function isFalse(obj) {
104
104
  return obj === false;
105
105
  }
106
106
 
107
+ function isBoolean(obj) {
108
+ return typeof obj === 'boolean';
109
+ }
110
+
107
111
  function isFunction$1(obj) {
108
112
  return typeof obj === 'function';
109
113
  }
@@ -246,6 +250,7 @@ const KEY__IS_NATIVE_SHADOW_ROOT_DEFINED = '$isNativeShadowRootDefined$';
246
250
  const KEY__SHADOW_RESOLVER = '$shadowResolver$';
247
251
  const KEY__SHADOW_TOKEN = '$shadowToken$';
248
252
  const KEY__SYNTHETIC_MODE = '$$lwc-synthetic-mode';
253
+ const KEY__SCOPED_CSS = '$scoped$';
249
254
  /**
250
255
  * Map composed of properties to attributes not following the HTML property to attribute mapping
251
256
  * convention.
@@ -294,7 +299,7 @@ function htmlPropertyToAttribute(propName) {
294
299
  CACHED_PROPERTY_ATTRIBUTE_MAPPING.set(propName, attributeName);
295
300
  return attributeName;
296
301
  }
297
- /** version: 2.3.4 */
302
+ /** version: 2.5.1 */
298
303
 
299
304
  /*
300
305
  * Copyright (c) 2018, salesforce.com, inc.
@@ -399,19 +404,33 @@ for (let i = 0, len = ElementPrototypeAriaPropertyNames.length; i < len; i += 1)
399
404
  */
400
405
 
401
406
 
407
+ const features = {
408
+ ENABLE_REACTIVE_SETTER: null,
409
+ ENABLE_HMR: null,
410
+ ENABLE_INNER_OUTER_TEXT_PATCH: null,
411
+ ENABLE_ELEMENT_PATCH: null,
412
+ ENABLE_NODE_LIST_PATCH: null,
413
+ ENABLE_HTML_COLLECTIONS_PATCH: null,
414
+ ENABLE_NODE_PATCH: null,
415
+ ENABLE_NON_COMPOSED_EVENTS_LEAKAGE: null,
416
+ ENABLE_MIXED_SHADOW_MODE: null,
417
+ ENABLE_WIRE_SYNC_EMIT: null
418
+ };
419
+
402
420
  if (!_globalThis.lwcRuntimeFlags) {
403
421
  Object.defineProperty(_globalThis, 'lwcRuntimeFlags', {
404
422
  value: create(null)
405
423
  });
406
424
  }
407
425
 
408
- const runtimeFlags = _globalThis.lwcRuntimeFlags; // This function is not supported for use within components and is meant for
409
- // configuring runtime feature flags during app initialization.
426
+ const runtimeFlags = _globalThis.lwcRuntimeFlags;
427
+ /**
428
+ * Set the value at runtime of a given feature flag. This method only be invoked once per feature
429
+ * flag. It is meant to be used during the app initialization.
430
+ */
410
431
 
411
432
  function setFeatureFlag(name, value) {
412
- const isBoolean = isTrue(value) || isFalse(value);
413
-
414
- if (!isBoolean) {
433
+ if (!isBoolean(value)) {
415
434
  const message = `Failed to set the value "${value}" for the runtime feature flag "${name}". Runtime feature flags can only be set to a boolean value.`;
416
435
 
417
436
  if (process.env.NODE_ENV !== 'production') {
@@ -423,9 +442,10 @@ function setFeatureFlag(name, value) {
423
442
  }
424
443
  }
425
444
 
426
- if (isUndefined$1(featureFlagLookup[name])) {
427
- // eslint-disable-next-line no-console
428
- console.warn(`Failed to set the value "${value}" for the runtime feature flag "${name}" because it is undefined. Possible reasons are that 1) it was misspelled or 2) it was removed from the @lwc/features package.`);
445
+ if (isUndefined$1(features[name])) {
446
+ const availableFlags = keys(features).map(name => `"${name}"`).join(', '); // eslint-disable-next-line no-console
447
+
448
+ console.warn(`Failed to set the value "${value}" for the runtime feature flag "${name}" because it is undefined. Available flags: ${availableFlags}.`);
429
449
  return;
430
450
  }
431
451
 
@@ -442,37 +462,23 @@ function setFeatureFlag(name, value) {
442
462
  return;
443
463
  }
444
464
 
445
- Object.defineProperty(runtimeFlags, name, {
465
+ defineProperty(runtimeFlags, name, {
446
466
  value
447
467
  });
448
468
  }
449
- } // This function is exposed to components to facilitate testing so we add a
450
- // check to make sure it is not invoked in production.
469
+ }
470
+ /**
471
+ * Set the value at runtime of a given feature flag. This method should only be used for testing
472
+ * purposes. It is a no-op when invoked in production mode.
473
+ */
451
474
 
452
475
 
453
476
  function setFeatureFlagForTest(name, value) {
454
477
  if (process.env.NODE_ENV !== 'production') {
455
- return setFeatureFlag(name, value);
478
+ setFeatureFlag(name, value);
456
479
  }
457
480
  }
458
-
459
- const featureFlagLookup = {
460
- ENABLE_REACTIVE_SETTER: null,
461
- ENABLE_HMR: null,
462
- // Flag to toggle on/off the enforcement of innerText/outerText shadow dom semantic in elements when using synthetic shadow.
463
- // Note: Once active, elements outside the lwc boundary are controlled by the ENABLE_ELEMENT_PATCH flag.
464
- ENABLE_INNER_OUTER_TEXT_PATCH: null,
465
- // Flags to toggle on/off the enforcement of shadow dom semantic in element/node outside lwc boundary when using synthetic shadow.
466
- ENABLE_ELEMENT_PATCH: null,
467
- ENABLE_NODE_LIST_PATCH: null,
468
- ENABLE_HTML_COLLECTIONS_PATCH: null,
469
- ENABLE_NODE_PATCH: null,
470
- // Disables the fix for #2121 where non-composed events are visible outside of their shadow root.
471
- ENABLE_NON_COMPOSED_EVENTS_LEAKAGE: null,
472
- ENABLE_LIGHT_DOM_COMPONENTS: null,
473
- ENABLE_MIXED_SHADOW_MODE: null
474
- };
475
- /** version: 2.3.4 */
481
+ /** version: 2.5.1 */
476
482
 
477
483
  /* proxy-compat-disable */
478
484
 
@@ -483,6 +489,7 @@ const featureFlagLookup = {
483
489
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
484
490
  */
485
491
 
492
+
486
493
  let nextTickCallbackQueue = [];
487
494
  const SPACE_CHAR = 32;
488
495
  const EmptyObject = seal(create(null));
@@ -2803,12 +2810,6 @@ const LightningElement = function () {
2803
2810
  associateVM(component, vm);
2804
2811
  associateVM(elm, vm);
2805
2812
 
2806
- if (!runtimeFlags.ENABLE_LIGHT_DOM_COMPONENTS) {
2807
- assert.isTrue(def.renderMode !== 0
2808
- /* Light */
2809
- , `${def.name || 'Anonymous class'} is an invalid LWC component. Light DOM components are not available in this environment.`);
2810
- }
2811
-
2812
2813
  if (vm.renderMode === 1
2813
2814
  /* Shadow */
2814
2815
  ) {
@@ -2847,6 +2848,12 @@ function attachShadow(vm) {
2847
2848
  if (process.env.NODE_ENV !== 'production') {
2848
2849
  patchShadowRootWithRestrictions(cmpRoot);
2849
2850
  }
2851
+ }
2852
+
2853
+ function warnIfInvokedDuringConstruction(vm, methodName) {
2854
+ if (isBeingConstructed(vm)) {
2855
+ logError(`this.${methodName}() should not be called during the construction of the custom element for ${getComponentTag(vm)} because the element is not yet in the DOM or has no children yet.`);
2856
+ }
2850
2857
  } // @ts-ignore
2851
2858
 
2852
2859
 
@@ -3005,7 +3012,7 @@ LightningElement.prototype = {
3005
3012
  } = vm;
3006
3013
 
3007
3014
  if (process.env.NODE_ENV !== 'production') {
3008
- assert.isFalse(isBeingConstructed(vm), `this.getBoundingClientRect() should not be called during the construction of the custom element for ${getComponentTag(vm)} because the element is not yet in the DOM, instead, you can use it in one of the available life-cycle hooks.`);
3015
+ warnIfInvokedDuringConstruction(vm, 'getBoundingClientRect');
3009
3016
  }
3010
3017
 
3011
3018
  return getBoundingClientRect(elm);
@@ -3021,7 +3028,7 @@ LightningElement.prototype = {
3021
3028
  } = vm;
3022
3029
 
3023
3030
  if (process.env.NODE_ENV !== 'production') {
3024
- assert.isFalse(isBeingConstructed(vm), `this.querySelector() cannot be called during the construction of the custom element for ${getComponentTag(vm)} because no children has been added to this element yet.`);
3031
+ warnIfInvokedDuringConstruction(vm, 'querySelector');
3025
3032
  }
3026
3033
 
3027
3034
  return querySelector(elm, selectors);
@@ -3037,7 +3044,7 @@ LightningElement.prototype = {
3037
3044
  } = vm;
3038
3045
 
3039
3046
  if (process.env.NODE_ENV !== 'production') {
3040
- assert.isFalse(isBeingConstructed(vm), `this.querySelectorAll() cannot be called during the construction of the custom element for ${getComponentTag(vm)} because no children has been added to this element yet.`);
3047
+ warnIfInvokedDuringConstruction(vm, 'querySelectorAll');
3041
3048
  }
3042
3049
 
3043
3050
  return querySelectorAll(elm, selectors);
@@ -3053,7 +3060,7 @@ LightningElement.prototype = {
3053
3060
  } = vm;
3054
3061
 
3055
3062
  if (process.env.NODE_ENV !== 'production') {
3056
- assert.isFalse(isBeingConstructed(vm), `this.getElementsByTagName() cannot be called during the construction of the custom element for ${getComponentTag(vm)} because no children has been added to this element yet.`);
3063
+ warnIfInvokedDuringConstruction(vm, 'getElementsByTagName');
3057
3064
  }
3058
3065
 
3059
3066
  return getElementsByTagName(elm, tagNameOrWildCard);
@@ -3069,7 +3076,7 @@ LightningElement.prototype = {
3069
3076
  } = vm;
3070
3077
 
3071
3078
  if (process.env.NODE_ENV !== 'production') {
3072
- assert.isFalse(isBeingConstructed(vm), `this.getElementsByClassName() cannot be called during the construction of the custom element for ${getComponentTag(vm)} because no children has been added to this element yet.`);
3079
+ warnIfInvokedDuringConstruction(vm, 'getElementsByClassName');
3073
3080
  }
3074
3081
 
3075
3082
  return getElementsByClassName(elm, names);
@@ -3442,18 +3449,33 @@ function createObservedFieldPropertyDescriptor(key) {
3442
3449
 
3443
3450
  function getClassDescriptorType(descriptor) {
3444
3451
  if (isFunction$1(descriptor.value)) {
3445
- return 'method';
3452
+ return "method"
3453
+ /* Method */
3454
+ ;
3446
3455
  } else if (isFunction$1(descriptor.set) || isFunction$1(descriptor.get)) {
3447
- return 'accessor';
3456
+ return "accessor"
3457
+ /* Accessor */
3458
+ ;
3448
3459
  } else {
3449
- return 'field';
3460
+ return "field"
3461
+ /* Field */
3462
+ ;
3450
3463
  }
3451
3464
  }
3452
3465
 
3453
3466
  function validateObservedField(Ctor, fieldName, descriptor) {
3454
3467
  if (!isUndefined$1(descriptor)) {
3455
3468
  const type = getClassDescriptorType(descriptor);
3456
- assert.fail(`Invalid observed ${fieldName} field. Found a duplicate ${type} with the same name.`);
3469
+ const message = `Invalid observed ${fieldName} field. Found a duplicate ${type} with the same name.`; // [W-9927596] Ideally we always throw an error when detecting duplicate observed field.
3470
+ // This branch is only here for backward compatibility reasons.
3471
+
3472
+ if (type === "accessor"
3473
+ /* Accessor */
3474
+ ) {
3475
+ logError(message);
3476
+ } else {
3477
+ assert.fail(message);
3478
+ }
3457
3479
  }
3458
3480
  }
3459
3481
 
@@ -3480,7 +3502,16 @@ function validateMethodDecoratedWithWire(Ctor, methodName, descriptor) {
3480
3502
  function validateFieldDecoratedWithApi(Ctor, fieldName, descriptor) {
3481
3503
  if (!isUndefined$1(descriptor)) {
3482
3504
  const type = getClassDescriptorType(descriptor);
3483
- assert.fail(`Invalid @api ${fieldName} field. Found a duplicate ${type} with the same name.`);
3505
+ const message = `Invalid @api ${fieldName} field. Found a duplicate ${type} with the same name.`; // [W-9927596] Ideally we always throw an error when detecting duplicate public properties.
3506
+ // This branch is only here for backward compatibility reasons.
3507
+
3508
+ if (type === "accessor"
3509
+ /* Accessor */
3510
+ ) {
3511
+ logError(message);
3512
+ } else {
3513
+ assert.fail(message);
3514
+ }
3484
3515
  }
3485
3516
  }
3486
3517
 
@@ -3543,9 +3574,16 @@ function registerDecorators(Ctor, meta) {
3543
3574
  // field declaration
3544
3575
  if (process.env.NODE_ENV !== 'production') {
3545
3576
  validateFieldDecoratedWithApi(Ctor, fieldName, descriptor);
3546
- }
3577
+ } // [W-9927596] If a component has both a public property and a private setter/getter
3578
+ // with the same name, the property is defined as a public accessor. This branch is
3579
+ // only here for backward compatibility reasons.
3580
+
3547
3581
 
3548
- descriptor = createPublicPropertyDescriptor(fieldName);
3582
+ if (!isUndefined$1(descriptor) && !isUndefined$1(descriptor.get)) {
3583
+ descriptor = createPublicAccessorDescriptor(fieldName, descriptor);
3584
+ } else {
3585
+ descriptor = createPublicPropertyDescriptor(fieldName);
3586
+ }
3549
3587
  }
3550
3588
 
3551
3589
  apiFields[fieldName] = descriptor;
@@ -3625,9 +3663,16 @@ function registerDecorators(Ctor, meta) {
3625
3663
 
3626
3664
  if (process.env.NODE_ENV !== 'production') {
3627
3665
  validateObservedField(Ctor, fieldName, descriptor);
3628
- }
3666
+ } // [W-9927596] Only mark a field as observed whenever it isn't a duplicated public nor
3667
+ // tracked property. This is only here for backward compatibility purposes.
3668
+
3629
3669
 
3630
- observedFields[fieldName] = createObservedFieldPropertyDescriptor(fieldName);
3670
+ const isDuplicatePublicProp = !isUndefined$1(publicProps) && fieldName in publicProps;
3671
+ const isDuplicateTrackedProp = !isUndefined$1(track) && fieldName in track;
3672
+
3673
+ if (!isDuplicatePublicProp && !isDuplicateTrackedProp) {
3674
+ observedFields[fieldName] = createObservedFieldPropertyDescriptor(fieldName);
3675
+ }
3631
3676
  }
3632
3677
  }
3633
3678
 
@@ -4479,6 +4524,19 @@ function observeElementChildNodes(elm) {
4479
4524
 
4480
4525
  function setElementShadowToken(elm, token) {
4481
4526
  elm.$shadowToken$ = token;
4527
+ } // Set the scope token class for *.scoped.css styles
4528
+
4529
+
4530
+ function setScopeTokenClassIfNecessary(elm, owner) {
4531
+ const {
4532
+ cmpTemplate,
4533
+ context
4534
+ } = owner;
4535
+ const token = cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken;
4536
+
4537
+ if (!isUndefined$1(token) && context.hasScopedStyles) {
4538
+ owner.renderer.getClassList(elm).add(token);
4539
+ }
4482
4540
  }
4483
4541
 
4484
4542
  function updateNodeHook(oldVnode, vnode) {
@@ -4552,6 +4610,7 @@ function fallbackElmHook(elm, vnode) {
4552
4610
  const {
4553
4611
  owner
4554
4612
  } = vnode;
4613
+ setScopeTokenClassIfNecessary(elm, owner);
4555
4614
 
4556
4615
  if (owner.shadowMode === 1
4557
4616
  /* Synthetic */
@@ -4562,7 +4621,7 @@ function fallbackElmHook(elm, vnode) {
4562
4621
  }
4563
4622
  } = vnode;
4564
4623
  const {
4565
- shadowAttribute
4624
+ stylesheetToken
4566
4625
  } = owner.context;
4567
4626
 
4568
4627
  if (!isUndefined$1(context) && !isUndefined$1(context.lwc) && context.lwc.dom === "manual"
@@ -4574,7 +4633,7 @@ function fallbackElmHook(elm, vnode) {
4574
4633
  // into each element from the template, so they can be styled accordingly.
4575
4634
 
4576
4635
 
4577
- setElementShadowToken(elm, shadowAttribute);
4636
+ setElementShadowToken(elm, stylesheetToken);
4578
4637
  }
4579
4638
 
4580
4639
  if (process.env.NODE_ENV !== 'production') {
@@ -4663,16 +4722,17 @@ function createViewModelHook(elm, vnode) {
4663
4722
  ctor,
4664
4723
  owner
4665
4724
  } = vnode;
4725
+ setScopeTokenClassIfNecessary(elm, owner);
4666
4726
 
4667
4727
  if (owner.shadowMode === 1
4668
4728
  /* Synthetic */
4669
4729
  ) {
4670
4730
  const {
4671
- shadowAttribute
4731
+ stylesheetToken
4672
4732
  } = owner.context; // when running in synthetic shadow mode, we need to set the shadowToken value
4673
4733
  // into each element from the template, so they can be styled accordingly.
4674
4734
 
4675
- setElementShadowToken(elm, shadowAttribute);
4735
+ setElementShadowToken(elm, stylesheetToken);
4676
4736
  }
4677
4737
 
4678
4738
  const def = getComponentInternalDef(ctor);
@@ -4972,13 +5032,19 @@ const CustomElementHook = {
4972
5032
 
4973
5033
  function linkNodeToShadow(elm, owner) {
4974
5034
  const {
5035
+ renderer,
5036
+ renderMode,
4975
5037
  shadowMode
4976
5038
  } = owner; // TODO [#1164]: this should eventually be done by the polyfill directly
4977
5039
 
4978
- if (shadowMode === 1
4979
- /* Synthetic */
4980
- ) {
4981
- elm[KEY__SHADOW_RESOLVER] = getRenderRoot(owner)[KEY__SHADOW_RESOLVER];
5040
+ if (renderer.isSyntheticShadowDefined) {
5041
+ if (shadowMode === 1
5042
+ /* Synthetic */
5043
+ || renderMode === 0
5044
+ /* Light */
5045
+ ) {
5046
+ elm[KEY__SHADOW_RESOLVER] = getRenderRoot(owner)[KEY__SHADOW_RESOLVER];
5047
+ }
4982
5048
  }
4983
5049
  }
4984
5050
 
@@ -5324,14 +5390,11 @@ function gid(id) {
5324
5390
 
5325
5391
  const {
5326
5392
  idx,
5327
- renderMode,
5328
5393
  shadowMode
5329
5394
  } = vmBeingRendered;
5330
5395
 
5331
5396
  if (shadowMode === 1
5332
5397
  /* Synthetic */
5333
- && renderMode === 1
5334
- /* Shadow */
5335
5398
  ) {
5336
5399
  return StringReplace.call(id, /\S+/g, id => `${id}-${idx}`);
5337
5400
  }
@@ -5360,14 +5423,11 @@ function fid(url) {
5360
5423
 
5361
5424
  const {
5362
5425
  idx,
5363
- renderMode,
5364
5426
  shadowMode
5365
5427
  } = vmBeingRendered; // Apply transformation only for fragment-only-urls, and only in shadow DOM
5366
5428
 
5367
5429
  if (shadowMode === 1
5368
5430
  /* Synthetic */
5369
- && renderMode === 1
5370
- /* Shadow */
5371
5431
  && /^#/.test(url)) {
5372
5432
  return `${url}-${idx}`;
5373
5433
  }
@@ -5468,6 +5528,10 @@ var api = /*#__PURE__*/Object.freeze({
5468
5528
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
5469
5529
  */
5470
5530
 
5531
+ function makeHostToken(token) {
5532
+ return `${token}-host`;
5533
+ }
5534
+
5471
5535
  function createInlineStyleVNode(content) {
5472
5536
  return h('style', {
5473
5537
  key: 'style',
@@ -5477,59 +5541,100 @@ function createInlineStyleVNode(content) {
5477
5541
  }, [t(content)]);
5478
5542
  }
5479
5543
 
5480
- function updateSyntheticShadowAttributes(vm, template) {
5544
+ function updateStylesheetToken(vm, template) {
5481
5545
  const {
5482
5546
  elm,
5483
5547
  context,
5484
5548
  renderer,
5485
- renderMode
5549
+ renderMode,
5550
+ shadowMode
5486
5551
  } = vm;
5487
5552
  const {
5488
5553
  stylesheets: newStylesheets,
5489
- stylesheetTokens: newStylesheetTokens
5554
+ stylesheetToken: newStylesheetToken
5490
5555
  } = template;
5491
- let newTokens; // Reset the styling token applied to the host element.
5556
+ const isSyntheticShadow = renderMode === 1
5557
+ /* Shadow */
5558
+ && shadowMode === 1
5559
+ /* Synthetic */
5560
+ ;
5561
+ const {
5562
+ hasScopedStyles
5563
+ } = context;
5564
+ let newToken;
5565
+ let newHasTokenInClass;
5566
+ let newHasTokenInAttribute; // Reset the styling token applied to the host element.
5567
+
5568
+ const {
5569
+ stylesheetToken: oldToken,
5570
+ hasTokenInClass: oldHasTokenInClass,
5571
+ hasTokenInAttribute: oldHasTokenInAttribute
5572
+ } = context;
5492
5573
 
5493
- const oldHostAttribute = context.hostAttribute;
5574
+ if (oldHasTokenInClass) {
5575
+ renderer.getClassList(elm).remove(makeHostToken(oldToken));
5576
+ }
5494
5577
 
5495
- if (!isUndefined$1(oldHostAttribute)) {
5496
- renderer.removeAttribute(elm, oldHostAttribute);
5578
+ if (oldHasTokenInAttribute) {
5579
+ renderer.removeAttribute(elm, makeHostToken(oldToken));
5497
5580
  } // Apply the new template styling token to the host element, if the new template has any
5498
- // associated stylesheets.
5581
+ // associated stylesheets. In the case of light DOM, also ensure there is at least one scoped stylesheet.
5499
5582
 
5500
5583
 
5501
- if (!isUndefined$1(newStylesheets) && newStylesheets.length !== 0 && renderMode === 1
5502
- /* Shadow */
5503
- ) {
5504
- newTokens = newStylesheetTokens;
5505
- }
5584
+ if (!isUndefined$1(newStylesheets) && newStylesheets.length !== 0) {
5585
+ newToken = newStylesheetToken;
5586
+ } // Set the new styling token on the host element
5587
+
5588
+
5589
+ if (!isUndefined$1(newToken)) {
5590
+ if (hasScopedStyles) {
5591
+ renderer.getClassList(elm).add(makeHostToken(newToken));
5592
+ newHasTokenInClass = true;
5593
+ }
5506
5594
 
5507
- if (!isUndefined$1(newTokens)) {
5508
- renderer.setAttribute(elm, newTokens.hostAttribute, '');
5595
+ if (isSyntheticShadow) {
5596
+ renderer.setAttribute(elm, makeHostToken(newToken), '');
5597
+ newHasTokenInAttribute = true;
5598
+ }
5509
5599
  } // Update the styling tokens present on the context object.
5510
5600
 
5511
5601
 
5512
- context.hostAttribute = newTokens === null || newTokens === void 0 ? void 0 : newTokens.hostAttribute;
5513
- context.shadowAttribute = newTokens === null || newTokens === void 0 ? void 0 : newTokens.shadowAttribute;
5602
+ context.stylesheetToken = newToken;
5603
+ context.hasTokenInClass = newHasTokenInClass;
5604
+ context.hasTokenInAttribute = newHasTokenInAttribute;
5514
5605
  }
5515
5606
 
5516
- function evaluateStylesheetsContent(stylesheets, hostSelector, shadowSelector, nativeShadow) {
5607
+ function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
5517
5608
  const content = [];
5518
5609
 
5519
5610
  for (let i = 0; i < stylesheets.length; i++) {
5520
5611
  let stylesheet = stylesheets[i];
5521
5612
 
5522
5613
  if (isArray$1(stylesheet)) {
5523
- ArrayPush$1.apply(content, evaluateStylesheetsContent(stylesheet, hostSelector, shadowSelector, nativeShadow));
5614
+ ArrayPush$1.apply(content, evaluateStylesheetsContent(stylesheet, stylesheetToken, vm));
5524
5615
  } else {
5525
5616
  if (process.env.NODE_ENV !== 'production') {
5526
5617
  // in dev-mode, we support hot swapping of stylesheet, which means that
5527
5618
  // the component instance might be attempting to use an old version of
5528
5619
  // the stylesheet, while internally, we have a replacement for it.
5529
5620
  stylesheet = getStyleOrSwappedStyle(stylesheet);
5530
- }
5621
+ } // Use the actual `:host` selector if we're rendering global CSS for light DOM, or if we're rendering
5622
+ // native shadow DOM. Synthetic shadow DOM never uses `:host`.
5623
+
5531
5624
 
5532
- ArrayPush$1.call(content, stylesheet(hostSelector, shadowSelector, nativeShadow));
5625
+ const isScopedCss = stylesheet[KEY__SCOPED_CSS];
5626
+ const useActualHostSelector = vm.renderMode === 0
5627
+ /* Light */
5628
+ ? !isScopedCss : vm.shadowMode === 0
5629
+ /* Native */
5630
+ ; // Apply the scope token only if the stylesheet itself is scoped, or if we're rendering synthetic shadow.
5631
+
5632
+ const scopeToken = isScopedCss || vm.shadowMode === 1
5633
+ /* Synthetic */
5634
+ && vm.renderMode === 1
5635
+ /* Shadow */
5636
+ ? stylesheetToken : undefined;
5637
+ ArrayPush$1.call(content, stylesheet(useActualHostSelector, scopeToken));
5533
5638
  }
5534
5639
  }
5535
5640
 
@@ -5539,37 +5644,36 @@ function evaluateStylesheetsContent(stylesheets, hostSelector, shadowSelector, n
5539
5644
  function getStylesheetsContent(vm, template) {
5540
5645
  const {
5541
5646
  stylesheets,
5542
- stylesheetTokens
5647
+ stylesheetToken
5543
5648
  } = template;
5544
- const {
5545
- renderMode,
5546
- shadowMode
5547
- } = vm;
5548
5649
  let content = [];
5549
5650
 
5550
5651
  if (!isUndefined$1(stylesheets) && stylesheets.length !== 0) {
5551
- let hostSelector;
5552
- let shadowSelector; // Scoping with the tokens is only necessary for synthetic shadow. For both
5553
- // light DOM elements and native shadow, we just render the CSS as-is.
5652
+ content = evaluateStylesheetsContent(stylesheets, stylesheetToken, vm);
5653
+ }
5654
+
5655
+ return content;
5656
+ } // It might be worth caching this to avoid doing the lookup repeatedly, but
5657
+ // perf testing has not shown it to be a huge improvement yet:
5658
+ // https://github.com/salesforce/lwc/pull/2460#discussion_r691208892
5659
+
5554
5660
 
5555
- if (renderMode === 1
5661
+ function getNearestNativeShadowComponent(vm) {
5662
+ let owner = vm;
5663
+
5664
+ while (!isNull(owner)) {
5665
+ if (owner.renderMode === 1
5556
5666
  /* Shadow */
5557
- && shadowMode === 1
5558
- /* Synthetic */
5559
- && !isUndefined$1(stylesheetTokens)) {
5560
- hostSelector = `[${stylesheetTokens.hostAttribute}]`;
5561
- shadowSelector = `[${stylesheetTokens.shadowAttribute}]`;
5562
- } else {
5563
- hostSelector = '';
5564
- shadowSelector = '';
5667
+ && owner.shadowMode === 0
5668
+ /* Native */
5669
+ ) {
5670
+ return owner;
5565
5671
  }
5566
5672
 
5567
- content = evaluateStylesheetsContent(stylesheets, hostSelector, shadowSelector, shadowMode === 0
5568
- /* Native */
5569
- );
5673
+ owner = owner.owner;
5570
5674
  }
5571
5675
 
5572
- return content;
5676
+ return owner;
5573
5677
  }
5574
5678
 
5575
5679
  function createStylesheet(vm, stylesheets) {
@@ -5587,13 +5691,26 @@ function createStylesheet(vm, stylesheets) {
5587
5691
  for (let i = 0; i < stylesheets.length; i++) {
5588
5692
  renderer.insertGlobalStylesheet(stylesheets[i]);
5589
5693
  }
5590
-
5591
- return null;
5592
- } else {
5593
- // native shadow or light DOM
5694
+ } else if (renderer.ssr) {
5695
+ // native shadow or light DOM, SSR
5594
5696
  const combinedStylesheetContent = ArrayJoin.call(stylesheets, '\n');
5595
5697
  return createInlineStyleVNode(combinedStylesheetContent);
5698
+ } else {
5699
+ // native shadow or light DOM, DOM renderer
5700
+ const root = getNearestNativeShadowComponent(vm);
5701
+ const isGlobal = isNull(root);
5702
+
5703
+ for (let i = 0; i < stylesheets.length; i++) {
5704
+ if (isGlobal) {
5705
+ renderer.insertGlobalStylesheet(stylesheets[i]);
5706
+ } else {
5707
+ // local level
5708
+ renderer.insertStylesheet(stylesheets[i], root.cmpRoot);
5709
+ }
5710
+ }
5596
5711
  }
5712
+
5713
+ return null;
5597
5714
  }
5598
5715
  /*
5599
5716
  * Copyright (c) 2018, salesforce.com, inc.
@@ -5799,8 +5916,7 @@ function evaluateTemplate(vm, html) {
5799
5916
  context,
5800
5917
  cmpSlots,
5801
5918
  cmpTemplate,
5802
- tro,
5803
- shadowMode
5919
+ tro
5804
5920
  } = vm;
5805
5921
  tro.observe(() => {
5806
5922
  // Reset the cache memoizer for template when needed.
@@ -5825,15 +5941,12 @@ function evaluateTemplate(vm, html) {
5825
5941
 
5826
5942
  vm.cmpTemplate = html; // Create a brand new template cache for the swapped templated.
5827
5943
 
5828
- context.tplCache = create(null); // Update the synthetic shadow attributes on the host element if necessary.
5944
+ context.tplCache = create(null); // Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
5829
5945
 
5830
- if (shadowMode === 1
5831
- /* Synthetic */
5832
- ) {
5833
- updateSyntheticShadowAttributes(vm, html);
5834
- } // Evaluate, create stylesheet and cache the produced VNode for future
5835
- // re-rendering.
5946
+ context.hasScopedStyles = computeHasScopedStyles(html); // Update the scoping token on the host element.
5836
5947
 
5948
+ updateStylesheetToken(vm, html); // Evaluate, create stylesheet and cache the produced VNode for future
5949
+ // re-rendering.
5837
5950
 
5838
5951
  const stylesheetsContent = getStylesheetsContent(vm, html);
5839
5952
  context.styleVNode = stylesheetsContent.length === 0 ? null : createStylesheet(vm, stylesheetsContent);
@@ -5875,6 +5988,22 @@ function evaluateTemplate(vm, html) {
5875
5988
 
5876
5989
  return vnodes;
5877
5990
  }
5991
+
5992
+ function computeHasScopedStyles(template) {
5993
+ const {
5994
+ stylesheets
5995
+ } = template;
5996
+
5997
+ if (!isUndefined$1(stylesheets)) {
5998
+ for (let i = 0; i < stylesheets.length; i++) {
5999
+ if (isTrue(stylesheets[i][KEY__SCOPED_CSS])) {
6000
+ return true;
6001
+ }
6002
+ }
6003
+ }
6004
+
6005
+ return false;
6006
+ }
5878
6007
  /*
5879
6008
  * Copyright (c) 2018, salesforce.com, inc.
5880
6009
  * All rights reserved.
@@ -6146,7 +6275,6 @@ function invokeServiceHook(vm, cbs) {
6146
6275
  */
6147
6276
 
6148
6277
 
6149
- const isNativeShadowRootDefined = _globalThis[KEY__IS_NATIVE_SHADOW_ROOT_DEFINED];
6150
6278
  let idx = 0;
6151
6279
  /** The internal slot used to associate different objects the engine manipulates with the VM */
6152
6280
 
@@ -6255,29 +6383,6 @@ function getNearestShadowAncestor(vm) {
6255
6383
  return ancestor;
6256
6384
  }
6257
6385
 
6258
- function assertNotSyntheticComposedWithinNative(vm) {
6259
- const isSynthetic = vm.renderMode === 1
6260
- /* Shadow */
6261
- && vm.shadowMode === 1
6262
- /* Synthetic */
6263
- ;
6264
-
6265
- if (!isSynthetic) {
6266
- return;
6267
- }
6268
-
6269
- const ancestor = getNearestShadowAncestor(vm);
6270
-
6271
- if (!isNull(ancestor)) {
6272
- // Any native shadow component being an ancestor of a synthetic shadow component is disallowed.
6273
- assert.isFalse(ancestor.renderMode === 1
6274
- /* Shadow */
6275
- && ancestor.shadowMode === 0
6276
- /* Native */
6277
- , `${getComponentTag(vm)} (synthetic shadow DOM) cannot be composed inside of ${getComponentTag(ancestor)} (native shadow DOM), because synthetic-within-native composition is disallowed`);
6278
- }
6279
- }
6280
-
6281
6386
  function createVM(elm, def, options) {
6282
6387
  const {
6283
6388
  mode,
@@ -6285,22 +6390,6 @@ function createVM(elm, def, options) {
6285
6390
  renderer,
6286
6391
  tagName
6287
6392
  } = options;
6288
- let shadowMode;
6289
-
6290
- if (renderer.syntheticShadow) {
6291
- shadowMode = def.shadowSupportMode === "any"
6292
- /* Any */
6293
- && isNativeShadowRootDefined ? 0
6294
- /* Native */
6295
- : 1
6296
- /* Synthetic */
6297
- ;
6298
- } else {
6299
- shadowMode = 0
6300
- /* Native */
6301
- ;
6302
- }
6303
-
6304
6393
  const vm = {
6305
6394
  elm,
6306
6395
  def,
@@ -6323,10 +6412,12 @@ function createVM(elm, def, options) {
6323
6412
  oar: create(null),
6324
6413
  cmpTemplate: null,
6325
6414
  renderMode: def.renderMode,
6326
- shadowMode,
6415
+ shadowMode: null,
6327
6416
  context: {
6328
- hostAttribute: undefined,
6329
- shadowAttribute: undefined,
6417
+ stylesheetToken: undefined,
6418
+ hasTokenInClass: undefined,
6419
+ hasTokenInAttribute: undefined,
6420
+ hasScopedStyles: undefined,
6330
6421
  styleVNode: null,
6331
6422
  tplCache: EmptyObject,
6332
6423
  wiredConnecting: EmptyArray,
@@ -6339,26 +6430,87 @@ function createVM(elm, def, options) {
6339
6430
  setHook,
6340
6431
  getHook
6341
6432
  };
6433
+ vm.shadowMode = computeShadowMode(vm);
6342
6434
  vm.tro = getTemplateReactiveObserver(vm);
6343
6435
 
6344
6436
  if (process.env.NODE_ENV !== 'production') {
6345
6437
  vm.toString = () => {
6346
6438
  return `[object:vm ${def.name} (${vm.idx})]`;
6347
6439
  };
6348
-
6349
- assertNotSyntheticComposedWithinNative(vm);
6350
6440
  } // Create component instance associated to the vm and the element.
6351
6441
 
6352
6442
 
6353
6443
  invokeComponentConstructor(vm, def.ctor); // Initializing the wire decorator per instance only when really needed
6354
6444
 
6355
- if (isFalse(renderer.ssr) && hasWireAdapters(vm)) {
6445
+ if (hasWireAdapters(vm)) {
6356
6446
  installWireAdapters(vm);
6357
6447
  }
6358
6448
 
6359
6449
  return vm;
6360
6450
  }
6361
6451
 
6452
+ function computeShadowMode(vm) {
6453
+ const {
6454
+ def,
6455
+ renderer
6456
+ } = vm;
6457
+ const {
6458
+ isNativeShadowDefined,
6459
+ isSyntheticShadowDefined
6460
+ } = renderer;
6461
+ let shadowMode;
6462
+
6463
+ if (isSyntheticShadowDefined) {
6464
+ if (def.renderMode === 0
6465
+ /* Light */
6466
+ ) {
6467
+ // ShadowMode.Native implies "not synthetic shadow" which is consistent with how
6468
+ // everything defaults to native when the synthetic shadow polyfill is unavailable.
6469
+ shadowMode = 0
6470
+ /* Native */
6471
+ ;
6472
+ } else if (isNativeShadowDefined) {
6473
+ if (def.shadowSupportMode === "any"
6474
+ /* Any */
6475
+ ) {
6476
+ shadowMode = 0
6477
+ /* Native */
6478
+ ;
6479
+ } else {
6480
+ const shadowAncestor = getNearestShadowAncestor(vm);
6481
+
6482
+ if (!isNull(shadowAncestor) && shadowAncestor.shadowMode === 0
6483
+ /* Native */
6484
+ ) {
6485
+ // Transitive support for native Shadow DOM. A component in native mode
6486
+ // transitively opts all of its descendants into native.
6487
+ shadowMode = 0
6488
+ /* Native */
6489
+ ;
6490
+ } else {
6491
+ // Synthetic if neither this component nor any of its ancestors are configured
6492
+ // to be native.
6493
+ shadowMode = 1
6494
+ /* Synthetic */
6495
+ ;
6496
+ }
6497
+ }
6498
+ } else {
6499
+ // Synthetic if there is no native Shadow DOM support.
6500
+ shadowMode = 1
6501
+ /* Synthetic */
6502
+ ;
6503
+ }
6504
+ } else {
6505
+ // Native if the synthetic shadow polyfill is unavailable.
6506
+ shadowMode = 0
6507
+ /* Native */
6508
+ ;
6509
+ }
6510
+
6511
+ return shadowMode;
6512
+ }
6513
+
6362
6514
  function assertIsVM(obj) {
6363
6515
  if (isNull(obj) || !isObject(obj) || !('cmpRoot' in obj)) {
6364
6516
  throw new TypeError(`${obj} is not a VM.`);
@@ -7100,11 +7252,14 @@ function installWireAdapters(vm) {
7100
7252
  ArrayPush$1.call(wiredConnecting, () => {
7101
7253
  connector.connect();
7102
7254
 
7103
- if (hasDynamicParams) {
7104
- Promise.resolve().then(computeConfigAndUpdate);
7105
- } else {
7106
- computeConfigAndUpdate();
7255
+ if (!runtimeFlags.ENABLE_WIRE_SYNC_EMIT) {
7256
+ if (hasDynamicParams) {
7257
+ Promise.resolve().then(computeConfigAndUpdate);
7258
+ return;
7259
+ }
7107
7260
  }
7261
+
7262
+ computeConfigAndUpdate();
7108
7263
  });
7109
7264
  ArrayPush$1.call(wiredDisconnecting, () => {
7110
7265
  connector.disconnect();
@@ -7211,7 +7366,7 @@ function readonly(obj) {
7211
7366
 
7212
7367
  return reactiveMembrane.getReadOnlyProxy(obj);
7213
7368
  }
7214
- /* version: 2.3.4 */
7369
+ /* version: 2.5.1 */
7215
7370
 
7216
7371
  /*
7217
7372
  * Copyright (c) 2018, salesforce.com, inc.
@@ -7233,6 +7388,10 @@ if (process.env.NODE_ENV === 'development') {
7233
7388
  }
7234
7389
 
7235
7390
  const globalStylesheetsParentElement = document.head || document.body || document;
7391
+ const supportsConstructableStyleSheets = isFunction$1(CSSStyleSheet.prototype.replaceSync);
7392
+ const styleElements = create(null);
7393
+ const styleSheets = create(null);
7394
+ const nodesToStyleSheets = new WeakMap();
7236
7395
  let getCustomElement, defineCustomElement, HTMLElementConstructor;
7237
7396
 
7238
7397
  function isCustomElementRegistryAvailable() {
@@ -7259,6 +7418,52 @@ function isCustomElementRegistryAvailable() {
7259
7418
  }
7260
7419
  }
7261
7420
 
7421
+ function insertConstructableStyleSheet(content, target) {
7422
+ // It's important for CSSStyleSheets to be unique based on their content, so that
7423
+ // `shadowRoot.adoptedStyleSheets.includes(sheet)` works.
7424
+ let styleSheet = styleSheets[content];
7425
+
7426
+ if (isUndefined$1(styleSheet)) {
7427
+ styleSheet = new CSSStyleSheet();
7428
+ styleSheet.replaceSync(content);
7429
+ styleSheets[content] = styleSheet;
7430
+ }
7431
+
7432
+ if (!target.adoptedStyleSheets.includes(styleSheet)) {
7433
+ target.adoptedStyleSheets = [...target.adoptedStyleSheets, styleSheet];
7434
+ }
7435
+ }
7436
+
7437
+ function insertStyleElement(content, target) {
7438
+ // Avoid inserting duplicate `<style>`s
7439
+ let sheets = nodesToStyleSheets.get(target);
7440
+
7441
+ if (isUndefined$1(sheets)) {
7442
+ sheets = create(null);
7443
+ nodesToStyleSheets.set(target, sheets);
7444
+ }
7445
+
7446
+ if (sheets[content]) {
7447
+ return;
7448
+ }
7449
+
7450
+ sheets[content] = true; // This `<style>` may be repeated multiple times in the DOM, so cache it. It's a bit
7451
+ // faster to call `cloneNode()` on an existing node than to recreate it every time.
7452
+
7453
+ let elm = styleElements[content];
7454
+
7455
+ if (isUndefined$1(elm)) {
7456
+ elm = document.createElement('style');
7457
+ elm.type = 'text/css';
7458
+ elm.textContent = content;
7459
+ styleElements[content] = elm;
7460
+ } else {
7461
+ elm = elm.cloneNode(true);
7462
+ }
7463
+
7464
+ target.appendChild(elm);
7465
+ }
7466
+
7262
7467
  if (isCustomElementRegistryAvailable()) {
7263
7468
  getCustomElement = customElements.get.bind(customElements);
7264
7469
  defineCustomElement = customElements.define.bind(customElements);
@@ -7304,7 +7509,8 @@ if (isCustomElementRegistryAvailable()) {
7304
7509
 
7305
7510
  const renderer = {
7306
7511
  ssr: false,
7307
- syntheticShadow: hasOwnProperty$1.call(Element.prototype, KEY__SHADOW_TOKEN),
7512
+ isNativeShadowDefined: _globalThis[KEY__IS_NATIVE_SHADOW_ROOT_DEFINED],
7513
+ isSyntheticShadowDefined: hasOwnProperty$1.call(Element.prototype, KEY__SHADOW_TOKEN),
7308
7514
 
7309
7515
  createElement(tagName, namespace) {
7310
7516
  return isUndefined$1(namespace) ? document.createElement(tagName) : document.createElementNS(namespace, tagName);
@@ -7427,6 +7633,15 @@ const renderer = {
7427
7633
  globalStylesheetsParentElement.appendChild(elm);
7428
7634
  },
7429
7635
 
7636
+ insertStylesheet(content, target) {
7637
+ if (supportsConstructableStyleSheets) {
7638
+ insertConstructableStyleSheet(content, target);
7639
+ } else {
7640
+ // Fall back to <style> element
7641
+ insertStyleElement(content, target);
7642
+ }
7643
+ },
7644
+
7430
7645
  assertInstanceOfHTMLElement(elm, msg) {
7431
7646
  assert.invariant(elm instanceof HTMLElement, msg);
7432
7647
  },
@@ -7656,7 +7871,7 @@ function isNodeFromTemplate(node) {
7656
7871
  return false;
7657
7872
  }
7658
7873
 
7659
- if (renderer.syntheticShadow) {
7874
+ if (renderer.isSyntheticShadowDefined) {
7660
7875
  // TODO [#1252]: old behavior that is still used by some pieces of the platform,
7661
7876
  // specifically, nodes inserted manually on places where `lwc:dom="manual"` directive is not
7662
7877
  // used, will be considered global elements.
@@ -7709,6 +7924,6 @@ defineProperty(LightningElement, 'CustomElementConstructor', {
7709
7924
  });
7710
7925
  freeze(LightningElement);
7711
7926
  seal(LightningElement.prototype);
7712
- /* version: 2.3.4 */
7927
+ /* version: 2.5.1 */
7713
7928
 
7714
7929
  export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, deprecatedBuildCustomElementConstructor as buildCustomElementConstructor, createContextProvider, createElement, getComponentConstructor, getComponentDef, isComponentConstructor, isNodeFromTemplate, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setFeatureFlag, setFeatureFlagForTest, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };