@lwc/engine-core 2.32.1 → 2.34.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.
package/dist/engine-core.js
CHANGED
|
@@ -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, 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
|
|
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, ArrayPop, isNumber, StringReplace, noop, ArrayUnshift, ArrayFilter, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift } from '@lwc/shared';
|
|
5
|
+
import { applyAriaReflection } from '@lwc/aria-reflection';
|
|
5
6
|
|
|
6
7
|
/*
|
|
7
8
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -307,6 +308,7 @@ function log(method, message, vm) {
|
|
|
307
308
|
if (!isUndefined$1(vm)) {
|
|
308
309
|
msg = `${msg}\n${getComponentStack(vm)}`;
|
|
309
310
|
}
|
|
311
|
+
// In Jest tests, reduce the warning and error verbosity by not printing the callstack
|
|
310
312
|
if (process.env.NODE_ENV === 'test') {
|
|
311
313
|
/* eslint-disable-next-line no-console */
|
|
312
314
|
console[method](msg);
|
|
@@ -376,6 +378,9 @@ function offsetPropertyErrorMessage(name) {
|
|
|
376
378
|
// Global HTML Attributes & Properties
|
|
377
379
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
|
|
378
380
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
|
381
|
+
//
|
|
382
|
+
// If you update this list, check for test files that recapitulate the same list. Searching the codebase
|
|
383
|
+
// for e.g. "dropzone" should suffice.
|
|
379
384
|
const globalHTMLProperties = assign(create(null), {
|
|
380
385
|
accessKey: {
|
|
381
386
|
attribute: 'accesskey',
|
|
@@ -1409,46 +1414,51 @@ function markLockerLiveObject(obj) {
|
|
|
1409
1414
|
* for the Base Lightning Element, it also include the reactivity bit, so the standard property is reactive.
|
|
1410
1415
|
*/
|
|
1411
1416
|
function createBridgeToElementDescriptor(propName, descriptor) {
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1417
|
+
const {
|
|
1418
|
+
get,
|
|
1419
|
+
set,
|
|
1420
|
+
enumerable,
|
|
1421
|
+
configurable
|
|
1422
|
+
} = descriptor;
|
|
1423
|
+
if (!isFunction$1(get)) {
|
|
1424
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1425
|
+
assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard getter.`);
|
|
1418
1426
|
}
|
|
1419
|
-
|
|
1427
|
+
throw new TypeError();
|
|
1428
|
+
}
|
|
1429
|
+
if (!isFunction$1(set)) {
|
|
1430
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1431
|
+
assert.fail(`Detected invalid public property descriptor for HTMLElement.prototype.${propName} definition. Missing the standard setter.`);
|
|
1432
|
+
}
|
|
1433
|
+
throw new TypeError();
|
|
1434
|
+
}
|
|
1435
|
+
return {
|
|
1436
|
+
enumerable,
|
|
1437
|
+
configurable,
|
|
1438
|
+
get() {
|
|
1439
|
+
const vm = getAssociatedVM(this);
|
|
1440
|
+
if (isBeingConstructed(vm)) {
|
|
1420
1441
|
if (process.env.NODE_ENV !== 'production') {
|
|
1421
|
-
|
|
1442
|
+
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
1443
|
}
|
|
1423
|
-
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
componentValueObserved(vm, propName);
|
|
1447
|
+
return get.call(vm.elm);
|
|
1448
|
+
},
|
|
1449
|
+
set(newValue) {
|
|
1450
|
+
const vm = getAssociatedVM(this);
|
|
1451
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1452
|
+
const vmBeingRendered = getVMBeingRendered();
|
|
1453
|
+
assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${propName}`);
|
|
1454
|
+
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}`);
|
|
1455
|
+
assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
|
|
1456
|
+
assert.invariant(!isObject(newValue) || isNull(newValue), `Invalid value "${newValue}" for "${propName}" of ${vm}. Value cannot be an object, must be a primitive value.`);
|
|
1457
|
+
}
|
|
1458
|
+
updateComponentValue(vm, propName, newValue);
|
|
1459
|
+
return set.call(vm.elm, newValue);
|
|
1424
1460
|
}
|
|
1425
|
-
|
|
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
|
-
};
|
|
1461
|
+
};
|
|
1452
1462
|
}
|
|
1453
1463
|
const EMPTY_REFS = freeze(create(null));
|
|
1454
1464
|
const refsCache = new WeakMap();
|
|
@@ -1458,345 +1468,444 @@ const refsCache = new WeakMap();
|
|
|
1458
1468
|
**/
|
|
1459
1469
|
// @ts-ignore
|
|
1460
1470
|
const LightningElement = function () {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1471
|
+
// This should be as performant as possible, while any initialization should be done lazily
|
|
1472
|
+
if (isNull(vmBeingConstructed)) {
|
|
1473
|
+
// Thrown when doing something like `new LightningElement()` or
|
|
1474
|
+
// `class Foo extends LightningElement {}; new Foo()`
|
|
1475
|
+
throw new TypeError('Illegal constructor');
|
|
1476
|
+
}
|
|
1477
|
+
const vm = vmBeingConstructed;
|
|
1478
|
+
const {
|
|
1479
|
+
def,
|
|
1480
|
+
elm
|
|
1481
|
+
} = vm;
|
|
1482
|
+
const {
|
|
1483
|
+
bridge
|
|
1484
|
+
} = def;
|
|
1485
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1486
|
+
const {
|
|
1487
|
+
assertInstanceOfHTMLElement
|
|
1488
|
+
} = vm.renderer;
|
|
1489
|
+
assertInstanceOfHTMLElement(vm.elm, `Component creation requires a DOM element to be associated to ${vm}.`);
|
|
1490
|
+
}
|
|
1491
|
+
const component = this;
|
|
1492
|
+
setPrototypeOf(elm, bridge.prototype);
|
|
1493
|
+
vm.component = this;
|
|
1494
|
+
// Locker hooks assignment. When the LWC engine run with Locker, Locker intercepts all the new
|
|
1495
|
+
// component creation and passes hooks to instrument all the component interactions with the
|
|
1496
|
+
// engine. We are intentionally hiding this argument from the formal API of LightningElement
|
|
1497
|
+
// because we don't want folks to know about it just yet.
|
|
1498
|
+
if (arguments.length === 1) {
|
|
1499
|
+
const {
|
|
1500
|
+
callHook,
|
|
1501
|
+
setHook,
|
|
1502
|
+
getHook
|
|
1503
|
+
} = arguments[0];
|
|
1504
|
+
vm.callHook = callHook;
|
|
1505
|
+
vm.setHook = setHook;
|
|
1506
|
+
vm.getHook = getHook;
|
|
1507
|
+
}
|
|
1508
|
+
markLockerLiveObject(this);
|
|
1509
|
+
// Linking elm, shadow root and component with the VM.
|
|
1510
|
+
associateVM(component, vm);
|
|
1511
|
+
associateVM(elm, vm);
|
|
1512
|
+
if (vm.renderMode === 1 /* RenderMode.Shadow */) {
|
|
1513
|
+
vm.renderRoot = doAttachShadow(vm);
|
|
1514
|
+
} else {
|
|
1515
|
+
vm.renderRoot = elm;
|
|
1516
|
+
}
|
|
1517
|
+
// Adding extra guard rails in DEV mode.
|
|
1518
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1519
|
+
patchCustomElementWithRestrictions(elm);
|
|
1520
|
+
patchComponentWithRestrictions(component);
|
|
1521
|
+
}
|
|
1522
|
+
return this;
|
|
1523
|
+
};
|
|
1524
|
+
function doAttachShadow(vm) {
|
|
1525
|
+
const {
|
|
1526
|
+
elm,
|
|
1527
|
+
mode,
|
|
1528
|
+
shadowMode,
|
|
1529
|
+
def: {
|
|
1530
|
+
ctor
|
|
1531
|
+
},
|
|
1532
|
+
renderer: {
|
|
1533
|
+
attachShadow
|
|
1534
|
+
}
|
|
1535
|
+
} = vm;
|
|
1536
|
+
const shadowRoot = attachShadow(elm, {
|
|
1537
|
+
[KEY__SYNTHETIC_MODE]: shadowMode === 1 /* ShadowMode.Synthetic */,
|
|
1538
|
+
delegatesFocus: Boolean(ctor.delegatesFocus),
|
|
1539
|
+
mode
|
|
1540
|
+
});
|
|
1541
|
+
vm.shadowRoot = shadowRoot;
|
|
1542
|
+
associateVM(shadowRoot, vm);
|
|
1543
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1544
|
+
patchShadowRootWithRestrictions(shadowRoot);
|
|
1545
|
+
}
|
|
1546
|
+
return shadowRoot;
|
|
1547
|
+
}
|
|
1548
|
+
function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
|
|
1549
|
+
if (isBeingConstructed(vm)) {
|
|
1550
|
+
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.`);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
// @ts-ignore
|
|
1554
|
+
LightningElement.prototype = {
|
|
1555
|
+
constructor: LightningElement,
|
|
1556
|
+
dispatchEvent(event) {
|
|
1557
|
+
const vm = getAssociatedVM(this);
|
|
1558
|
+
const {
|
|
1559
|
+
elm,
|
|
1560
|
+
renderer: {
|
|
1561
|
+
dispatchEvent
|
|
1562
|
+
}
|
|
1563
|
+
} = vm;
|
|
1564
|
+
return dispatchEvent(elm, event);
|
|
1565
|
+
},
|
|
1566
|
+
addEventListener(type, listener, options) {
|
|
1567
|
+
const vm = getAssociatedVM(this);
|
|
1568
|
+
const {
|
|
1569
|
+
elm,
|
|
1570
|
+
renderer: {
|
|
1571
|
+
addEventListener
|
|
1572
|
+
}
|
|
1573
|
+
} = vm;
|
|
1470
1574
|
if (process.env.NODE_ENV !== 'production') {
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1575
|
+
const vmBeingRendered = getVMBeingRendered();
|
|
1576
|
+
assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm} by adding an event listener for "${type}".`);
|
|
1577
|
+
assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm} by adding an event listener for "${type}".`);
|
|
1578
|
+
assert.invariant(isFunction$1(listener), `Invalid second argument for this.addEventListener() in ${vm} for event "${type}". Expected an EventListener but received ${listener}.`);
|
|
1579
|
+
}
|
|
1580
|
+
const wrappedListener = getWrappedComponentsListener(vm, listener);
|
|
1581
|
+
addEventListener(elm, type, wrappedListener, options);
|
|
1582
|
+
},
|
|
1583
|
+
removeEventListener(type, listener, options) {
|
|
1584
|
+
const vm = getAssociatedVM(this);
|
|
1585
|
+
const {
|
|
1586
|
+
elm,
|
|
1587
|
+
renderer: {
|
|
1588
|
+
removeEventListener
|
|
1589
|
+
}
|
|
1590
|
+
} = vm;
|
|
1591
|
+
const wrappedListener = getWrappedComponentsListener(vm, listener);
|
|
1592
|
+
removeEventListener(elm, type, wrappedListener, options);
|
|
1593
|
+
},
|
|
1594
|
+
hasAttribute(name) {
|
|
1595
|
+
const vm = getAssociatedVM(this);
|
|
1596
|
+
const {
|
|
1597
|
+
elm,
|
|
1598
|
+
renderer: {
|
|
1599
|
+
getAttribute
|
|
1600
|
+
}
|
|
1601
|
+
} = vm;
|
|
1602
|
+
return !isNull(getAttribute(elm, name));
|
|
1603
|
+
},
|
|
1604
|
+
hasAttributeNS(namespace, name) {
|
|
1605
|
+
const vm = getAssociatedVM(this);
|
|
1606
|
+
const {
|
|
1607
|
+
elm,
|
|
1608
|
+
renderer: {
|
|
1609
|
+
getAttribute
|
|
1610
|
+
}
|
|
1611
|
+
} = vm;
|
|
1612
|
+
return !isNull(getAttribute(elm, name, namespace));
|
|
1613
|
+
},
|
|
1614
|
+
removeAttribute(name) {
|
|
1615
|
+
const vm = getAssociatedVM(this);
|
|
1616
|
+
const {
|
|
1617
|
+
elm,
|
|
1618
|
+
renderer: {
|
|
1619
|
+
removeAttribute
|
|
1620
|
+
}
|
|
1621
|
+
} = vm;
|
|
1622
|
+
unlockAttribute(elm, name);
|
|
1623
|
+
removeAttribute(elm, name);
|
|
1624
|
+
lockAttribute();
|
|
1625
|
+
},
|
|
1626
|
+
removeAttributeNS(namespace, name) {
|
|
1627
|
+
const {
|
|
1628
|
+
elm,
|
|
1629
|
+
renderer: {
|
|
1630
|
+
removeAttribute
|
|
1631
|
+
}
|
|
1632
|
+
} = getAssociatedVM(this);
|
|
1633
|
+
unlockAttribute(elm, name);
|
|
1634
|
+
removeAttribute(elm, name, namespace);
|
|
1635
|
+
lockAttribute();
|
|
1636
|
+
},
|
|
1637
|
+
getAttribute(name) {
|
|
1638
|
+
const vm = getAssociatedVM(this);
|
|
1639
|
+
const {
|
|
1640
|
+
elm
|
|
1641
|
+
} = vm;
|
|
1642
|
+
const {
|
|
1643
|
+
getAttribute
|
|
1644
|
+
} = vm.renderer;
|
|
1645
|
+
return getAttribute(elm, name);
|
|
1646
|
+
},
|
|
1647
|
+
getAttributeNS(namespace, name) {
|
|
1648
|
+
const vm = getAssociatedVM(this);
|
|
1649
|
+
const {
|
|
1650
|
+
elm
|
|
1651
|
+
} = vm;
|
|
1652
|
+
const {
|
|
1653
|
+
getAttribute
|
|
1654
|
+
} = vm.renderer;
|
|
1655
|
+
return getAttribute(elm, name, namespace);
|
|
1656
|
+
},
|
|
1657
|
+
setAttribute(name, value) {
|
|
1658
|
+
const vm = getAssociatedVM(this);
|
|
1659
|
+
const {
|
|
1660
|
+
elm,
|
|
1661
|
+
renderer: {
|
|
1662
|
+
setAttribute
|
|
1663
|
+
}
|
|
1664
|
+
} = vm;
|
|
1665
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1666
|
+
assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
|
|
1667
|
+
}
|
|
1668
|
+
unlockAttribute(elm, name);
|
|
1669
|
+
setAttribute(elm, name, value);
|
|
1670
|
+
lockAttribute();
|
|
1671
|
+
},
|
|
1672
|
+
setAttributeNS(namespace, name, value) {
|
|
1673
|
+
const vm = getAssociatedVM(this);
|
|
1674
|
+
const {
|
|
1675
|
+
elm,
|
|
1676
|
+
renderer: {
|
|
1677
|
+
setAttribute
|
|
1678
|
+
}
|
|
1679
|
+
} = vm;
|
|
1680
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1681
|
+
assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
|
|
1682
|
+
}
|
|
1683
|
+
unlockAttribute(elm, name);
|
|
1684
|
+
setAttribute(elm, name, value, namespace);
|
|
1685
|
+
lockAttribute();
|
|
1686
|
+
},
|
|
1687
|
+
getBoundingClientRect() {
|
|
1688
|
+
const vm = getAssociatedVM(this);
|
|
1689
|
+
const {
|
|
1690
|
+
elm,
|
|
1691
|
+
renderer: {
|
|
1692
|
+
getBoundingClientRect
|
|
1693
|
+
}
|
|
1694
|
+
} = vm;
|
|
1695
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1696
|
+
warnIfInvokedDuringConstruction(vm, 'getBoundingClientRect()');
|
|
1493
1697
|
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1698
|
+
return getBoundingClientRect(elm);
|
|
1699
|
+
},
|
|
1700
|
+
get isConnected() {
|
|
1701
|
+
const vm = getAssociatedVM(this);
|
|
1702
|
+
const {
|
|
1703
|
+
elm,
|
|
1704
|
+
renderer: {
|
|
1705
|
+
isConnected
|
|
1706
|
+
}
|
|
1707
|
+
} = vm;
|
|
1708
|
+
return isConnected(elm);
|
|
1709
|
+
},
|
|
1710
|
+
get classList() {
|
|
1711
|
+
const vm = getAssociatedVM(this);
|
|
1712
|
+
const {
|
|
1713
|
+
elm,
|
|
1714
|
+
renderer: {
|
|
1715
|
+
getClassList
|
|
1716
|
+
}
|
|
1717
|
+
} = vm;
|
|
1718
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1719
|
+
// TODO [#1290]: this still fails in dev but works in production, eventually, we should
|
|
1720
|
+
// just throw in all modes
|
|
1721
|
+
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.`);
|
|
1722
|
+
}
|
|
1723
|
+
return getClassList(elm);
|
|
1724
|
+
},
|
|
1725
|
+
get template() {
|
|
1726
|
+
const vm = getAssociatedVM(this);
|
|
1727
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1728
|
+
if (vm.renderMode === 0 /* RenderMode.Light */) {
|
|
1729
|
+
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`.');
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
return vm.shadowRoot;
|
|
1733
|
+
},
|
|
1734
|
+
get refs() {
|
|
1735
|
+
const vm = getAssociatedVM(this);
|
|
1736
|
+
if (isUpdatingTemplate) {
|
|
1737
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1738
|
+
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().`);
|
|
1739
|
+
}
|
|
1740
|
+
// If the template is in the process of being updated, then we don't want to go through the normal
|
|
1741
|
+
// process of returning the refs and caching them, because the state of the refs is unstable.
|
|
1742
|
+
// This can happen if e.g. a template contains `<div class={foo}></div>` and `foo` is computed
|
|
1743
|
+
// based on `this.refs.bar`.
|
|
1744
|
+
return;
|
|
1496
1745
|
}
|
|
1497
|
-
// Adding extra guard rails in DEV mode.
|
|
1498
1746
|
if (process.env.NODE_ENV !== 'production') {
|
|
1499
|
-
|
|
1500
|
-
patchComponentWithRestrictions(component);
|
|
1747
|
+
warnIfInvokedDuringConstruction(vm, 'refs');
|
|
1501
1748
|
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1749
|
+
const {
|
|
1750
|
+
refVNodes,
|
|
1751
|
+
hasRefVNodes,
|
|
1752
|
+
cmpTemplate
|
|
1753
|
+
} = vm;
|
|
1754
|
+
// If the `cmpTemplate` is null, that means that the template has not been rendered yet. Most likely this occurs
|
|
1755
|
+
// if `this.refs` is called during the `connectedCallback` phase. The DOM elements have not been rendered yet,
|
|
1756
|
+
// so log a warning. Note we also check `isBeingConstructed()` to avoid a double warning (due to
|
|
1757
|
+
// `warnIfInvokedDuringConstruction` above).
|
|
1758
|
+
if (process.env.NODE_ENV !== 'production' && isNull(cmpTemplate) && !isBeingConstructed(vm)) {
|
|
1759
|
+
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().`);
|
|
1760
|
+
}
|
|
1761
|
+
// For backwards compatibility with component written before template refs
|
|
1762
|
+
// were introduced, we return undefined if the template has no refs defined
|
|
1763
|
+
// anywhere. This fixes components that may want to add an expando called `refs`
|
|
1764
|
+
// and are checking if it exists with `if (this.refs)` before adding it.
|
|
1765
|
+
// Note it is not sufficient to just check if `refVNodes` is null or empty,
|
|
1766
|
+
// because a template may have `lwc:ref` defined within a falsy `if:true` block.
|
|
1767
|
+
if (!hasRefVNodes) {
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
// For templates that are using `lwc:ref`, if there are no refs currently available
|
|
1771
|
+
// (e.g. refs inside of a falsy `if:true` block), we return an empty object.
|
|
1772
|
+
if (isNull(refVNodes)) {
|
|
1773
|
+
return EMPTY_REFS;
|
|
1774
|
+
}
|
|
1775
|
+
// The refNodes can be cached based on the refVNodes, since the refVNodes
|
|
1776
|
+
// are recreated from scratch every time the template is rendered.
|
|
1777
|
+
// This happens with `vm.refVNodes = null` in `template.ts` in `@lwc/engine-core`.
|
|
1778
|
+
let refs = refsCache.get(refVNodes);
|
|
1779
|
+
if (isUndefined$1(refs)) {
|
|
1780
|
+
refs = create(null);
|
|
1781
|
+
for (const key of keys(refVNodes)) {
|
|
1782
|
+
refs[key] = refVNodes[key].elm;
|
|
1783
|
+
}
|
|
1784
|
+
freeze(refs);
|
|
1785
|
+
refsCache.set(refVNodes, refs);
|
|
1786
|
+
}
|
|
1787
|
+
return refs;
|
|
1788
|
+
},
|
|
1789
|
+
// For backwards compat, we allow component authors to set `refs` as an expando
|
|
1790
|
+
set refs(value) {
|
|
1791
|
+
defineProperty(this, 'refs', {
|
|
1792
|
+
configurable: true,
|
|
1793
|
+
enumerable: true,
|
|
1794
|
+
writable: true,
|
|
1795
|
+
value
|
|
1510
1796
|
});
|
|
1511
|
-
|
|
1512
|
-
|
|
1797
|
+
},
|
|
1798
|
+
get shadowRoot() {
|
|
1799
|
+
// From within the component instance, the shadowRoot is always reported as "closed".
|
|
1800
|
+
// Authors should rely on this.template instead.
|
|
1801
|
+
return null;
|
|
1802
|
+
},
|
|
1803
|
+
get children() {
|
|
1804
|
+
const vm = getAssociatedVM(this);
|
|
1805
|
+
const renderer = vm.renderer;
|
|
1513
1806
|
if (process.env.NODE_ENV !== 'production') {
|
|
1514
|
-
|
|
1807
|
+
warnIfInvokedDuringConstruction(vm, 'children');
|
|
1515
1808
|
}
|
|
1516
|
-
return
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1809
|
+
return renderer.getChildren(vm.elm);
|
|
1810
|
+
},
|
|
1811
|
+
get childNodes() {
|
|
1812
|
+
const vm = getAssociatedVM(this);
|
|
1813
|
+
const renderer = vm.renderer;
|
|
1814
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1815
|
+
warnIfInvokedDuringConstruction(vm, 'childNodes');
|
|
1521
1816
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
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
|
-
},
|
|
1817
|
+
return renderer.getChildNodes(vm.elm);
|
|
1818
|
+
},
|
|
1819
|
+
get firstChild() {
|
|
1820
|
+
const vm = getAssociatedVM(this);
|
|
1821
|
+
const renderer = vm.renderer;
|
|
1822
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1823
|
+
warnIfInvokedDuringConstruction(vm, 'firstChild');
|
|
1824
|
+
}
|
|
1825
|
+
return renderer.getFirstChild(vm.elm);
|
|
1826
|
+
},
|
|
1827
|
+
get firstElementChild() {
|
|
1828
|
+
const vm = getAssociatedVM(this);
|
|
1829
|
+
const renderer = vm.renderer;
|
|
1830
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1831
|
+
warnIfInvokedDuringConstruction(vm, 'firstElementChild');
|
|
1832
|
+
}
|
|
1833
|
+
return renderer.getFirstElementChild(vm.elm);
|
|
1834
|
+
},
|
|
1835
|
+
get lastChild() {
|
|
1836
|
+
const vm = getAssociatedVM(this);
|
|
1837
|
+
const renderer = vm.renderer;
|
|
1838
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1839
|
+
warnIfInvokedDuringConstruction(vm, 'lastChild');
|
|
1840
|
+
}
|
|
1841
|
+
return renderer.getLastChild(vm.elm);
|
|
1842
|
+
},
|
|
1843
|
+
get lastElementChild() {
|
|
1844
|
+
const vm = getAssociatedVM(this);
|
|
1845
|
+
const renderer = vm.renderer;
|
|
1846
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1847
|
+
warnIfInvokedDuringConstruction(vm, 'lastElementChild');
|
|
1848
|
+
}
|
|
1849
|
+
return renderer.getLastElementChild(vm.elm);
|
|
1850
|
+
},
|
|
1851
|
+
render() {
|
|
1852
|
+
const vm = getAssociatedVM(this);
|
|
1853
|
+
return vm.def.template;
|
|
1854
|
+
},
|
|
1855
|
+
toString() {
|
|
1856
|
+
const vm = getAssociatedVM(this);
|
|
1857
|
+
return `[object ${vm.def.name}]`;
|
|
1858
|
+
}
|
|
1761
1859
|
};
|
|
1762
1860
|
const queryAndChildGetterDescriptors = create(null);
|
|
1763
|
-
const queryMethods = [
|
|
1764
|
-
'getElementsByClassName',
|
|
1765
|
-
'getElementsByTagName',
|
|
1766
|
-
'querySelector',
|
|
1767
|
-
'querySelectorAll',
|
|
1768
|
-
];
|
|
1861
|
+
const queryMethods = ['getElementsByClassName', 'getElementsByTagName', 'querySelector', 'querySelectorAll'];
|
|
1769
1862
|
// Generic passthrough for query APIs on HTMLElement to the relevant Renderer APIs
|
|
1770
1863
|
for (const queryMethod of queryMethods) {
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1864
|
+
queryAndChildGetterDescriptors[queryMethod] = {
|
|
1865
|
+
value(arg) {
|
|
1866
|
+
const vm = getAssociatedVM(this);
|
|
1867
|
+
const {
|
|
1868
|
+
elm,
|
|
1869
|
+
renderer
|
|
1870
|
+
} = vm;
|
|
1871
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1872
|
+
warnIfInvokedDuringConstruction(vm, `${queryMethod}()`);
|
|
1873
|
+
}
|
|
1874
|
+
return renderer[queryMethod](elm, arg);
|
|
1875
|
+
},
|
|
1876
|
+
configurable: true,
|
|
1877
|
+
enumerable: true,
|
|
1878
|
+
writable: true
|
|
1879
|
+
};
|
|
1784
1880
|
}
|
|
1785
1881
|
defineProperties(LightningElement.prototype, queryAndChildGetterDescriptors);
|
|
1786
1882
|
const lightningBasedDescriptors = create(null);
|
|
1787
1883
|
for (const propName in HTMLElementOriginalDescriptors) {
|
|
1788
|
-
|
|
1884
|
+
lightningBasedDescriptors[propName] = createBridgeToElementDescriptor(propName, HTMLElementOriginalDescriptors[propName]);
|
|
1789
1885
|
}
|
|
1790
1886
|
defineProperties(LightningElement.prototype, lightningBasedDescriptors);
|
|
1887
|
+
function applyAriaReflectionToLightningElement() {
|
|
1888
|
+
// If ARIA reflection is not applied globally to Element.prototype, or if we are running server-side,
|
|
1889
|
+
// apply it to LightningElement.prototype.
|
|
1890
|
+
// This allows `this.aria*` property accessors to work from inside a component, and to reflect `aria-*` attrs.
|
|
1891
|
+
applyAriaReflection(LightningElement.prototype);
|
|
1892
|
+
}
|
|
1893
|
+
// The reason for this odd if/else branching is limitations in @lwc/features:
|
|
1894
|
+
// https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#only-works-with-if-statements
|
|
1895
|
+
if (lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
|
|
1896
|
+
applyAriaReflectionToLightningElement();
|
|
1897
|
+
} else if (!process.env.IS_BROWSER) {
|
|
1898
|
+
applyAriaReflectionToLightningElement();
|
|
1899
|
+
}
|
|
1791
1900
|
defineProperty(LightningElement, 'CustomElementConstructor', {
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1901
|
+
get() {
|
|
1902
|
+
// If required, a runtime-specific implementation must be defined.
|
|
1903
|
+
throw new ReferenceError('The current runtime does not support CustomElementConstructor.');
|
|
1904
|
+
},
|
|
1905
|
+
configurable: true
|
|
1797
1906
|
});
|
|
1798
1907
|
if (process.env.NODE_ENV !== 'production') {
|
|
1799
|
-
|
|
1908
|
+
patchLightningElementPrototypeWithRestrictions(LightningElement.prototype);
|
|
1800
1909
|
}
|
|
1801
1910
|
|
|
1802
1911
|
function createObservedFieldPropertyDescriptor(key) {
|
|
@@ -2256,138 +2365,161 @@ function sanitizeAttribute(tagName, namespaceUri, attrName, attrValue) {
|
|
|
2256
2365
|
const cachedGetterByKey = create(null);
|
|
2257
2366
|
const cachedSetterByKey = create(null);
|
|
2258
2367
|
function createGetter(key) {
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2368
|
+
let fn = cachedGetterByKey[key];
|
|
2369
|
+
if (isUndefined$1(fn)) {
|
|
2370
|
+
fn = cachedGetterByKey[key] = function () {
|
|
2371
|
+
const vm = getAssociatedVM(this);
|
|
2372
|
+
const {
|
|
2373
|
+
getHook
|
|
2374
|
+
} = vm;
|
|
2375
|
+
return getHook(vm.component, key);
|
|
2376
|
+
};
|
|
2377
|
+
}
|
|
2378
|
+
return fn;
|
|
2268
2379
|
}
|
|
2269
2380
|
function createSetter(key) {
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2381
|
+
let fn = cachedSetterByKey[key];
|
|
2382
|
+
if (isUndefined$1(fn)) {
|
|
2383
|
+
fn = cachedSetterByKey[key] = function (newValue) {
|
|
2384
|
+
const vm = getAssociatedVM(this);
|
|
2385
|
+
const {
|
|
2386
|
+
setHook
|
|
2387
|
+
} = vm;
|
|
2388
|
+
newValue = getReadOnlyProxy(newValue);
|
|
2389
|
+
setHook(vm.component, key, newValue);
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
return fn;
|
|
2280
2393
|
}
|
|
2281
2394
|
function createMethodCaller(methodName) {
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
};
|
|
2395
|
+
return function () {
|
|
2396
|
+
const vm = getAssociatedVM(this);
|
|
2397
|
+
const {
|
|
2398
|
+
callHook,
|
|
2399
|
+
component
|
|
2400
|
+
} = vm;
|
|
2401
|
+
const fn = component[methodName];
|
|
2402
|
+
return callHook(vm.component, fn, ArraySlice.call(arguments));
|
|
2403
|
+
};
|
|
2288
2404
|
}
|
|
2289
2405
|
function createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback) {
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
}
|
|
2295
|
-
const propName = attributeToPropMap[attrName];
|
|
2296
|
-
if (isUndefined$1(propName)) {
|
|
2297
|
-
if (!isUndefined$1(superAttributeChangedCallback)) {
|
|
2298
|
-
// delegate unknown attributes to the super.
|
|
2299
|
-
// Typescript does not like it when you treat the `arguments` object as an array
|
|
2300
|
-
// @ts-ignore type-mismatch
|
|
2301
|
-
superAttributeChangedCallback.apply(this, arguments);
|
|
2302
|
-
}
|
|
2303
|
-
return;
|
|
2304
|
-
}
|
|
2305
|
-
if (!isAttributeLocked(this, attrName)) {
|
|
2306
|
-
// Ignore changes triggered by the engine itself during:
|
|
2307
|
-
// * diffing when public props are attempting to reflect to the DOM
|
|
2308
|
-
// * component via `this.setAttribute()`, should never update the prop
|
|
2309
|
-
// Both cases, the setAttribute call is always wrapped by the unlocking of the
|
|
2310
|
-
// attribute to be changed
|
|
2311
|
-
return;
|
|
2312
|
-
}
|
|
2313
|
-
// Reflect attribute change to the corresponding property when changed from outside.
|
|
2314
|
-
this[propName] = newValue;
|
|
2315
|
-
};
|
|
2316
|
-
}
|
|
2317
|
-
function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
2318
|
-
let HTMLBridgeElement;
|
|
2319
|
-
/**
|
|
2320
|
-
* Modern browsers will have all Native Constructors as regular Classes
|
|
2321
|
-
* and must be instantiated with the new keyword. In older browsers,
|
|
2322
|
-
* specifically IE11, those are objects with a prototype property defined,
|
|
2323
|
-
* since they are not supposed to be extended or instantiated with the
|
|
2324
|
-
* new keyword. This forking logic supports both cases, specifically because
|
|
2325
|
-
* wc.ts relies on the construction path of the bridges to create new
|
|
2326
|
-
* fully qualifying web components.
|
|
2327
|
-
*/
|
|
2328
|
-
if (isFunction$1(SuperClass)) {
|
|
2329
|
-
HTMLBridgeElement = class extends SuperClass {
|
|
2330
|
-
};
|
|
2331
|
-
}
|
|
2332
|
-
else {
|
|
2333
|
-
HTMLBridgeElement = function () {
|
|
2334
|
-
// Bridge classes are not supposed to be instantiated directly in
|
|
2335
|
-
// browsers that do not support web components.
|
|
2336
|
-
throw new TypeError('Illegal constructor');
|
|
2337
|
-
};
|
|
2338
|
-
// prototype inheritance dance
|
|
2339
|
-
setPrototypeOf(HTMLBridgeElement, SuperClass);
|
|
2340
|
-
setPrototypeOf(HTMLBridgeElement.prototype, SuperClass.prototype);
|
|
2341
|
-
defineProperty(HTMLBridgeElement.prototype, 'constructor', {
|
|
2342
|
-
writable: true,
|
|
2343
|
-
configurable: true,
|
|
2344
|
-
value: HTMLBridgeElement,
|
|
2345
|
-
});
|
|
2406
|
+
return function attributeChangedCallback(attrName, oldValue, newValue) {
|
|
2407
|
+
if (oldValue === newValue) {
|
|
2408
|
+
// Ignore same values.
|
|
2409
|
+
return;
|
|
2346
2410
|
}
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
|
|
2357
|
-
descriptors[propName] = {
|
|
2358
|
-
get: createGetter(propName),
|
|
2359
|
-
set: createSetter(propName),
|
|
2360
|
-
enumerable: true,
|
|
2361
|
-
configurable: true,
|
|
2362
|
-
};
|
|
2411
|
+
const propName = attributeToPropMap[attrName];
|
|
2412
|
+
if (isUndefined$1(propName)) {
|
|
2413
|
+
if (!isUndefined$1(superAttributeChangedCallback)) {
|
|
2414
|
+
// delegate unknown attributes to the super.
|
|
2415
|
+
// Typescript does not like it when you treat the `arguments` object as an array
|
|
2416
|
+
// @ts-ignore type-mismatch
|
|
2417
|
+
superAttributeChangedCallback.apply(this, arguments);
|
|
2418
|
+
}
|
|
2419
|
+
return;
|
|
2363
2420
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
};
|
|
2421
|
+
if (!isAttributeLocked(this, attrName)) {
|
|
2422
|
+
// Ignore changes triggered by the engine itself during:
|
|
2423
|
+
// * diffing when public props are attempting to reflect to the DOM
|
|
2424
|
+
// * component via `this.setAttribute()`, should never update the prop
|
|
2425
|
+
// Both cases, the setAttribute call is always wrapped by the unlocking of the
|
|
2426
|
+
// attribute to be changed
|
|
2427
|
+
return;
|
|
2372
2428
|
}
|
|
2373
|
-
//
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2429
|
+
// Reflect attribute change to the corresponding property when changed from outside.
|
|
2430
|
+
this[propName] = newValue;
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
2434
|
+
let HTMLBridgeElement;
|
|
2435
|
+
/**
|
|
2436
|
+
* Modern browsers will have all Native Constructors as regular Classes
|
|
2437
|
+
* and must be instantiated with the new keyword. In older browsers,
|
|
2438
|
+
* specifically IE11, those are objects with a prototype property defined,
|
|
2439
|
+
* since they are not supposed to be extended or instantiated with the
|
|
2440
|
+
* new keyword. This forking logic supports both cases, specifically because
|
|
2441
|
+
* wc.ts relies on the construction path of the bridges to create new
|
|
2442
|
+
* fully qualifying web components.
|
|
2443
|
+
*/
|
|
2444
|
+
if (isFunction$1(SuperClass)) {
|
|
2445
|
+
HTMLBridgeElement = class extends SuperClass {};
|
|
2446
|
+
} else {
|
|
2447
|
+
HTMLBridgeElement = function () {
|
|
2448
|
+
// Bridge classes are not supposed to be instantiated directly in
|
|
2449
|
+
// browsers that do not support web components.
|
|
2450
|
+
throw new TypeError('Illegal constructor');
|
|
2379
2451
|
};
|
|
2380
|
-
//
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2452
|
+
// prototype inheritance dance
|
|
2453
|
+
setPrototypeOf(HTMLBridgeElement, SuperClass);
|
|
2454
|
+
setPrototypeOf(HTMLBridgeElement.prototype, SuperClass.prototype);
|
|
2455
|
+
defineProperty(HTMLBridgeElement.prototype, 'constructor', {
|
|
2456
|
+
writable: true,
|
|
2457
|
+
configurable: true,
|
|
2458
|
+
value: HTMLBridgeElement
|
|
2386
2459
|
});
|
|
2387
|
-
|
|
2388
|
-
|
|
2460
|
+
}
|
|
2461
|
+
// generating the hash table for attributes to avoid duplicate fields and facilitate validation
|
|
2462
|
+
// and false positives in case of inheritance.
|
|
2463
|
+
const attributeToPropMap = create(null);
|
|
2464
|
+
const {
|
|
2465
|
+
attributeChangedCallback: superAttributeChangedCallback
|
|
2466
|
+
} = SuperClass.prototype;
|
|
2467
|
+
const {
|
|
2468
|
+
observedAttributes: superObservedAttributes = []
|
|
2469
|
+
} = SuperClass;
|
|
2470
|
+
const descriptors = create(null);
|
|
2471
|
+
// expose getters and setters for each public props on the new Element Bridge
|
|
2472
|
+
for (let i = 0, len = props.length; i < len; i += 1) {
|
|
2473
|
+
const propName = props[i];
|
|
2474
|
+
attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
|
|
2475
|
+
descriptors[propName] = {
|
|
2476
|
+
get: createGetter(propName),
|
|
2477
|
+
set: createSetter(propName),
|
|
2478
|
+
enumerable: true,
|
|
2479
|
+
configurable: true
|
|
2480
|
+
};
|
|
2481
|
+
}
|
|
2482
|
+
// expose public methods as props on the new Element Bridge
|
|
2483
|
+
for (let i = 0, len = methods.length; i < len; i += 1) {
|
|
2484
|
+
const methodName = methods[i];
|
|
2485
|
+
descriptors[methodName] = {
|
|
2486
|
+
value: createMethodCaller(methodName),
|
|
2487
|
+
writable: true,
|
|
2488
|
+
configurable: true
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
// creating a new attributeChangedCallback per bridge because they are bound to the corresponding
|
|
2492
|
+
// map of attributes to props. We do this after all other props and methods to avoid the possibility
|
|
2493
|
+
// of getting overrule by a class declaration in user-land, and we make it non-writable, non-configurable
|
|
2494
|
+
// to preserve this definition.
|
|
2495
|
+
descriptors.attributeChangedCallback = {
|
|
2496
|
+
value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback)
|
|
2497
|
+
};
|
|
2498
|
+
// Specify attributes for which we want to reflect changes back to their corresponding
|
|
2499
|
+
// properties via attributeChangedCallback.
|
|
2500
|
+
defineProperty(HTMLBridgeElement, 'observedAttributes', {
|
|
2501
|
+
get() {
|
|
2502
|
+
return [...superObservedAttributes, ...keys(attributeToPropMap)];
|
|
2503
|
+
}
|
|
2504
|
+
});
|
|
2505
|
+
defineProperties(HTMLBridgeElement.prototype, descriptors);
|
|
2506
|
+
return HTMLBridgeElement;
|
|
2389
2507
|
}
|
|
2390
2508
|
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), []);
|
|
2509
|
+
if (process.env.IS_BROWSER) {
|
|
2510
|
+
// This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
|
|
2511
|
+
// so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
|
|
2512
|
+
// ARIA props outside the LightningElement
|
|
2513
|
+
if (lwcRuntimeFlags.DISABLE_ARIA_REFLECTION_POLYFILL) {
|
|
2514
|
+
// If ARIA reflection is not applied globally to Element.prototype, apply it to HTMLBridgeElement.prototype.
|
|
2515
|
+
// This allows `elm.aria*` property accessors to work from outside a component, and to reflect `aria-*` attrs.
|
|
2516
|
+
// This is especially important because the template compiler compiles aria-* attrs on components to aria* props
|
|
2517
|
+
//
|
|
2518
|
+
// Also note that we apply this to BaseBridgeElement.prototype to avoid excessively redefining property
|
|
2519
|
+
// accessors inside the HTMLBridgeElementFactory.
|
|
2520
|
+
applyAriaReflection(BaseBridgeElement.prototype);
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2391
2523
|
freeze(BaseBridgeElement);
|
|
2392
2524
|
seal(BaseBridgeElement.prototype);
|
|
2393
2525
|
|
|
@@ -2843,6 +2975,9 @@ function updateStylesheetToken(vm, template) {
|
|
|
2843
2975
|
stylesheets: newStylesheets,
|
|
2844
2976
|
stylesheetToken: newStylesheetToken
|
|
2845
2977
|
} = template;
|
|
2978
|
+
const {
|
|
2979
|
+
stylesheets: newVmStylesheets
|
|
2980
|
+
} = vm;
|
|
2846
2981
|
const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
2847
2982
|
const {
|
|
2848
2983
|
hasScopedStyles
|
|
@@ -2866,7 +3001,9 @@ function updateStylesheetToken(vm, template) {
|
|
|
2866
3001
|
}
|
|
2867
3002
|
// Apply the new template styling token to the host element, if the new template has any
|
|
2868
3003
|
// associated stylesheets. In the case of light DOM, also ensure there is at least one scoped stylesheet.
|
|
2869
|
-
|
|
3004
|
+
const hasNewStylesheets = hasStyles(newStylesheets);
|
|
3005
|
+
const hasNewVmStylesheets = hasStyles(newVmStylesheets);
|
|
3006
|
+
if (hasNewStylesheets || hasNewVmStylesheets) {
|
|
2870
3007
|
newToken = newStylesheetToken;
|
|
2871
3008
|
}
|
|
2872
3009
|
// Set the new styling token on the host element
|
|
@@ -2938,10 +3075,17 @@ function getStylesheetsContent(vm, template) {
|
|
|
2938
3075
|
stylesheets,
|
|
2939
3076
|
stylesheetToken
|
|
2940
3077
|
} = template;
|
|
3078
|
+
const {
|
|
3079
|
+
stylesheets: vmStylesheets
|
|
3080
|
+
} = vm;
|
|
2941
3081
|
let content = [];
|
|
2942
|
-
if (
|
|
3082
|
+
if (hasStyles(stylesheets)) {
|
|
2943
3083
|
content = evaluateStylesheetsContent(stylesheets, stylesheetToken, vm);
|
|
2944
3084
|
}
|
|
3085
|
+
// VM (component) stylesheets apply after template stylesheets
|
|
3086
|
+
if (hasStyles(vmStylesheets)) {
|
|
3087
|
+
ArrayPush$1.apply(content, evaluateStylesheetsContent(vmStylesheets, stylesheetToken, vm));
|
|
3088
|
+
}
|
|
2945
3089
|
return content;
|
|
2946
3090
|
}
|
|
2947
3091
|
// It might be worth caching this to avoid doing the lookup repeatedly, but
|
|
@@ -2979,10 +3123,13 @@ function getStylesheetTokenHost(vnode) {
|
|
|
2979
3123
|
const {
|
|
2980
3124
|
template
|
|
2981
3125
|
} = getComponentInternalDef(vnode.ctor);
|
|
3126
|
+
const {
|
|
3127
|
+
vm
|
|
3128
|
+
} = vnode;
|
|
2982
3129
|
const {
|
|
2983
3130
|
stylesheetToken
|
|
2984
3131
|
} = template;
|
|
2985
|
-
return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template) ? makeHostToken(stylesheetToken) : null;
|
|
3132
|
+
return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template, vm) ? makeHostToken(stylesheetToken) : null;
|
|
2986
3133
|
}
|
|
2987
3134
|
function getNearestNativeShadowComponent(vm) {
|
|
2988
3135
|
const owner = getNearestShadowComponent(vm);
|
|
@@ -3599,6 +3746,28 @@ function patchCustomElement(n1, n2, parent, renderer) {
|
|
|
3599
3746
|
// in fallback mode, the allocation will always set children to
|
|
3600
3747
|
// empty and delegate the real allocation to the slot elements
|
|
3601
3748
|
allocateChildren(n2, vm);
|
|
3749
|
+
// Solves an edge case with slotted VFragments in native shadow mode.
|
|
3750
|
+
//
|
|
3751
|
+
// During allocation, in native shadow, slotted VFragment nodes are flattened and their text delimiters are removed
|
|
3752
|
+
// to avoid interfering with native slot behavior. When this happens, if any of the fragments
|
|
3753
|
+
// were not stable, the children must go through the dynamic diffing algo.
|
|
3754
|
+
//
|
|
3755
|
+
// If the new children (n2.children) contain no VFragments, but the previous children (n1.children) were dynamic,
|
|
3756
|
+
// the new nodes must be marked dynamic so that all nodes are properly updated. The only indicator that the new
|
|
3757
|
+
// nodes need to be dynamic comes from the previous children, so we check that to determine whether we need to
|
|
3758
|
+
// mark the new children dynamic.
|
|
3759
|
+
//
|
|
3760
|
+
// Example:
|
|
3761
|
+
// n1.children: [div, VFragment('', div, null, ''), div] => [div, div, null, div]; // marked dynamic
|
|
3762
|
+
// n2.children: [div, null, div] => [div, null, div] // marked ???
|
|
3763
|
+
const {
|
|
3764
|
+
shadowMode,
|
|
3765
|
+
renderMode
|
|
3766
|
+
} = vm;
|
|
3767
|
+
if (shadowMode == 0 /* ShadowMode.Native */ && renderMode !== 0 /* RenderMode.Light */ && hasDynamicChildren(n1.children)) {
|
|
3768
|
+
// No-op if children has already been marked dynamic by 'allocateChildren()'.
|
|
3769
|
+
markAsDynamicChildren(n2.children);
|
|
3770
|
+
}
|
|
3602
3771
|
}
|
|
3603
3772
|
// in fallback mode, the children will be always empty, so, nothing
|
|
3604
3773
|
// will happen, but in native, it does allocate the light dom
|
|
@@ -3791,7 +3960,6 @@ function allocateChildren(vnode, vm) {
|
|
|
3791
3960
|
//
|
|
3792
3961
|
// In case #2, we will always get a fresh VCustomElement.
|
|
3793
3962
|
const children = vnode.aChildren || vnode.children;
|
|
3794
|
-
vm.aChildren = children;
|
|
3795
3963
|
const {
|
|
3796
3964
|
renderMode,
|
|
3797
3965
|
shadowMode
|
|
@@ -3804,15 +3972,61 @@ function allocateChildren(vnode, vm) {
|
|
|
3804
3972
|
logError(`Invalid usage of 'lwc:slot-data' on ${getComponentTag(vm)} tag. Scoped slot content can only be passed to a light dom child.`);
|
|
3805
3973
|
}
|
|
3806
3974
|
}
|
|
3975
|
+
// If any of the children being allocated are VFragments, we remove the text delimiters and flatten all immediate
|
|
3976
|
+
// children VFragments to avoid them interfering with default slot behavior.
|
|
3977
|
+
const allocatedChildren = flattenFragmentsInChildren(children);
|
|
3978
|
+
vnode.children = allocatedChildren;
|
|
3979
|
+
vm.aChildren = allocatedChildren;
|
|
3807
3980
|
if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
|
|
3808
3981
|
// slow path
|
|
3809
|
-
allocateInSlot(vm,
|
|
3982
|
+
allocateInSlot(vm, allocatedChildren, vnode.owner);
|
|
3810
3983
|
// save the allocated children in case this vnode is reused.
|
|
3811
|
-
vnode.aChildren =
|
|
3984
|
+
vnode.aChildren = allocatedChildren;
|
|
3812
3985
|
// every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
|
|
3813
3986
|
vnode.children = EmptyArray;
|
|
3814
3987
|
}
|
|
3815
3988
|
}
|
|
3989
|
+
/**
|
|
3990
|
+
* Flattens the contents of all VFragments in an array of VNodes, removes the text delimiters on those VFragments, and
|
|
3991
|
+
* marks the resulting children array as dynamic. Uses a stack (array) to iteratively traverse the nested VFragments
|
|
3992
|
+
* and avoid the perf overhead of creating/destroying throwaway arrays/objects in a recursive approach.
|
|
3993
|
+
*
|
|
3994
|
+
* With the delimiters removed, the contents are marked dynamic so they are diffed correctly.
|
|
3995
|
+
*
|
|
3996
|
+
* This function is used for slotted VFragments to avoid the text delimiters interfering with slotting functionality.
|
|
3997
|
+
*/
|
|
3998
|
+
function flattenFragmentsInChildren(children) {
|
|
3999
|
+
const flattenedChildren = [];
|
|
4000
|
+
// Initialize our stack with the direct children of the custom component and check whether we have a VFragment.
|
|
4001
|
+
// If no VFragment is found in children, we don't need to traverse anything or mark the children dynamic and can return early.
|
|
4002
|
+
const nodeStack = [];
|
|
4003
|
+
let fragmentFound = false;
|
|
4004
|
+
for (let i = children.length - 1; i > -1; i -= 1) {
|
|
4005
|
+
const child = children[i];
|
|
4006
|
+
ArrayPush$1.call(nodeStack, child);
|
|
4007
|
+
fragmentFound = fragmentFound || !!(child && isVFragment(child));
|
|
4008
|
+
}
|
|
4009
|
+
if (!fragmentFound) {
|
|
4010
|
+
return children;
|
|
4011
|
+
}
|
|
4012
|
+
let currentNode;
|
|
4013
|
+
while (!isUndefined$1(currentNode = ArrayPop.call(nodeStack))) {
|
|
4014
|
+
if (!isNull(currentNode) && isVFragment(currentNode)) {
|
|
4015
|
+
const fChildren = currentNode.children;
|
|
4016
|
+
// Ignore the start and end text node delimiters
|
|
4017
|
+
for (let i = fChildren.length - 2; i > 0; i -= 1) {
|
|
4018
|
+
ArrayPush$1.call(nodeStack, fChildren[i]);
|
|
4019
|
+
}
|
|
4020
|
+
} else {
|
|
4021
|
+
ArrayPush$1.call(flattenedChildren, currentNode);
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
// We always mark the children as dynamic because nothing generates stable VFragments yet.
|
|
4025
|
+
// If/when stable VFragments are generated by the compiler, this code should be updated to
|
|
4026
|
+
// not mark dynamic if all flattened VFragments were stable.
|
|
4027
|
+
markAsDynamicChildren(flattenedChildren);
|
|
4028
|
+
return flattenedChildren;
|
|
4029
|
+
}
|
|
3816
4030
|
function createViewModelHook(elm, vnode, renderer) {
|
|
3817
4031
|
let vm = getAssociatedVMIfPresent(elm);
|
|
3818
4032
|
// There is a possibility that a custom element is registered under tagName, in which case, the
|
|
@@ -3837,22 +4051,20 @@ function createViewModelHook(elm, vnode, renderer) {
|
|
|
3837
4051
|
}
|
|
3838
4052
|
return vm;
|
|
3839
4053
|
}
|
|
3840
|
-
|
|
3841
|
-
* Collects all slots into a SlotSet, traversing through VFragment Nodes
|
|
3842
|
-
*/
|
|
3843
|
-
function collectSlots(vm, children, cmpSlotsMapping) {
|
|
4054
|
+
function allocateInSlot(vm, children, owner) {
|
|
3844
4055
|
var _a, _b;
|
|
4056
|
+
const {
|
|
4057
|
+
cmpSlots: {
|
|
4058
|
+
slotAssignments: oldSlotsMapping
|
|
4059
|
+
}
|
|
4060
|
+
} = vm;
|
|
4061
|
+
const cmpSlotsMapping = create(null);
|
|
4062
|
+
// Collect all slots into cmpSlotsMapping
|
|
3845
4063
|
for (let i = 0, len = children.length; i < len; i += 1) {
|
|
3846
4064
|
const vnode = children[i];
|
|
3847
4065
|
if (isNull(vnode)) {
|
|
3848
4066
|
continue;
|
|
3849
4067
|
}
|
|
3850
|
-
// Dive further iff the content is wrapped in a VFragment
|
|
3851
|
-
if (isVFragment(vnode)) {
|
|
3852
|
-
// Remove the text delimiter nodes to avoid overriding default slot content
|
|
3853
|
-
collectSlots(vm, vnode.children.slice(1, -1), cmpSlotsMapping);
|
|
3854
|
-
continue;
|
|
3855
|
-
}
|
|
3856
4068
|
let slotName = '';
|
|
3857
4069
|
if (isVBaseElement(vnode)) {
|
|
3858
4070
|
slotName = (_b = (_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : '';
|
|
@@ -3862,15 +4074,6 @@ function collectSlots(vm, children, cmpSlotsMapping) {
|
|
|
3862
4074
|
const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
|
|
3863
4075
|
ArrayPush$1.call(vnodes, vnode);
|
|
3864
4076
|
}
|
|
3865
|
-
}
|
|
3866
|
-
function allocateInSlot(vm, children, owner) {
|
|
3867
|
-
const {
|
|
3868
|
-
cmpSlots: {
|
|
3869
|
-
slotAssignments: oldSlotsMapping
|
|
3870
|
-
}
|
|
3871
|
-
} = vm;
|
|
3872
|
-
const cmpSlotsMapping = create(null);
|
|
3873
|
-
collectSlots(vm, children, cmpSlotsMapping);
|
|
3874
4077
|
vm.cmpSlots = {
|
|
3875
4078
|
owner,
|
|
3876
4079
|
slotAssignments: cmpSlotsMapping
|
|
@@ -3901,14 +4104,14 @@ function allocateInSlot(vm, children, owner) {
|
|
|
3901
4104
|
}
|
|
3902
4105
|
}
|
|
3903
4106
|
// Using a WeakMap instead of a WeakSet because this one works in IE11 :(
|
|
3904
|
-
const
|
|
3905
|
-
// dynamic children means it was generated by an iteration
|
|
3906
|
-
//
|
|
4107
|
+
const DynamicChildren = new WeakMap();
|
|
4108
|
+
// dynamic children means it was either generated by an iteration in a template
|
|
4109
|
+
// or part of an unstable fragment, and will require a more complex diffing algo.
|
|
3907
4110
|
function markAsDynamicChildren(children) {
|
|
3908
|
-
|
|
4111
|
+
DynamicChildren.set(children, 1);
|
|
3909
4112
|
}
|
|
3910
4113
|
function hasDynamicChildren(children) {
|
|
3911
|
-
return
|
|
4114
|
+
return DynamicChildren.has(children);
|
|
3912
4115
|
}
|
|
3913
4116
|
function createKeyToOldIdx(children, beginIdx, endIdx) {
|
|
3914
4117
|
const map = {};
|
|
@@ -4774,7 +4977,7 @@ function evaluateTemplate(vm, html) {
|
|
|
4774
4977
|
// Create a brand new template cache for the swapped templated.
|
|
4775
4978
|
context.tplCache = create(null);
|
|
4776
4979
|
// Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
|
|
4777
|
-
context.hasScopedStyles = computeHasScopedStyles(html);
|
|
4980
|
+
context.hasScopedStyles = computeHasScopedStyles(html, vm);
|
|
4778
4981
|
// Update the scoping token on the host element.
|
|
4779
4982
|
updateStylesheetToken(vm, html);
|
|
4780
4983
|
// Evaluate, create stylesheet and cache the produced VNode for future
|
|
@@ -4817,9 +5020,8 @@ function evaluateTemplate(vm, html) {
|
|
|
4817
5020
|
}
|
|
4818
5021
|
return vnodes;
|
|
4819
5022
|
}
|
|
4820
|
-
function
|
|
4821
|
-
|
|
4822
|
-
if (!isUndefined$1(stylesheets)) {
|
|
5023
|
+
function computeHasScopedStylesInStylesheets(stylesheets) {
|
|
5024
|
+
if (hasStyles(stylesheets)) {
|
|
4823
5025
|
for (let i = 0; i < stylesheets.length; i++) {
|
|
4824
5026
|
if (isTrue(stylesheets[i][KEY__SCOPED_CSS])) {
|
|
4825
5027
|
return true;
|
|
@@ -4828,6 +5030,15 @@ function computeHasScopedStyles(template) {
|
|
|
4828
5030
|
}
|
|
4829
5031
|
return false;
|
|
4830
5032
|
}
|
|
5033
|
+
function computeHasScopedStyles(template, vm) {
|
|
5034
|
+
const { stylesheets } = template;
|
|
5035
|
+
const vmStylesheets = !isUndefined$1(vm) ? vm.stylesheets : null;
|
|
5036
|
+
return (computeHasScopedStylesInStylesheets(stylesheets) ||
|
|
5037
|
+
computeHasScopedStylesInStylesheets(vmStylesheets));
|
|
5038
|
+
}
|
|
5039
|
+
function hasStyles(stylesheets) {
|
|
5040
|
+
return !isUndefined$1(stylesheets) && !isNull(stylesheets) && stylesheets.length > 0;
|
|
5041
|
+
}
|
|
4831
5042
|
|
|
4832
5043
|
/*
|
|
4833
5044
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -5143,6 +5354,7 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5143
5354
|
// Properties set right after VM creation.
|
|
5144
5355
|
tro: null,
|
|
5145
5356
|
shadowMode: null,
|
|
5357
|
+
stylesheets: null,
|
|
5146
5358
|
// Properties set by the LightningElement constructor.
|
|
5147
5359
|
component: null,
|
|
5148
5360
|
shadowRoot: null,
|
|
@@ -5155,6 +5367,7 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5155
5367
|
if (process.env.NODE_ENV !== 'production') {
|
|
5156
5368
|
vm.debugInfo = create(null);
|
|
5157
5369
|
}
|
|
5370
|
+
vm.stylesheets = computeStylesheets(vm, def.ctor);
|
|
5158
5371
|
vm.shadowMode = computeShadowMode(vm, renderer);
|
|
5159
5372
|
vm.tro = getTemplateReactiveObserver(vm);
|
|
5160
5373
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -5173,6 +5386,42 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5173
5386
|
}
|
|
5174
5387
|
return vm;
|
|
5175
5388
|
}
|
|
5389
|
+
function validateComponentStylesheets(vm, stylesheets) {
|
|
5390
|
+
let valid = true;
|
|
5391
|
+
const validate = arrayOrStylesheet => {
|
|
5392
|
+
if (isArray$1(arrayOrStylesheet)) {
|
|
5393
|
+
for (let i = 0; i < arrayOrStylesheet.length; i++) {
|
|
5394
|
+
validate(arrayOrStylesheet[i]);
|
|
5395
|
+
}
|
|
5396
|
+
} else if (!isFunction$1(arrayOrStylesheet)) {
|
|
5397
|
+
// function assumed to be a stylesheet factory
|
|
5398
|
+
valid = false;
|
|
5399
|
+
}
|
|
5400
|
+
};
|
|
5401
|
+
if (!isArray$1(stylesheets)) {
|
|
5402
|
+
valid = false;
|
|
5403
|
+
} else {
|
|
5404
|
+
validate(stylesheets);
|
|
5405
|
+
}
|
|
5406
|
+
return valid;
|
|
5407
|
+
}
|
|
5408
|
+
// Validate and flatten any stylesheets defined as `static stylesheets`
|
|
5409
|
+
function computeStylesheets(vm, ctor) {
|
|
5410
|
+
if (lwcRuntimeFlags.ENABLE_PROGRAMMATIC_STYLESHEETS) {
|
|
5411
|
+
const {
|
|
5412
|
+
stylesheets
|
|
5413
|
+
} = ctor;
|
|
5414
|
+
if (!isUndefined$1(stylesheets)) {
|
|
5415
|
+
const valid = validateComponentStylesheets(vm, stylesheets);
|
|
5416
|
+
if (valid) {
|
|
5417
|
+
return flattenStylesheets(stylesheets);
|
|
5418
|
+
} else if (process.env.NODE_ENV !== 'production') {
|
|
5419
|
+
logError(`static stylesheets must be an array of CSS stylesheets. Found invalid stylesheets on <${vm.tagName}>`, vm);
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
}
|
|
5423
|
+
return null;
|
|
5424
|
+
}
|
|
5176
5425
|
function computeShadowMode(vm, renderer) {
|
|
5177
5426
|
const {
|
|
5178
5427
|
def
|
|
@@ -6496,4 +6745,4 @@ function getComponentConstructor(elm) {
|
|
|
6496
6745
|
}
|
|
6497
6746
|
|
|
6498
6747
|
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 };
|
|
6499
|
-
/* version: 2.
|
|
6748
|
+
/* version: 2.34.0 */
|