@lwc/engine-core 2.32.0 → 2.33.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.
@@ -1,7 +1,8 @@
1
1
  /* proxy-compat-disable */
2
2
  import { lwcRuntimeFlags } from '@lwc/features';
3
3
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
4
- import { seal, create, isUndefined as isUndefined$1, isFunction as isFunction$1, ArrayPush as ArrayPush$1, ArrayIndexOf, ArraySplice, StringToLowerCase, isNull, ArrayJoin, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, freeze, assert, KEY__SYNTHETIC_MODE, isFalse, isTrue, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, htmlAttributeToProperty, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, isNumber, StringReplace, noop, ArrayUnshift, ArrayFilter, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
4
+ import { seal, create, isUndefined as isUndefined$1, isFunction as isFunction$1, ArrayPush as ArrayPush$1, ArrayIndexOf, ArraySplice, StringToLowerCase, isNull, ArrayJoin, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, freeze, assert, 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, isNumber, StringReplace, noop, ArrayUnshift, ArrayFilter, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
5
+ import { applyAriaReflection } from '@lwc/aria-reflection';
5
6
 
6
7
  /*
7
8
  * Copyright (c) 2018, salesforce.com, inc.
@@ -561,7 +562,7 @@ function patchElementWithRestrictions(elm, options) {
561
562
  }),
562
563
  };
563
564
  // Apply extra restriction related to DOM manipulation if the element is not a portal.
564
- if (!options.isLight && !options.isPortal) {
565
+ if (!options.isLight && options.isSynthetic && !options.isPortal) {
565
566
  const { appendChild, insertBefore, removeChild, replaceChild } = elm;
566
567
  const originalNodeValueDescriptor = getPropertyDescriptor(elm, 'nodeValue');
567
568
  const originalInnerHTMLDescriptor = getPropertyDescriptor(elm, 'innerHTML');
@@ -1409,46 +1410,51 @@ function markLockerLiveObject(obj) {
1409
1410
  * for the Base Lightning Element, it also include the reactivity bit, so the standard property is reactive.
1410
1411
  */
1411
1412
  function createBridgeToElementDescriptor(propName, descriptor) {
1412
- const { get, set, enumerable, configurable } = descriptor;
1413
- if (!isFunction$1(get)) {
1414
- if (process.env.NODE_ENV !== 'production') {
1415
- assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard getter.`);
1416
- }
1417
- throw new TypeError();
1413
+ const {
1414
+ get,
1415
+ set,
1416
+ enumerable,
1417
+ configurable
1418
+ } = descriptor;
1419
+ if (!isFunction$1(get)) {
1420
+ if (process.env.NODE_ENV !== 'production') {
1421
+ assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard getter.`);
1418
1422
  }
1419
- if (!isFunction$1(set)) {
1423
+ throw new TypeError();
1424
+ }
1425
+ if (!isFunction$1(set)) {
1426
+ if (process.env.NODE_ENV !== 'production') {
1427
+ assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard setter.`);
1428
+ }
1429
+ throw new TypeError();
1430
+ }
1431
+ return {
1432
+ enumerable,
1433
+ configurable,
1434
+ get() {
1435
+ const vm = getAssociatedVM(this);
1436
+ if (isBeingConstructed(vm)) {
1420
1437
  if (process.env.NODE_ENV !== 'production') {
1421
- assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard setter.`);
1438
+ logError(`The value of property \`${propName}\` can't be read from the constructor because the owner component hasn't set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1422
1439
  }
1423
- throw new TypeError();
1440
+ return;
1441
+ }
1442
+ componentValueObserved(vm, propName);
1443
+ return get.call(vm.elm);
1444
+ },
1445
+ set(newValue) {
1446
+ const vm = getAssociatedVM(this);
1447
+ if (process.env.NODE_ENV !== 'production') {
1448
+ const vmBeingRendered = getVMBeingRendered();
1449
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${propName}`);
1450
+ assert.invariant(!isUpdatingTemplate, `When updating the template of ${vmBeingRendered}, one of the accessors used by the template has side effects on the state of ${vm}.${propName}`);
1451
+ assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1452
+ assert.invariant(!isObject(newValue) || isNull(newValue), `Invalid value "${newValue}" for "${propName}" of ${vm}. Value cannot be an object, must be a primitive value.`);
1453
+ }
1454
+ updateComponentValue(vm, propName, newValue);
1455
+ return set.call(vm.elm, newValue);
1424
1456
  }
1425
- return {
1426
- enumerable,
1427
- configurable,
1428
- get() {
1429
- const vm = getAssociatedVM(this);
1430
- if (isBeingConstructed(vm)) {
1431
- if (process.env.NODE_ENV !== 'production') {
1432
- logError(`The value of property \`${propName}\` can't be read from the constructor because the owner component hasn't set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1433
- }
1434
- return;
1435
- }
1436
- componentValueObserved(vm, propName);
1437
- return get.call(vm.elm);
1438
- },
1439
- set(newValue) {
1440
- const vm = getAssociatedVM(this);
1441
- if (process.env.NODE_ENV !== 'production') {
1442
- const vmBeingRendered = getVMBeingRendered();
1443
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${propName}`);
1444
- assert.invariant(!isUpdatingTemplate, `When updating the template of ${vmBeingRendered}, one of the accessors used by the template has side effects on the state of ${vm}.${propName}`);
1445
- assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1446
- assert.invariant(!isObject(newValue) || isNull(newValue), `Invalid value "${newValue}" for "${propName}" of ${vm}. Value cannot be an object, must be a primitive value.`);
1447
- }
1448
- updateComponentValue(vm, propName, newValue);
1449
- return set.call(vm.elm, newValue);
1450
- },
1451
- };
1457
+ };
1452
1458
  }
1453
1459
  const EMPTY_REFS = freeze(create(null));
1454
1460
  const refsCache = new WeakMap();
@@ -1458,345 +1464,444 @@ const refsCache = new WeakMap();
1458
1464
  **/
1459
1465
  // @ts-ignore
1460
1466
  const LightningElement = function () {
1461
- // This should be as performant as possible, while any initialization should be done lazily
1462
- if (isNull(vmBeingConstructed)) {
1463
- // Thrown when doing something like `new LightningElement()` or
1464
- // `class Foo extends LightningElement {}; new Foo()`
1465
- throw new TypeError('Illegal constructor');
1466
- }
1467
- const vm = vmBeingConstructed;
1468
- const { def, elm } = vm;
1469
- const { bridge } = def;
1467
+ // This should be as performant as possible, while any initialization should be done lazily
1468
+ if (isNull(vmBeingConstructed)) {
1469
+ // Thrown when doing something like `new LightningElement()` or
1470
+ // `class Foo extends LightningElement {}; new Foo()`
1471
+ throw new TypeError('Illegal constructor');
1472
+ }
1473
+ const vm = vmBeingConstructed;
1474
+ const {
1475
+ def,
1476
+ elm
1477
+ } = vm;
1478
+ const {
1479
+ bridge
1480
+ } = def;
1481
+ if (process.env.NODE_ENV !== 'production') {
1482
+ const {
1483
+ assertInstanceOfHTMLElement
1484
+ } = vm.renderer;
1485
+ assertInstanceOfHTMLElement(vm.elm, `Component creation requires a DOM element to be associated to ${vm}.`);
1486
+ }
1487
+ const component = this;
1488
+ setPrototypeOf(elm, bridge.prototype);
1489
+ vm.component = this;
1490
+ // Locker hooks assignment. When the LWC engine run with Locker, Locker intercepts all the new
1491
+ // component creation and passes hooks to instrument all the component interactions with the
1492
+ // engine. We are intentionally hiding this argument from the formal API of LightningElement
1493
+ // because we don't want folks to know about it just yet.
1494
+ if (arguments.length === 1) {
1495
+ const {
1496
+ callHook,
1497
+ setHook,
1498
+ getHook
1499
+ } = arguments[0];
1500
+ vm.callHook = callHook;
1501
+ vm.setHook = setHook;
1502
+ vm.getHook = getHook;
1503
+ }
1504
+ markLockerLiveObject(this);
1505
+ // Linking elm, shadow root and component with the VM.
1506
+ associateVM(component, vm);
1507
+ associateVM(elm, vm);
1508
+ if (vm.renderMode === 1 /* RenderMode.Shadow */) {
1509
+ vm.renderRoot = doAttachShadow(vm);
1510
+ } else {
1511
+ vm.renderRoot = elm;
1512
+ }
1513
+ // Adding extra guard rails in DEV mode.
1514
+ if (process.env.NODE_ENV !== 'production') {
1515
+ patchCustomElementWithRestrictions(elm);
1516
+ patchComponentWithRestrictions(component);
1517
+ }
1518
+ return this;
1519
+ };
1520
+ function doAttachShadow(vm) {
1521
+ const {
1522
+ elm,
1523
+ mode,
1524
+ shadowMode,
1525
+ def: {
1526
+ ctor
1527
+ },
1528
+ renderer: {
1529
+ attachShadow
1530
+ }
1531
+ } = vm;
1532
+ const shadowRoot = attachShadow(elm, {
1533
+ [KEY__SYNTHETIC_MODE]: shadowMode === 1 /* ShadowMode.Synthetic */,
1534
+ delegatesFocus: Boolean(ctor.delegatesFocus),
1535
+ mode
1536
+ });
1537
+ vm.shadowRoot = shadowRoot;
1538
+ associateVM(shadowRoot, vm);
1539
+ if (process.env.NODE_ENV !== 'production') {
1540
+ patchShadowRootWithRestrictions(shadowRoot);
1541
+ }
1542
+ return shadowRoot;
1543
+ }
1544
+ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1545
+ if (isBeingConstructed(vm)) {
1546
+ logError(`this.${methodOrPropName} 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.`);
1547
+ }
1548
+ }
1549
+ // @ts-ignore
1550
+ LightningElement.prototype = {
1551
+ constructor: LightningElement,
1552
+ dispatchEvent(event) {
1553
+ const vm = getAssociatedVM(this);
1554
+ const {
1555
+ elm,
1556
+ renderer: {
1557
+ dispatchEvent
1558
+ }
1559
+ } = vm;
1560
+ return dispatchEvent(elm, event);
1561
+ },
1562
+ addEventListener(type, listener, options) {
1563
+ const vm = getAssociatedVM(this);
1564
+ const {
1565
+ elm,
1566
+ renderer: {
1567
+ addEventListener
1568
+ }
1569
+ } = vm;
1470
1570
  if (process.env.NODE_ENV !== 'production') {
1471
- const { assertInstanceOfHTMLElement } = vm.renderer;
1472
- assertInstanceOfHTMLElement(vm.elm, `Component creation requires a DOM element to be associated to ${vm}.`);
1473
- }
1474
- const component = this;
1475
- setPrototypeOf(elm, bridge.prototype);
1476
- vm.component = this;
1477
- // Locker hooks assignment. When the LWC engine run with Locker, Locker intercepts all the new
1478
- // component creation and passes hooks to instrument all the component interactions with the
1479
- // engine. We are intentionally hiding this argument from the formal API of LightningElement
1480
- // because we don't want folks to know about it just yet.
1481
- if (arguments.length === 1) {
1482
- const { callHook, setHook, getHook } = arguments[0];
1483
- vm.callHook = callHook;
1484
- vm.setHook = setHook;
1485
- vm.getHook = getHook;
1486
- }
1487
- markLockerLiveObject(this);
1488
- // Linking elm, shadow root and component with the VM.
1489
- associateVM(component, vm);
1490
- associateVM(elm, vm);
1491
- if (vm.renderMode === 1 /* RenderMode.Shadow */) {
1492
- vm.renderRoot = doAttachShadow(vm);
1571
+ const vmBeingRendered = getVMBeingRendered();
1572
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm} by adding an event listener for "${type}".`);
1573
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm} by adding an event listener for "${type}".`);
1574
+ assert.invariant(isFunction$1(listener), `Invalid second argument for this.addEventListener() in ${vm} for event "${type}". Expected an EventListener but received ${listener}.`);
1575
+ }
1576
+ const wrappedListener = getWrappedComponentsListener(vm, listener);
1577
+ addEventListener(elm, type, wrappedListener, options);
1578
+ },
1579
+ removeEventListener(type, listener, options) {
1580
+ const vm = getAssociatedVM(this);
1581
+ const {
1582
+ elm,
1583
+ renderer: {
1584
+ removeEventListener
1585
+ }
1586
+ } = vm;
1587
+ const wrappedListener = getWrappedComponentsListener(vm, listener);
1588
+ removeEventListener(elm, type, wrappedListener, options);
1589
+ },
1590
+ hasAttribute(name) {
1591
+ const vm = getAssociatedVM(this);
1592
+ const {
1593
+ elm,
1594
+ renderer: {
1595
+ getAttribute
1596
+ }
1597
+ } = vm;
1598
+ return !isNull(getAttribute(elm, name));
1599
+ },
1600
+ hasAttributeNS(namespace, name) {
1601
+ const vm = getAssociatedVM(this);
1602
+ const {
1603
+ elm,
1604
+ renderer: {
1605
+ getAttribute
1606
+ }
1607
+ } = vm;
1608
+ return !isNull(getAttribute(elm, name, namespace));
1609
+ },
1610
+ removeAttribute(name) {
1611
+ const vm = getAssociatedVM(this);
1612
+ const {
1613
+ elm,
1614
+ renderer: {
1615
+ removeAttribute
1616
+ }
1617
+ } = vm;
1618
+ unlockAttribute(elm, name);
1619
+ removeAttribute(elm, name);
1620
+ lockAttribute();
1621
+ },
1622
+ removeAttributeNS(namespace, name) {
1623
+ const {
1624
+ elm,
1625
+ renderer: {
1626
+ removeAttribute
1627
+ }
1628
+ } = getAssociatedVM(this);
1629
+ unlockAttribute(elm, name);
1630
+ removeAttribute(elm, name, namespace);
1631
+ lockAttribute();
1632
+ },
1633
+ getAttribute(name) {
1634
+ const vm = getAssociatedVM(this);
1635
+ const {
1636
+ elm
1637
+ } = vm;
1638
+ const {
1639
+ getAttribute
1640
+ } = vm.renderer;
1641
+ return getAttribute(elm, name);
1642
+ },
1643
+ getAttributeNS(namespace, name) {
1644
+ const vm = getAssociatedVM(this);
1645
+ const {
1646
+ elm
1647
+ } = vm;
1648
+ const {
1649
+ getAttribute
1650
+ } = vm.renderer;
1651
+ return getAttribute(elm, name, namespace);
1652
+ },
1653
+ setAttribute(name, value) {
1654
+ const vm = getAssociatedVM(this);
1655
+ const {
1656
+ elm,
1657
+ renderer: {
1658
+ setAttribute
1659
+ }
1660
+ } = vm;
1661
+ if (process.env.NODE_ENV !== 'production') {
1662
+ assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1663
+ }
1664
+ unlockAttribute(elm, name);
1665
+ setAttribute(elm, name, value);
1666
+ lockAttribute();
1667
+ },
1668
+ setAttributeNS(namespace, name, value) {
1669
+ const vm = getAssociatedVM(this);
1670
+ const {
1671
+ elm,
1672
+ renderer: {
1673
+ setAttribute
1674
+ }
1675
+ } = vm;
1676
+ if (process.env.NODE_ENV !== 'production') {
1677
+ assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1678
+ }
1679
+ unlockAttribute(elm, name);
1680
+ setAttribute(elm, name, value, namespace);
1681
+ lockAttribute();
1682
+ },
1683
+ getBoundingClientRect() {
1684
+ const vm = getAssociatedVM(this);
1685
+ const {
1686
+ elm,
1687
+ renderer: {
1688
+ getBoundingClientRect
1689
+ }
1690
+ } = vm;
1691
+ if (process.env.NODE_ENV !== 'production') {
1692
+ warnIfInvokedDuringConstruction(vm, 'getBoundingClientRect()');
1493
1693
  }
1494
- else {
1495
- vm.renderRoot = elm;
1694
+ return getBoundingClientRect(elm);
1695
+ },
1696
+ get isConnected() {
1697
+ const vm = getAssociatedVM(this);
1698
+ const {
1699
+ elm,
1700
+ renderer: {
1701
+ isConnected
1702
+ }
1703
+ } = vm;
1704
+ return isConnected(elm);
1705
+ },
1706
+ get classList() {
1707
+ const vm = getAssociatedVM(this);
1708
+ const {
1709
+ elm,
1710
+ renderer: {
1711
+ getClassList
1712
+ }
1713
+ } = vm;
1714
+ if (process.env.NODE_ENV !== 'production') {
1715
+ // TODO [#1290]: this still fails in dev but works in production, eventually, we should
1716
+ // just throw in all modes
1717
+ assert.isFalse(isBeingConstructed(vm), `Failed to construct ${vm}: The result must not have attributes. Adding or tampering with classname in constructor is not allowed in a web component, use connectedCallback() instead.`);
1718
+ }
1719
+ return getClassList(elm);
1720
+ },
1721
+ get template() {
1722
+ const vm = getAssociatedVM(this);
1723
+ if (process.env.NODE_ENV !== 'production') {
1724
+ if (vm.renderMode === 0 /* RenderMode.Light */) {
1725
+ logError('`this.template` returns null for light DOM components. Since there is no shadow, the rendered content can be accessed via `this` itself. e.g. instead of `this.template.querySelector`, use `this.querySelector`.');
1726
+ }
1727
+ }
1728
+ return vm.shadowRoot;
1729
+ },
1730
+ get refs() {
1731
+ const vm = getAssociatedVM(this);
1732
+ if (isUpdatingTemplate) {
1733
+ if (process.env.NODE_ENV !== 'production') {
1734
+ logError(`this.refs should not be called while ${getComponentTag(vm)} is rendering. Use this.refs only when the DOM is stable, e.g. in renderedCallback().`);
1735
+ }
1736
+ // If the template is in the process of being updated, then we don't want to go through the normal
1737
+ // process of returning the refs and caching them, because the state of the refs is unstable.
1738
+ // This can happen if e.g. a template contains `<div class={foo}></div>` and `foo` is computed
1739
+ // based on `this.refs.bar`.
1740
+ return;
1496
1741
  }
1497
- // Adding extra guard rails in DEV mode.
1498
1742
  if (process.env.NODE_ENV !== 'production') {
1499
- patchCustomElementWithRestrictions(elm);
1500
- patchComponentWithRestrictions(component);
1743
+ warnIfInvokedDuringConstruction(vm, 'refs');
1501
1744
  }
1502
- return this;
1503
- };
1504
- function doAttachShadow(vm) {
1505
- const { elm, mode, shadowMode, def: { ctor }, renderer: { attachShadow }, } = vm;
1506
- const shadowRoot = attachShadow(elm, {
1507
- [KEY__SYNTHETIC_MODE]: shadowMode === 1 /* ShadowMode.Synthetic */,
1508
- delegatesFocus: Boolean(ctor.delegatesFocus),
1509
- mode,
1745
+ const {
1746
+ refVNodes,
1747
+ hasRefVNodes,
1748
+ cmpTemplate
1749
+ } = vm;
1750
+ // If the `cmpTemplate` is null, that means that the template has not been rendered yet. Most likely this occurs
1751
+ // if `this.refs` is called during the `connectedCallback` phase. The DOM elements have not been rendered yet,
1752
+ // so log a warning. Note we also check `isBeingConstructed()` to avoid a double warning (due to
1753
+ // `warnIfInvokedDuringConstruction` above).
1754
+ if (process.env.NODE_ENV !== 'production' && isNull(cmpTemplate) && !isBeingConstructed(vm)) {
1755
+ logError(`this.refs is undefined for ${getComponentTag(vm)}. This is either because the attached template has no "lwc:ref" directive, or this.refs was ` + `invoked before renderedCallback(). Use this.refs only when the referenced HTML elements have ` + `been rendered to the DOM, such as within renderedCallback() or disconnectedCallback().`);
1756
+ }
1757
+ // For backwards compatibility with component written before template refs
1758
+ // were introduced, we return undefined if the template has no refs defined
1759
+ // anywhere. This fixes components that may want to add an expando called `refs`
1760
+ // and are checking if it exists with `if (this.refs)` before adding it.
1761
+ // Note it is not sufficient to just check if `refVNodes` is null or empty,
1762
+ // because a template may have `lwc:ref` defined within a falsy `if:true` block.
1763
+ if (!hasRefVNodes) {
1764
+ return;
1765
+ }
1766
+ // For templates that are using `lwc:ref`, if there are no refs currently available
1767
+ // (e.g. refs inside of a falsy `if:true` block), we return an empty object.
1768
+ if (isNull(refVNodes)) {
1769
+ return EMPTY_REFS;
1770
+ }
1771
+ // The refNodes can be cached based on the refVNodes, since the refVNodes
1772
+ // are recreated from scratch every time the template is rendered.
1773
+ // This happens with `vm.refVNodes = null` in `template.ts` in `@lwc/engine-core`.
1774
+ let refs = refsCache.get(refVNodes);
1775
+ if (isUndefined$1(refs)) {
1776
+ refs = create(null);
1777
+ for (const key of keys(refVNodes)) {
1778
+ refs[key] = refVNodes[key].elm;
1779
+ }
1780
+ freeze(refs);
1781
+ refsCache.set(refVNodes, refs);
1782
+ }
1783
+ return refs;
1784
+ },
1785
+ // For backwards compat, we allow component authors to set `refs` as an expando
1786
+ set refs(value) {
1787
+ defineProperty(this, 'refs', {
1788
+ configurable: true,
1789
+ enumerable: true,
1790
+ writable: true,
1791
+ value
1510
1792
  });
1511
- vm.shadowRoot = shadowRoot;
1512
- associateVM(shadowRoot, vm);
1793
+ },
1794
+ get shadowRoot() {
1795
+ // From within the component instance, the shadowRoot is always reported as "closed".
1796
+ // Authors should rely on this.template instead.
1797
+ return null;
1798
+ },
1799
+ get children() {
1800
+ const vm = getAssociatedVM(this);
1801
+ const renderer = vm.renderer;
1513
1802
  if (process.env.NODE_ENV !== 'production') {
1514
- patchShadowRootWithRestrictions(shadowRoot);
1803
+ warnIfInvokedDuringConstruction(vm, 'children');
1515
1804
  }
1516
- return shadowRoot;
1517
- }
1518
- function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1519
- if (isBeingConstructed(vm)) {
1520
- logError(`this.${methodOrPropName} 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.`);
1805
+ return renderer.getChildren(vm.elm);
1806
+ },
1807
+ get childNodes() {
1808
+ const vm = getAssociatedVM(this);
1809
+ const renderer = vm.renderer;
1810
+ if (process.env.NODE_ENV !== 'production') {
1811
+ warnIfInvokedDuringConstruction(vm, 'childNodes');
1521
1812
  }
1522
- }
1523
- // @ts-ignore
1524
- LightningElement.prototype = {
1525
- constructor: LightningElement,
1526
- dispatchEvent(event) {
1527
- const vm = getAssociatedVM(this);
1528
- const { elm, renderer: { dispatchEvent }, } = vm;
1529
- return dispatchEvent(elm, event);
1530
- },
1531
- addEventListener(type, listener, options) {
1532
- const vm = getAssociatedVM(this);
1533
- const { elm, renderer: { addEventListener }, } = vm;
1534
- if (process.env.NODE_ENV !== 'production') {
1535
- const vmBeingRendered = getVMBeingRendered();
1536
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm} by adding an event listener for "${type}".`);
1537
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm} by adding an event listener for "${type}".`);
1538
- assert.invariant(isFunction$1(listener), `Invalid second argument for this.addEventListener() in ${vm} for event "${type}". Expected an EventListener but received ${listener}.`);
1539
- }
1540
- const wrappedListener = getWrappedComponentsListener(vm, listener);
1541
- addEventListener(elm, type, wrappedListener, options);
1542
- },
1543
- removeEventListener(type, listener, options) {
1544
- const vm = getAssociatedVM(this);
1545
- const { elm, renderer: { removeEventListener }, } = vm;
1546
- const wrappedListener = getWrappedComponentsListener(vm, listener);
1547
- removeEventListener(elm, type, wrappedListener, options);
1548
- },
1549
- hasAttribute(name) {
1550
- const vm = getAssociatedVM(this);
1551
- const { elm, renderer: { getAttribute }, } = vm;
1552
- return !isNull(getAttribute(elm, name));
1553
- },
1554
- hasAttributeNS(namespace, name) {
1555
- const vm = getAssociatedVM(this);
1556
- const { elm, renderer: { getAttribute }, } = vm;
1557
- return !isNull(getAttribute(elm, name, namespace));
1558
- },
1559
- removeAttribute(name) {
1560
- const vm = getAssociatedVM(this);
1561
- const { elm, renderer: { removeAttribute }, } = vm;
1562
- unlockAttribute(elm, name);
1563
- removeAttribute(elm, name);
1564
- lockAttribute();
1565
- },
1566
- removeAttributeNS(namespace, name) {
1567
- const { elm, renderer: { removeAttribute }, } = getAssociatedVM(this);
1568
- unlockAttribute(elm, name);
1569
- removeAttribute(elm, name, namespace);
1570
- lockAttribute();
1571
- },
1572
- getAttribute(name) {
1573
- const vm = getAssociatedVM(this);
1574
- const { elm } = vm;
1575
- const { getAttribute } = vm.renderer;
1576
- return getAttribute(elm, name);
1577
- },
1578
- getAttributeNS(namespace, name) {
1579
- const vm = getAssociatedVM(this);
1580
- const { elm } = vm;
1581
- const { getAttribute } = vm.renderer;
1582
- return getAttribute(elm, name, namespace);
1583
- },
1584
- setAttribute(name, value) {
1585
- const vm = getAssociatedVM(this);
1586
- const { elm, renderer: { setAttribute }, } = vm;
1587
- if (process.env.NODE_ENV !== 'production') {
1588
- assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1589
- }
1590
- unlockAttribute(elm, name);
1591
- setAttribute(elm, name, value);
1592
- lockAttribute();
1593
- },
1594
- setAttributeNS(namespace, name, value) {
1595
- const vm = getAssociatedVM(this);
1596
- const { elm, renderer: { setAttribute }, } = vm;
1597
- if (process.env.NODE_ENV !== 'production') {
1598
- assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1599
- }
1600
- unlockAttribute(elm, name);
1601
- setAttribute(elm, name, value, namespace);
1602
- lockAttribute();
1603
- },
1604
- getBoundingClientRect() {
1605
- const vm = getAssociatedVM(this);
1606
- const { elm, renderer: { getBoundingClientRect }, } = vm;
1607
- if (process.env.NODE_ENV !== 'production') {
1608
- warnIfInvokedDuringConstruction(vm, 'getBoundingClientRect()');
1609
- }
1610
- return getBoundingClientRect(elm);
1611
- },
1612
- get isConnected() {
1613
- const vm = getAssociatedVM(this);
1614
- const { elm, renderer: { isConnected }, } = vm;
1615
- return isConnected(elm);
1616
- },
1617
- get classList() {
1618
- const vm = getAssociatedVM(this);
1619
- const { elm, renderer: { getClassList }, } = vm;
1620
- if (process.env.NODE_ENV !== 'production') {
1621
- // TODO [#1290]: this still fails in dev but works in production, eventually, we should
1622
- // just throw in all modes
1623
- assert.isFalse(isBeingConstructed(vm), `Failed to construct ${vm}: The result must not have attributes. Adding or tampering with classname in constructor is not allowed in a web component, use connectedCallback() instead.`);
1624
- }
1625
- return getClassList(elm);
1626
- },
1627
- get template() {
1628
- const vm = getAssociatedVM(this);
1629
- if (process.env.NODE_ENV !== 'production') {
1630
- if (vm.renderMode === 0 /* RenderMode.Light */) {
1631
- logError('`this.template` returns null for light DOM components. Since there is no shadow, the rendered content can be accessed via `this` itself. e.g. instead of `this.template.querySelector`, use `this.querySelector`.');
1632
- }
1633
- }
1634
- return vm.shadowRoot;
1635
- },
1636
- get refs() {
1637
- const vm = getAssociatedVM(this);
1638
- if (isUpdatingTemplate) {
1639
- if (process.env.NODE_ENV !== 'production') {
1640
- logError(`this.refs should not be called while ${getComponentTag(vm)} is rendering. Use this.refs only when the DOM is stable, e.g. in renderedCallback().`);
1641
- }
1642
- // If the template is in the process of being updated, then we don't want to go through the normal
1643
- // process of returning the refs and caching them, because the state of the refs is unstable.
1644
- // This can happen if e.g. a template contains `<div class={foo}></div>` and `foo` is computed
1645
- // based on `this.refs.bar`.
1646
- return;
1647
- }
1648
- if (process.env.NODE_ENV !== 'production') {
1649
- warnIfInvokedDuringConstruction(vm, 'refs');
1650
- }
1651
- const { refVNodes, hasRefVNodes, cmpTemplate } = vm;
1652
- // If the `cmpTemplate` is null, that means that the template has not been rendered yet. Most likely this occurs
1653
- // if `this.refs` is called during the `connectedCallback` phase. The DOM elements have not been rendered yet,
1654
- // so log a warning. Note we also check `isBeingConstructed()` to avoid a double warning (due to
1655
- // `warnIfInvokedDuringConstruction` above).
1656
- if (process.env.NODE_ENV !== 'production' &&
1657
- isNull(cmpTemplate) &&
1658
- !isBeingConstructed(vm)) {
1659
- logError(`this.refs is undefined for ${getComponentTag(vm)}. This is either because the attached template has no "lwc:ref" directive, or this.refs was ` +
1660
- `invoked before renderedCallback(). Use this.refs only when the referenced HTML elements have ` +
1661
- `been rendered to the DOM, such as within renderedCallback() or disconnectedCallback().`);
1662
- }
1663
- // For backwards compatibility with component written before template refs
1664
- // were introduced, we return undefined if the template has no refs defined
1665
- // anywhere. This fixes components that may want to add an expando called `refs`
1666
- // and are checking if it exists with `if (this.refs)` before adding it.
1667
- // Note it is not sufficient to just check if `refVNodes` is null or empty,
1668
- // because a template may have `lwc:ref` defined within a falsy `if:true` block.
1669
- if (!hasRefVNodes) {
1670
- return;
1671
- }
1672
- // For templates that are using `lwc:ref`, if there are no refs currently available
1673
- // (e.g. refs inside of a falsy `if:true` block), we return an empty object.
1674
- if (isNull(refVNodes)) {
1675
- return EMPTY_REFS;
1676
- }
1677
- // The refNodes can be cached based on the refVNodes, since the refVNodes
1678
- // are recreated from scratch every time the template is rendered.
1679
- // This happens with `vm.refVNodes = null` in `template.ts` in `@lwc/engine-core`.
1680
- let refs = refsCache.get(refVNodes);
1681
- if (isUndefined$1(refs)) {
1682
- refs = create(null);
1683
- for (const key of keys(refVNodes)) {
1684
- refs[key] = refVNodes[key].elm;
1685
- }
1686
- freeze(refs);
1687
- refsCache.set(refVNodes, refs);
1688
- }
1689
- return refs;
1690
- },
1691
- // For backwards compat, we allow component authors to set `refs` as an expando
1692
- set refs(value) {
1693
- defineProperty(this, 'refs', {
1694
- configurable: true,
1695
- enumerable: true,
1696
- writable: true,
1697
- value,
1698
- });
1699
- },
1700
- get shadowRoot() {
1701
- // From within the component instance, the shadowRoot is always reported as "closed".
1702
- // Authors should rely on this.template instead.
1703
- return null;
1704
- },
1705
- get children() {
1706
- const vm = getAssociatedVM(this);
1707
- const renderer = vm.renderer;
1708
- if (process.env.NODE_ENV !== 'production') {
1709
- warnIfInvokedDuringConstruction(vm, 'children');
1710
- }
1711
- return renderer.getChildren(vm.elm);
1712
- },
1713
- get childNodes() {
1714
- const vm = getAssociatedVM(this);
1715
- const renderer = vm.renderer;
1716
- if (process.env.NODE_ENV !== 'production') {
1717
- warnIfInvokedDuringConstruction(vm, 'childNodes');
1718
- }
1719
- return renderer.getChildNodes(vm.elm);
1720
- },
1721
- get firstChild() {
1722
- const vm = getAssociatedVM(this);
1723
- const renderer = vm.renderer;
1724
- if (process.env.NODE_ENV !== 'production') {
1725
- warnIfInvokedDuringConstruction(vm, 'firstChild');
1726
- }
1727
- return renderer.getFirstChild(vm.elm);
1728
- },
1729
- get firstElementChild() {
1730
- const vm = getAssociatedVM(this);
1731
- const renderer = vm.renderer;
1732
- if (process.env.NODE_ENV !== 'production') {
1733
- warnIfInvokedDuringConstruction(vm, 'firstElementChild');
1734
- }
1735
- return renderer.getFirstElementChild(vm.elm);
1736
- },
1737
- get lastChild() {
1738
- const vm = getAssociatedVM(this);
1739
- const renderer = vm.renderer;
1740
- if (process.env.NODE_ENV !== 'production') {
1741
- warnIfInvokedDuringConstruction(vm, 'lastChild');
1742
- }
1743
- return renderer.getLastChild(vm.elm);
1744
- },
1745
- get lastElementChild() {
1746
- const vm = getAssociatedVM(this);
1747
- const renderer = vm.renderer;
1748
- if (process.env.NODE_ENV !== 'production') {
1749
- warnIfInvokedDuringConstruction(vm, 'lastElementChild');
1750
- }
1751
- return renderer.getLastElementChild(vm.elm);
1752
- },
1753
- render() {
1754
- const vm = getAssociatedVM(this);
1755
- return vm.def.template;
1756
- },
1757
- toString() {
1758
- const vm = getAssociatedVM(this);
1759
- return `[object ${vm.def.name}]`;
1760
- },
1813
+ return renderer.getChildNodes(vm.elm);
1814
+ },
1815
+ get firstChild() {
1816
+ const vm = getAssociatedVM(this);
1817
+ const renderer = vm.renderer;
1818
+ if (process.env.NODE_ENV !== 'production') {
1819
+ warnIfInvokedDuringConstruction(vm, 'firstChild');
1820
+ }
1821
+ return renderer.getFirstChild(vm.elm);
1822
+ },
1823
+ get firstElementChild() {
1824
+ const vm = getAssociatedVM(this);
1825
+ const renderer = vm.renderer;
1826
+ if (process.env.NODE_ENV !== 'production') {
1827
+ warnIfInvokedDuringConstruction(vm, 'firstElementChild');
1828
+ }
1829
+ return renderer.getFirstElementChild(vm.elm);
1830
+ },
1831
+ get lastChild() {
1832
+ const vm = getAssociatedVM(this);
1833
+ const renderer = vm.renderer;
1834
+ if (process.env.NODE_ENV !== 'production') {
1835
+ warnIfInvokedDuringConstruction(vm, 'lastChild');
1836
+ }
1837
+ return renderer.getLastChild(vm.elm);
1838
+ },
1839
+ get lastElementChild() {
1840
+ const vm = getAssociatedVM(this);
1841
+ const renderer = vm.renderer;
1842
+ if (process.env.NODE_ENV !== 'production') {
1843
+ warnIfInvokedDuringConstruction(vm, 'lastElementChild');
1844
+ }
1845
+ return renderer.getLastElementChild(vm.elm);
1846
+ },
1847
+ render() {
1848
+ const vm = getAssociatedVM(this);
1849
+ return vm.def.template;
1850
+ },
1851
+ toString() {
1852
+ const vm = getAssociatedVM(this);
1853
+ return `[object ${vm.def.name}]`;
1854
+ }
1761
1855
  };
1762
1856
  const queryAndChildGetterDescriptors = create(null);
1763
- const queryMethods = [
1764
- 'getElementsByClassName',
1765
- 'getElementsByTagName',
1766
- 'querySelector',
1767
- 'querySelectorAll',
1768
- ];
1857
+ const queryMethods = ['getElementsByClassName', 'getElementsByTagName', 'querySelector', 'querySelectorAll'];
1769
1858
  // Generic passthrough for query APIs on HTMLElement to the relevant Renderer APIs
1770
1859
  for (const queryMethod of queryMethods) {
1771
- queryAndChildGetterDescriptors[queryMethod] = {
1772
- value(arg) {
1773
- const vm = getAssociatedVM(this);
1774
- const { elm, renderer } = vm;
1775
- if (process.env.NODE_ENV !== 'production') {
1776
- warnIfInvokedDuringConstruction(vm, `${queryMethod}()`);
1777
- }
1778
- return renderer[queryMethod](elm, arg);
1779
- },
1780
- configurable: true,
1781
- enumerable: true,
1782
- writable: true,
1783
- };
1860
+ queryAndChildGetterDescriptors[queryMethod] = {
1861
+ value(arg) {
1862
+ const vm = getAssociatedVM(this);
1863
+ const {
1864
+ elm,
1865
+ renderer
1866
+ } = vm;
1867
+ if (process.env.NODE_ENV !== 'production') {
1868
+ warnIfInvokedDuringConstruction(vm, `${queryMethod}()`);
1869
+ }
1870
+ return renderer[queryMethod](elm, arg);
1871
+ },
1872
+ configurable: true,
1873
+ enumerable: true,
1874
+ writable: true
1875
+ };
1784
1876
  }
1785
1877
  defineProperties(LightningElement.prototype, queryAndChildGetterDescriptors);
1786
1878
  const lightningBasedDescriptors = create(null);
1787
1879
  for (const propName in HTMLElementOriginalDescriptors) {
1788
- lightningBasedDescriptors[propName] = createBridgeToElementDescriptor(propName, HTMLElementOriginalDescriptors[propName]);
1880
+ lightningBasedDescriptors[propName] = createBridgeToElementDescriptor(propName, HTMLElementOriginalDescriptors[propName]);
1789
1881
  }
1790
1882
  defineProperties(LightningElement.prototype, lightningBasedDescriptors);
1883
+ function applyAriaReflectionToLightningElement() {
1884
+ // If ARIA reflection is not applied globally to Element.prototype, or if we are running server-side,
1885
+ // apply it to LightningElement.prototype.
1886
+ // This allows `this.aria*` property accessors to work from inside a component, and to reflect `aria-*` attrs.
1887
+ applyAriaReflection(LightningElement.prototype);
1888
+ }
1889
+ // The reason for this odd if/else branching is limitations in @lwc/features:
1890
+ // https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#only-works-with-if-statements
1891
+ if (lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
1892
+ applyAriaReflectionToLightningElement();
1893
+ } else if (!process.env.IS_BROWSER) {
1894
+ applyAriaReflectionToLightningElement();
1895
+ }
1791
1896
  defineProperty(LightningElement, 'CustomElementConstructor', {
1792
- get() {
1793
- // If required, a runtime-specific implementation must be defined.
1794
- throw new ReferenceError('The current runtime does not support CustomElementConstructor.');
1795
- },
1796
- configurable: true,
1897
+ get() {
1898
+ // If required, a runtime-specific implementation must be defined.
1899
+ throw new ReferenceError('The current runtime does not support CustomElementConstructor.');
1900
+ },
1901
+ configurable: true
1797
1902
  });
1798
1903
  if (process.env.NODE_ENV !== 'production') {
1799
- patchLightningElementPrototypeWithRestrictions(LightningElement.prototype);
1904
+ patchLightningElementPrototypeWithRestrictions(LightningElement.prototype);
1800
1905
  }
1801
1906
 
1802
1907
  function createObservedFieldPropertyDescriptor(key) {
@@ -1815,60 +1920,6 @@ function createObservedFieldPropertyDescriptor(key) {
1815
1920
  };
1816
1921
  }
1817
1922
 
1818
- /*
1819
- * Copyright (c) 2018, salesforce.com, inc.
1820
- * All rights reserved.
1821
- * SPDX-License-Identifier: MIT
1822
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1823
- */
1824
- const DUMMY_ACCESSOR_REACTIVE_OBSERVER = {
1825
- observe(job) {
1826
- job();
1827
- },
1828
- reset() { },
1829
- link() { },
1830
- };
1831
- class AccessorReactiveObserver extends ReactiveObserver {
1832
- constructor(vm, set) {
1833
- super(() => {
1834
- if (isFalse(this.debouncing)) {
1835
- this.debouncing = true;
1836
- addCallbackToNextTick(() => {
1837
- if (isTrue(this.debouncing)) {
1838
- const { value } = this;
1839
- const { isDirty: dirtyStateBeforeSetterCall, component, idx } = vm;
1840
- set.call(component, value);
1841
- // de-bouncing after the call to the original setter to prevent
1842
- // infinity loop if the setter itself is mutating things that
1843
- // were accessed during the previous invocation.
1844
- this.debouncing = false;
1845
- if (isTrue(vm.isDirty) && isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1846
- // immediate rehydration due to a setter driven mutation, otherwise
1847
- // the component will get rendered on the second tick, which it is not
1848
- // desirable.
1849
- rerenderVM(vm);
1850
- }
1851
- }
1852
- });
1853
- }
1854
- });
1855
- this.debouncing = false;
1856
- }
1857
- reset(value) {
1858
- super.reset();
1859
- this.debouncing = false;
1860
- if (arguments.length > 0) {
1861
- this.value = value;
1862
- }
1863
- }
1864
- }
1865
- function createAccessorReactiveObserver(vm, set) {
1866
- // On the server side, we don't need mutation tracking. Skipping it improves performance.
1867
- return process.env.IS_BROWSER
1868
- ? new AccessorReactiveObserver(vm, set)
1869
- : DUMMY_ACCESSOR_REACTIVE_OBSERVER;
1870
- }
1871
-
1872
1923
  /*
1873
1924
  * Copyright (c) 2018, salesforce.com, inc.
1874
1925
  * All rights reserved.
@@ -1876,90 +1927,71 @@ function createAccessorReactiveObserver(vm, set) {
1876
1927
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1877
1928
  */
1878
1929
  function api$1() {
1879
- if (process.env.NODE_ENV !== 'production') {
1880
- assert.fail(`@api decorator can only be used as a decorator function.`);
1881
- }
1882
- throw new Error();
1930
+ if (process.env.NODE_ENV !== 'production') {
1931
+ assert.fail(`@api decorator can only be used as a decorator function.`);
1932
+ }
1933
+ throw new Error();
1883
1934
  }
1884
1935
  function createPublicPropertyDescriptor(key) {
1885
- return {
1886
- get() {
1887
- const vm = getAssociatedVM(this);
1888
- if (isBeingConstructed(vm)) {
1889
- if (process.env.NODE_ENV !== 'production') {
1890
- logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1891
- }
1892
- return;
1893
- }
1894
- componentValueObserved(vm, key);
1895
- return vm.cmpProps[key];
1896
- },
1897
- set(newValue) {
1898
- const vm = getAssociatedVM(this);
1899
- if (process.env.NODE_ENV !== 'production') {
1900
- const vmBeingRendered = getVMBeingRendered();
1901
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1902
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1903
- }
1904
- vm.cmpProps[key] = newValue;
1905
- componentValueMutated(vm, key);
1906
- },
1907
- enumerable: true,
1908
- configurable: true
1909
- };
1936
+ return {
1937
+ get() {
1938
+ const vm = getAssociatedVM(this);
1939
+ if (isBeingConstructed(vm)) {
1940
+ if (process.env.NODE_ENV !== 'production') {
1941
+ logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1942
+ }
1943
+ return;
1944
+ }
1945
+ componentValueObserved(vm, key);
1946
+ return vm.cmpProps[key];
1947
+ },
1948
+ set(newValue) {
1949
+ const vm = getAssociatedVM(this);
1950
+ if (process.env.NODE_ENV !== 'production') {
1951
+ const vmBeingRendered = getVMBeingRendered();
1952
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1953
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1954
+ }
1955
+ vm.cmpProps[key] = newValue;
1956
+ componentValueMutated(vm, key);
1957
+ },
1958
+ enumerable: true,
1959
+ configurable: true,
1960
+ };
1910
1961
  }
1911
1962
  function createPublicAccessorDescriptor(key, descriptor) {
1912
- const {
1913
- get,
1914
- set,
1915
- enumerable,
1916
- configurable
1917
- } = descriptor;
1918
- if (!isFunction$1(get)) {
1919
- if (process.env.NODE_ENV !== 'production') {
1920
- assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
1921
- }
1922
- throw new Error();
1923
- }
1924
- return {
1925
- get() {
1926
- if (process.env.NODE_ENV !== 'production') {
1927
- // Assert that the this value is an actual Component with an associated VM.
1928
- getAssociatedVM(this);
1929
- }
1930
- return get.call(this);
1931
- },
1932
- set(newValue) {
1933
- const vm = getAssociatedVM(this);
1934
- if (process.env.NODE_ENV !== 'production') {
1935
- const vmBeingRendered = getVMBeingRendered();
1936
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1937
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1938
- }
1939
- if (set) {
1940
- if (lwcRuntimeFlags.ENABLE_REACTIVE_SETTER) {
1941
- let ro = vm.oar[key];
1942
- if (isUndefined$1(ro)) {
1943
- ro = vm.oar[key] = createAccessorReactiveObserver(vm, set);
1944
- }
1945
- // every time we invoke this setter from outside (through this wrapper setter)
1946
- // we should reset the value and then debounce just in case there is a pending
1947
- // invocation the next tick that is not longer relevant since the value is changing
1948
- // from outside.
1949
- ro.reset(newValue);
1950
- ro.observe(() => {
1951
- set.call(this, newValue);
1952
- });
1953
- } else {
1954
- set.call(this, newValue);
1963
+ const { get, set, enumerable, configurable } = descriptor;
1964
+ if (!isFunction$1(get)) {
1965
+ if (process.env.NODE_ENV !== 'production') {
1966
+ assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
1955
1967
  }
1956
- } else if (process.env.NODE_ENV !== 'production') {
1957
- assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
1958
- }
1959
- },
1960
- enumerable,
1961
- configurable
1962
- };
1968
+ throw new Error();
1969
+ }
1970
+ return {
1971
+ get() {
1972
+ if (process.env.NODE_ENV !== 'production') {
1973
+ // Assert that the this value is an actual Component with an associated VM.
1974
+ getAssociatedVM(this);
1975
+ }
1976
+ return get.call(this);
1977
+ },
1978
+ set(newValue) {
1979
+ const vm = getAssociatedVM(this);
1980
+ if (process.env.NODE_ENV !== 'production') {
1981
+ const vmBeingRendered = getVMBeingRendered();
1982
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1983
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1984
+ }
1985
+ if (set) {
1986
+ set.call(this, newValue);
1987
+ }
1988
+ else if (process.env.NODE_ENV !== 'production') {
1989
+ assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
1990
+ }
1991
+ },
1992
+ enumerable,
1993
+ configurable,
1994
+ };
1963
1995
  }
1964
1996
 
1965
1997
  /*
@@ -2285,12 +2317,6 @@ function checkVersionMismatch(func, type) {
2285
2317
  }
2286
2318
  }
2287
2319
 
2288
- /*
2289
- * Copyright (c) 2018, salesforce.com, inc.
2290
- * All rights reserved.
2291
- * SPDX-License-Identifier: MIT
2292
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2293
- */
2294
2320
  const signedTemplateSet = new Set();
2295
2321
  function defaultEmptyTemplate() {
2296
2322
  return [];
@@ -2308,32 +2334,6 @@ function registerTemplate(tpl) {
2308
2334
  checkVersionMismatch(tpl, 'template');
2309
2335
  }
2310
2336
  signedTemplateSet.add(tpl);
2311
- // FIXME[@W-10950976]: the template object should be frozen, and it should not be possible to set
2312
- // the stylesheets or stylesheetToken(s). For backwards compat, though, we shim stylesheetTokens
2313
- // on top of stylesheetToken for anyone who is accessing the old internal API.
2314
- // Details: https://salesforce.quip.com/v1rmAFu2cKAr
2315
- defineProperty(tpl, 'stylesheetTokens', {
2316
- enumerable: true,
2317
- configurable: true,
2318
- get() {
2319
- const { stylesheetToken } = this;
2320
- if (isUndefined$1(stylesheetToken)) {
2321
- return stylesheetToken;
2322
- }
2323
- // Shim for the old `stylesheetTokens` property
2324
- // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
2325
- return {
2326
- hostAttribute: `${stylesheetToken}-host`,
2327
- shadowAttribute: stylesheetToken,
2328
- };
2329
- },
2330
- set(value) {
2331
- // If the value is null or some other exotic object, you would be broken anyway in the past
2332
- // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
2333
- // However it may be undefined in newer versions of LWC, so we need to guard against that case.
2334
- this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
2335
- },
2336
- });
2337
2337
  // chaining this method as a way to wrap existing
2338
2338
  // assignment of templates easily, without too much transformation
2339
2339
  return tpl;
@@ -2361,138 +2361,161 @@ function sanitizeAttribute(tagName, namespaceUri, attrName, attrValue) {
2361
2361
  const cachedGetterByKey = create(null);
2362
2362
  const cachedSetterByKey = create(null);
2363
2363
  function createGetter(key) {
2364
- let fn = cachedGetterByKey[key];
2365
- if (isUndefined$1(fn)) {
2366
- fn = cachedGetterByKey[key] = function () {
2367
- const vm = getAssociatedVM(this);
2368
- const { getHook } = vm;
2369
- return getHook(vm.component, key);
2370
- };
2371
- }
2372
- return fn;
2364
+ let fn = cachedGetterByKey[key];
2365
+ if (isUndefined$1(fn)) {
2366
+ fn = cachedGetterByKey[key] = function () {
2367
+ const vm = getAssociatedVM(this);
2368
+ const {
2369
+ getHook
2370
+ } = vm;
2371
+ return getHook(vm.component, key);
2372
+ };
2373
+ }
2374
+ return fn;
2373
2375
  }
2374
2376
  function createSetter(key) {
2375
- let fn = cachedSetterByKey[key];
2376
- if (isUndefined$1(fn)) {
2377
- fn = cachedSetterByKey[key] = function (newValue) {
2378
- const vm = getAssociatedVM(this);
2379
- const { setHook } = vm;
2380
- newValue = getReadOnlyProxy(newValue);
2381
- setHook(vm.component, key, newValue);
2382
- };
2383
- }
2384
- return fn;
2377
+ let fn = cachedSetterByKey[key];
2378
+ if (isUndefined$1(fn)) {
2379
+ fn = cachedSetterByKey[key] = function (newValue) {
2380
+ const vm = getAssociatedVM(this);
2381
+ const {
2382
+ setHook
2383
+ } = vm;
2384
+ newValue = getReadOnlyProxy(newValue);
2385
+ setHook(vm.component, key, newValue);
2386
+ };
2387
+ }
2388
+ return fn;
2385
2389
  }
2386
2390
  function createMethodCaller(methodName) {
2387
- return function () {
2388
- const vm = getAssociatedVM(this);
2389
- const { callHook, component } = vm;
2390
- const fn = component[methodName];
2391
- return callHook(vm.component, fn, ArraySlice.call(arguments));
2392
- };
2391
+ return function () {
2392
+ const vm = getAssociatedVM(this);
2393
+ const {
2394
+ callHook,
2395
+ component
2396
+ } = vm;
2397
+ const fn = component[methodName];
2398
+ return callHook(vm.component, fn, ArraySlice.call(arguments));
2399
+ };
2393
2400
  }
2394
2401
  function createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback) {
2395
- return function attributeChangedCallback(attrName, oldValue, newValue) {
2396
- if (oldValue === newValue) {
2397
- // Ignore same values.
2398
- return;
2399
- }
2400
- const propName = attributeToPropMap[attrName];
2401
- if (isUndefined$1(propName)) {
2402
- if (!isUndefined$1(superAttributeChangedCallback)) {
2403
- // delegate unknown attributes to the super.
2404
- // Typescript does not like it when you treat the `arguments` object as an array
2405
- // @ts-ignore type-mismatch
2406
- superAttributeChangedCallback.apply(this, arguments);
2407
- }
2408
- return;
2409
- }
2410
- if (!isAttributeLocked(this, attrName)) {
2411
- // Ignore changes triggered by the engine itself during:
2412
- // * diffing when public props are attempting to reflect to the DOM
2413
- // * component via `this.setAttribute()`, should never update the prop
2414
- // Both cases, the setAttribute call is always wrapped by the unlocking of the
2415
- // attribute to be changed
2416
- return;
2417
- }
2418
- // Reflect attribute change to the corresponding property when changed from outside.
2419
- this[propName] = newValue;
2420
- };
2421
- }
2422
- function HTMLBridgeElementFactory(SuperClass, props, methods) {
2423
- let HTMLBridgeElement;
2424
- /**
2425
- * Modern browsers will have all Native Constructors as regular Classes
2426
- * and must be instantiated with the new keyword. In older browsers,
2427
- * specifically IE11, those are objects with a prototype property defined,
2428
- * since they are not supposed to be extended or instantiated with the
2429
- * new keyword. This forking logic supports both cases, specifically because
2430
- * wc.ts relies on the construction path of the bridges to create new
2431
- * fully qualifying web components.
2432
- */
2433
- if (isFunction$1(SuperClass)) {
2434
- HTMLBridgeElement = class extends SuperClass {
2435
- };
2436
- }
2437
- else {
2438
- HTMLBridgeElement = function () {
2439
- // Bridge classes are not supposed to be instantiated directly in
2440
- // browsers that do not support web components.
2441
- throw new TypeError('Illegal constructor');
2442
- };
2443
- // prototype inheritance dance
2444
- setPrototypeOf(HTMLBridgeElement, SuperClass);
2445
- setPrototypeOf(HTMLBridgeElement.prototype, SuperClass.prototype);
2446
- defineProperty(HTMLBridgeElement.prototype, 'constructor', {
2447
- writable: true,
2448
- configurable: true,
2449
- value: HTMLBridgeElement,
2450
- });
2402
+ return function attributeChangedCallback(attrName, oldValue, newValue) {
2403
+ if (oldValue === newValue) {
2404
+ // Ignore same values.
2405
+ return;
2451
2406
  }
2452
- // generating the hash table for attributes to avoid duplicate fields and facilitate validation
2453
- // and false positives in case of inheritance.
2454
- const attributeToPropMap = create(null);
2455
- const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
2456
- const { observedAttributes: superObservedAttributes = [] } = SuperClass;
2457
- const descriptors = create(null);
2458
- // expose getters and setters for each public props on the new Element Bridge
2459
- for (let i = 0, len = props.length; i < len; i += 1) {
2460
- const propName = props[i];
2461
- attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
2462
- descriptors[propName] = {
2463
- get: createGetter(propName),
2464
- set: createSetter(propName),
2465
- enumerable: true,
2466
- configurable: true,
2467
- };
2407
+ const propName = attributeToPropMap[attrName];
2408
+ if (isUndefined$1(propName)) {
2409
+ if (!isUndefined$1(superAttributeChangedCallback)) {
2410
+ // delegate unknown attributes to the super.
2411
+ // Typescript does not like it when you treat the `arguments` object as an array
2412
+ // @ts-ignore type-mismatch
2413
+ superAttributeChangedCallback.apply(this, arguments);
2414
+ }
2415
+ return;
2468
2416
  }
2469
- // expose public methods as props on the new Element Bridge
2470
- for (let i = 0, len = methods.length; i < len; i += 1) {
2471
- const methodName = methods[i];
2472
- descriptors[methodName] = {
2473
- value: createMethodCaller(methodName),
2474
- writable: true,
2475
- configurable: true,
2476
- };
2417
+ if (!isAttributeLocked(this, attrName)) {
2418
+ // Ignore changes triggered by the engine itself during:
2419
+ // * diffing when public props are attempting to reflect to the DOM
2420
+ // * component via `this.setAttribute()`, should never update the prop
2421
+ // Both cases, the setAttribute call is always wrapped by the unlocking of the
2422
+ // attribute to be changed
2423
+ return;
2477
2424
  }
2478
- // creating a new attributeChangedCallback per bridge because they are bound to the corresponding
2479
- // map of attributes to props. We do this after all other props and methods to avoid the possibility
2480
- // of getting overrule by a class declaration in user-land, and we make it non-writable, non-configurable
2481
- // to preserve this definition.
2482
- descriptors.attributeChangedCallback = {
2483
- value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
2425
+ // Reflect attribute change to the corresponding property when changed from outside.
2426
+ this[propName] = newValue;
2427
+ };
2428
+ }
2429
+ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2430
+ let HTMLBridgeElement;
2431
+ /**
2432
+ * Modern browsers will have all Native Constructors as regular Classes
2433
+ * and must be instantiated with the new keyword. In older browsers,
2434
+ * specifically IE11, those are objects with a prototype property defined,
2435
+ * since they are not supposed to be extended or instantiated with the
2436
+ * new keyword. This forking logic supports both cases, specifically because
2437
+ * wc.ts relies on the construction path of the bridges to create new
2438
+ * fully qualifying web components.
2439
+ */
2440
+ if (isFunction$1(SuperClass)) {
2441
+ HTMLBridgeElement = class extends SuperClass {};
2442
+ } else {
2443
+ HTMLBridgeElement = function () {
2444
+ // Bridge classes are not supposed to be instantiated directly in
2445
+ // browsers that do not support web components.
2446
+ throw new TypeError('Illegal constructor');
2484
2447
  };
2485
- // Specify attributes for which we want to reflect changes back to their corresponding
2486
- // properties via attributeChangedCallback.
2487
- defineProperty(HTMLBridgeElement, 'observedAttributes', {
2488
- get() {
2489
- return [...superObservedAttributes, ...keys(attributeToPropMap)];
2490
- },
2448
+ // prototype inheritance dance
2449
+ setPrototypeOf(HTMLBridgeElement, SuperClass);
2450
+ setPrototypeOf(HTMLBridgeElement.prototype, SuperClass.prototype);
2451
+ defineProperty(HTMLBridgeElement.prototype, 'constructor', {
2452
+ writable: true,
2453
+ configurable: true,
2454
+ value: HTMLBridgeElement
2491
2455
  });
2492
- defineProperties(HTMLBridgeElement.prototype, descriptors);
2493
- return HTMLBridgeElement;
2456
+ }
2457
+ // generating the hash table for attributes to avoid duplicate fields and facilitate validation
2458
+ // and false positives in case of inheritance.
2459
+ const attributeToPropMap = create(null);
2460
+ const {
2461
+ attributeChangedCallback: superAttributeChangedCallback
2462
+ } = SuperClass.prototype;
2463
+ const {
2464
+ observedAttributes: superObservedAttributes = []
2465
+ } = SuperClass;
2466
+ const descriptors = create(null);
2467
+ // expose getters and setters for each public props on the new Element Bridge
2468
+ for (let i = 0, len = props.length; i < len; i += 1) {
2469
+ const propName = props[i];
2470
+ attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
2471
+ descriptors[propName] = {
2472
+ get: createGetter(propName),
2473
+ set: createSetter(propName),
2474
+ enumerable: true,
2475
+ configurable: true
2476
+ };
2477
+ }
2478
+ // expose public methods as props on the new Element Bridge
2479
+ for (let i = 0, len = methods.length; i < len; i += 1) {
2480
+ const methodName = methods[i];
2481
+ descriptors[methodName] = {
2482
+ value: createMethodCaller(methodName),
2483
+ writable: true,
2484
+ configurable: true
2485
+ };
2486
+ }
2487
+ // creating a new attributeChangedCallback per bridge because they are bound to the corresponding
2488
+ // map of attributes to props. We do this after all other props and methods to avoid the possibility
2489
+ // of getting overrule by a class declaration in user-land, and we make it non-writable, non-configurable
2490
+ // to preserve this definition.
2491
+ descriptors.attributeChangedCallback = {
2492
+ value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback)
2493
+ };
2494
+ // Specify attributes for which we want to reflect changes back to their corresponding
2495
+ // properties via attributeChangedCallback.
2496
+ defineProperty(HTMLBridgeElement, 'observedAttributes', {
2497
+ get() {
2498
+ return [...superObservedAttributes, ...keys(attributeToPropMap)];
2499
+ }
2500
+ });
2501
+ defineProperties(HTMLBridgeElement.prototype, descriptors);
2502
+ return HTMLBridgeElement;
2494
2503
  }
2495
2504
  const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), []);
2505
+ if (process.env.IS_BROWSER) {
2506
+ // This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
2507
+ // so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
2508
+ // ARIA props outside the LightningElement
2509
+ if (lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
2510
+ // If ARIA reflection is not applied globally to Element.prototype, apply it to HTMLBridgeElement.prototype.
2511
+ // This allows `elm.aria*` property accessors to work from outside a component, and to reflect `aria-*` attrs.
2512
+ // This is especially important because the template compiler compiles aria-* attrs on components to aria* props
2513
+ //
2514
+ // Also note that we apply this to BaseBridgeElement.prototype to avoid excessively redefining property
2515
+ // accessors inside the HTMLBridgeElementFactory.
2516
+ applyAriaReflection(BaseBridgeElement.prototype);
2517
+ }
2518
+ }
2496
2519
  freeze(BaseBridgeElement);
2497
2520
  seal(BaseBridgeElement.prototype);
2498
2521
 
@@ -3874,11 +3897,13 @@ function applyDomManual(elm, vnode) {
3874
3897
  function applyElementRestrictions(elm, vnode) {
3875
3898
  var _a, _b;
3876
3899
  if (process.env.NODE_ENV !== 'production') {
3900
+ const isSynthetic = vnode.owner.shadowMode === 1 /* ShadowMode.Synthetic */;
3877
3901
  const isPortal = vnode.type === 2 /* VNodeType.Element */ && ((_b = (_a = vnode.data.context) === null || _a === void 0 ? void 0 : _a.lwc) === null || _b === void 0 ? void 0 : _b.dom) === "manual" /* LwcDomMode.Manual */;
3878
3902
  const isLight = vnode.owner.renderMode === 0 /* RenderMode.Light */;
3879
3903
  patchElementWithRestrictions(elm, {
3880
3904
  isPortal,
3881
- isLight
3905
+ isLight,
3906
+ isSynthetic
3882
3907
  });
3883
3908
  }
3884
3909
  }
@@ -4294,7 +4319,7 @@ function s(slotName, data, children, slotset) {
4294
4319
  // undefined is for root components, but root components cannot accept slotted content
4295
4320
  setVMBeingRendered(slotset.owner);
4296
4321
  try {
4297
- ArrayPush$1.apply(newChildren, vnode.factory(data.slotData));
4322
+ ArrayPush$1.call(newChildren, vnode.factory(data.slotData, data.key));
4298
4323
  }
4299
4324
  finally {
4300
4325
  setVMBeingRendered(vmBeingRenderedInception);
@@ -5174,15 +5199,10 @@ function resetComponentStateWhenRemoved(vm) {
5174
5199
  } = vm;
5175
5200
  if (state !== 2 /* VMState.disconnected */) {
5176
5201
  const {
5177
- oar,
5178
5202
  tro
5179
5203
  } = vm;
5180
5204
  // Making sure that any observing record will not trigger the rehydrated on this vm
5181
5205
  tro.reset();
5182
- // Making sure that any observing accessor record will not trigger the setter to be reinvoked
5183
- for (const key in oar) {
5184
- oar[key].reset();
5185
- }
5186
5206
  runDisconnectedCallback(vm);
5187
5207
  // Spec: https://dom.spec.whatwg.org/#concept-node-remove (step 14-15)
5188
5208
  runChildNodesDisconnectedCallback(vm);
@@ -5235,7 +5255,6 @@ function createVM(elm, ctor, renderer, options) {
5235
5255
  cmpSlots: {
5236
5256
  slotAssignments: create(null)
5237
5257
  },
5238
- oar: create(null),
5239
5258
  cmpTemplate: null,
5240
5259
  hydrated: Boolean(hydrated),
5241
5260
  renderMode: def.renderMode,
@@ -6419,94 +6438,166 @@ function setHooks(hooks) {
6419
6438
  // See @lwc/engine-core/src/framework/template.ts
6420
6439
  const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6421
6440
  // Via https://www.npmjs.com/package/object-observer
6422
- const ARRAY_MUTATION_METHODS = [
6423
- 'pop',
6424
- 'push',
6425
- 'shift',
6426
- 'unshift',
6427
- 'reverse',
6428
- 'sort',
6429
- 'fill',
6430
- 'splice',
6431
- 'copyWithin',
6432
- ];
6441
+ const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6442
+ // Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
6443
+ const STYLESHEET_FUNCTION_EXPANDOS = [
6444
+ // SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
6445
+ '$scoped$'];
6433
6446
  function getOriginalArrayMethod(prop) {
6434
- switch (prop) {
6435
- case 'pop':
6436
- return ArrayPop;
6437
- case 'push':
6438
- return ArrayPush$1;
6439
- case 'shift':
6440
- return ArrayShift;
6441
- case 'unshift':
6442
- return ArrayUnshift;
6443
- case 'reverse':
6444
- return ArrayReverse;
6445
- case 'sort':
6446
- return ArraySort;
6447
- case 'fill':
6448
- return ArrayFill;
6449
- case 'splice':
6450
- return ArraySplice;
6451
- case 'copyWithin':
6452
- return ArrayCopyWithin;
6453
- }
6447
+ switch (prop) {
6448
+ case 'pop':
6449
+ return ArrayPop;
6450
+ case 'push':
6451
+ return ArrayPush$1;
6452
+ case 'shift':
6453
+ return ArrayShift;
6454
+ case 'unshift':
6455
+ return ArrayUnshift;
6456
+ case 'reverse':
6457
+ return ArrayReverse;
6458
+ case 'sort':
6459
+ return ArraySort;
6460
+ case 'fill':
6461
+ return ArrayFill;
6462
+ case 'splice':
6463
+ return ArraySplice;
6464
+ case 'copyWithin':
6465
+ return ArrayCopyWithin;
6466
+ }
6454
6467
  }
6455
6468
  let mutationWarningsSilenced = false;
6456
- // Warn if the user tries to mutate tmpl.stylesheets, e.g.:
6469
+ // Warn if the user tries to mutate a stylesheets array, e.g.:
6457
6470
  // `tmpl.stylesheets.push(someStylesheetFunction)`
6458
6471
  function warnOnArrayMutation(stylesheets) {
6459
- // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6460
- // we can at least warn when they use the most common mutation methods.
6461
- for (const prop of ARRAY_MUTATION_METHODS) {
6462
- const originalArrayMethod = getOriginalArrayMethod(prop);
6463
- stylesheets[prop] = function arrayMutationWarningWrapper() {
6464
- logError(`Mutating the "stylesheets" array on a template function ` +
6465
- `is deprecated and may be removed in a future version of LWC.`);
6466
- // @ts-ignore
6467
- return originalArrayMethod.apply(this, arguments);
6468
- };
6472
+ // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6473
+ // we can at least warn when they use the most common mutation methods.
6474
+ for (const prop of ARRAY_MUTATION_METHODS) {
6475
+ const originalArrayMethod = getOriginalArrayMethod(prop);
6476
+ stylesheets[prop] = function arrayMutationWarningWrapper() {
6477
+ logError(`Mutating the "stylesheets" array on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6478
+ // @ts-ignore
6479
+ return originalArrayMethod.apply(this, arguments);
6480
+ };
6481
+ }
6482
+ }
6483
+ // Warn if the user tries to mutate a stylesheet factory function, e.g.:
6484
+ // `stylesheet.$scoped$ = true`
6485
+ function warnOnStylesheetFunctionMutation(stylesheet) {
6486
+ // We could warn on other properties, but in practice only certain expandos are meaningful to LWC at runtime
6487
+ for (const prop of STYLESHEET_FUNCTION_EXPANDOS) {
6488
+ let value = stylesheet[prop];
6489
+ defineProperty(stylesheet, prop, {
6490
+ enumerable: true,
6491
+ configurable: true,
6492
+ get() {
6493
+ return value;
6494
+ },
6495
+ set(newValue) {
6496
+ logError(`Dynamically setting the "${prop}" property on a stylesheet function ` + `is deprecated and may be removed in a future version of LWC.`);
6497
+ value = newValue;
6498
+ }
6499
+ });
6500
+ }
6501
+ }
6502
+ // Warn on either array or stylesheet (function) mutation, in a deeply-nested array
6503
+ function warnOnStylesheetsMutation(stylesheets) {
6504
+ traverseStylesheets(stylesheets, subStylesheets => {
6505
+ if (isArray$1(subStylesheets)) {
6506
+ warnOnArrayMutation(subStylesheets);
6507
+ } else {
6508
+ warnOnStylesheetFunctionMutation(subStylesheets);
6469
6509
  }
6510
+ });
6511
+ }
6512
+ // Deeply freeze the entire array (of arrays) of stylesheet factory functions
6513
+ function deepFreeze(stylesheets) {
6514
+ traverseStylesheets(stylesheets, subStylesheets => {
6515
+ freeze(subStylesheets);
6516
+ });
6517
+ }
6518
+ // Deep-traverse an array (of arrays) of stylesheet factory functions, and call the callback for every array/function
6519
+ function traverseStylesheets(stylesheets, callback) {
6520
+ callback(stylesheets);
6521
+ for (let i = 0; i < stylesheets.length; i++) {
6522
+ const stylesheet = stylesheets[i];
6523
+ if (isArray$1(stylesheet)) {
6524
+ traverseStylesheets(stylesheet, callback);
6525
+ } else {
6526
+ callback(stylesheet);
6527
+ }
6528
+ }
6470
6529
  }
6471
- // TODO [#2782]: eventually freezeTemplate() will _actually_ freeze the tmpl object. Today it
6472
- // just warns on mutation.
6473
6530
  function freezeTemplate(tmpl) {
6531
+ if (lwcRuntimeFlags.ENABLE_FROZEN_TEMPLATE) {
6532
+ // Deep freeze the template
6533
+ freeze(tmpl);
6534
+ if (!isUndefined$1(tmpl.stylesheets)) {
6535
+ deepFreeze(tmpl.stylesheets);
6536
+ }
6537
+ } else {
6538
+ // TODO [#2782]: remove this flag and delete the legacy behavior
6539
+ // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6540
+ // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
6541
+ defineProperty(tmpl, 'stylesheetTokens', {
6542
+ enumerable: true,
6543
+ configurable: true,
6544
+ get() {
6545
+ const {
6546
+ stylesheetToken
6547
+ } = this;
6548
+ if (isUndefined$1(stylesheetToken)) {
6549
+ return stylesheetToken;
6550
+ }
6551
+ // Shim for the old `stylesheetTokens` property
6552
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
6553
+ return {
6554
+ hostAttribute: `${stylesheetToken}-host`,
6555
+ shadowAttribute: stylesheetToken
6556
+ };
6557
+ },
6558
+ set(value) {
6559
+ // If the value is null or some other exotic object, you would be broken anyway in the past
6560
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
6561
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
6562
+ this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
6563
+ }
6564
+ });
6565
+ // When ENABLE_FROZEN_TEMPLATE is false, warn in dev mode whenever someone is mutating the template
6474
6566
  if (process.env.NODE_ENV !== 'production') {
6475
- if (!isUndefined$1(tmpl.stylesheets)) {
6476
- warnOnArrayMutation(tmpl.stylesheets);
6477
- }
6478
- for (const prop of TEMPLATE_PROPS) {
6479
- let value = tmpl[prop];
6480
- defineProperty(tmpl, prop, {
6481
- enumerable: true,
6482
- configurable: true,
6483
- get() {
6484
- return value;
6485
- },
6486
- set(newValue) {
6487
- if (!mutationWarningsSilenced) {
6488
- logError(`Dynamically setting the "${prop}" property on a template function ` +
6489
- `is deprecated and may be removed in a future version of LWC.`);
6490
- }
6491
- value = newValue;
6492
- },
6493
- });
6494
- }
6495
- const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6496
- defineProperty(tmpl, 'stylesheetTokens', {
6497
- enumerable: true,
6498
- configurable: true,
6499
- get: originalDescriptor.get,
6500
- set(value) {
6501
- logError(`Dynamically setting the "stylesheetTokens" property on a template function ` +
6502
- `is deprecated and may be removed in a future version of LWC.`);
6503
- // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6504
- mutationWarningsSilenced = true;
6505
- originalDescriptor.set.call(this, value);
6506
- mutationWarningsSilenced = false;
6507
- },
6567
+ if (!isUndefined$1(tmpl.stylesheets)) {
6568
+ warnOnStylesheetsMutation(tmpl.stylesheets);
6569
+ }
6570
+ for (const prop of TEMPLATE_PROPS) {
6571
+ let value = tmpl[prop];
6572
+ defineProperty(tmpl, prop, {
6573
+ enumerable: true,
6574
+ configurable: true,
6575
+ get() {
6576
+ return value;
6577
+ },
6578
+ set(newValue) {
6579
+ if (!mutationWarningsSilenced) {
6580
+ logError(`Dynamically setting the "${prop}" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6581
+ }
6582
+ value = newValue;
6583
+ }
6508
6584
  });
6585
+ }
6586
+ const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6587
+ defineProperty(tmpl, 'stylesheetTokens', {
6588
+ enumerable: true,
6589
+ configurable: true,
6590
+ get: originalDescriptor.get,
6591
+ set(value) {
6592
+ logError(`Dynamically setting the "stylesheetTokens" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6593
+ // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6594
+ mutationWarningsSilenced = true;
6595
+ originalDescriptor.set.call(this, value);
6596
+ mutationWarningsSilenced = false;
6597
+ }
6598
+ });
6509
6599
  }
6600
+ }
6510
6601
  }
6511
6602
 
6512
6603
  /*
@@ -6533,4 +6624,4 @@ function getComponentConstructor(elm) {
6533
6624
  }
6534
6625
 
6535
6626
  export { LightningElement, profilerControl as __unstable__ProfilerControl, 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 };
6536
- /* version: 2.32.0 */
6627
+ /* version: 2.33.0 */