@lwc/engine-core 4.0.0-alpha.0 → 4.0.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/README.md +0 -5
- package/dist/framework/api.d.ts +4 -2
- package/dist/framework/base-bridge-element.d.ts +2 -1
- package/dist/framework/base-lightning-element.d.ts +6 -1
- package/dist/framework/def.d.ts +5 -0
- package/dist/framework/main.d.ts +1 -2
- package/dist/framework/modules/events.d.ts +2 -2
- package/dist/framework/modules/refs.d.ts +3 -0
- package/dist/framework/modules/static-parts.d.ts +11 -0
- package/dist/framework/renderer.d.ts +4 -1
- package/dist/framework/stylesheet.d.ts +2 -2
- package/dist/framework/template.d.ts +2 -0
- package/dist/framework/utils.d.ts +0 -3
- package/dist/framework/vm.d.ts +20 -3
- package/dist/framework/vnodes.d.ts +7 -3
- package/dist/index.cjs.js +579 -191
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +574 -190
- package/dist/index.js.map +1 -1
- package/dist/libs/aria-reflection/aria-reflection.d.ts +2 -0
- package/package.json +5 -6
- package/dist/framework/services.d.ts +0 -22
package/dist/index.cjs.js
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
7
7
|
|
|
8
8
|
var shared = require('@lwc/shared');
|
|
9
|
-
var ariaReflection = require('@lwc/aria-reflection');
|
|
10
9
|
var features = require('@lwc/features');
|
|
11
10
|
|
|
12
11
|
/*
|
|
@@ -392,20 +391,6 @@ function flattenStylesheets(stylesheets) {
|
|
|
392
391
|
}
|
|
393
392
|
return list;
|
|
394
393
|
}
|
|
395
|
-
// Set a ref (lwc:ref) on a VM, from a template API
|
|
396
|
-
function setRefVNode(vm, ref, vnode) {
|
|
397
|
-
if (process.env.NODE_ENV !== 'production' && shared.isUndefined(vm.refVNodes)) {
|
|
398
|
-
throw new Error('refVNodes must be defined when setting a ref');
|
|
399
|
-
}
|
|
400
|
-
// If this method is called, then vm.refVNodes is set as the template has refs.
|
|
401
|
-
// If not, then something went wrong and we threw an error above.
|
|
402
|
-
const refVNodes = vm.refVNodes;
|
|
403
|
-
// In cases of conflict (two elements with the same ref), prefer, the last one,
|
|
404
|
-
// in depth-first traversal order.
|
|
405
|
-
if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
|
|
406
|
-
refVNodes[ref] = vnode;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
394
|
// Throw an error if we're running in prod mode. Ensures code is truly removed from prod mode.
|
|
410
395
|
function assertNotProd() {
|
|
411
396
|
/* istanbul ignore if */
|
|
@@ -433,6 +418,45 @@ var _a, _b;
|
|
|
433
418
|
const instrumentDef = (_a = shared.globalThis.__lwc_instrument_cmp_def) !== null && _a !== void 0 ? _a : shared.noop;
|
|
434
419
|
const instrumentInstance = (_b = shared.globalThis.__lwc_instrument_cmp_instance) !== null && _b !== void 0 ? _b : shared.noop;
|
|
435
420
|
|
|
421
|
+
/*
|
|
422
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
423
|
+
* All rights reserved.
|
|
424
|
+
* SPDX-License-Identifier: MIT
|
|
425
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
426
|
+
*/
|
|
427
|
+
// Apply ARIA string reflection behavior to a prototype.
|
|
428
|
+
// This is deliberately kept separate from @lwc/aria-reflection. @lwc/aria-reflection is a global polyfill that is
|
|
429
|
+
// needed for backwards compatibility in LEX, whereas `applyAriaReflection` is designed to only apply to our own
|
|
430
|
+
// LightningElement/BaseBridgeElement prototypes.
|
|
431
|
+
function applyAriaReflection(prototype) {
|
|
432
|
+
for (const propName of shared.keys(shared.AriaPropNameToAttrNameMap)) {
|
|
433
|
+
const attrName = shared.AriaPropNameToAttrNameMap[propName];
|
|
434
|
+
if (shared.isUndefined(shared.getOwnPropertyDescriptor(prototype, propName))) {
|
|
435
|
+
// Note that we need to call this.{get,set,has,remove}Attribute rather than dereferencing
|
|
436
|
+
// from Element.prototype, because these methods are overridden in LightningElement.
|
|
437
|
+
shared.defineProperty(prototype, propName, {
|
|
438
|
+
get() {
|
|
439
|
+
return this.getAttribute(attrName);
|
|
440
|
+
},
|
|
441
|
+
set(newValue) {
|
|
442
|
+
// TODO [#3284]: there is disagreement between browsers and the spec on how to treat undefined
|
|
443
|
+
// Our historical behavior is to only treat null as removing the attribute
|
|
444
|
+
// See also https://github.com/w3c/aria/issues/1858
|
|
445
|
+
if (shared.isNull(newValue)) {
|
|
446
|
+
this.removeAttribute(attrName);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this.setAttribute(attrName, newValue);
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
// configurable and enumerable to allow it to be overridden – this mimics Safari's/Chrome's behavior
|
|
453
|
+
configurable: true,
|
|
454
|
+
enumerable: true,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
436
460
|
/*
|
|
437
461
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
438
462
|
* All rights reserved.
|
|
@@ -523,8 +547,8 @@ function lockDomMutation() {
|
|
|
523
547
|
assertNotProd(); // this method should never leak to prod
|
|
524
548
|
isDomMutationAllowed = false;
|
|
525
549
|
}
|
|
526
|
-
function
|
|
527
|
-
return
|
|
550
|
+
function logMissingPortalWarn(name, type) {
|
|
551
|
+
return logWarn(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
|
|
528
552
|
}
|
|
529
553
|
function patchElementWithRestrictions(elm, options) {
|
|
530
554
|
assertNotProd(); // this method should never leak to prod
|
|
@@ -549,14 +573,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
549
573
|
shared.assign(descriptors, {
|
|
550
574
|
appendChild: generateDataDescriptor({
|
|
551
575
|
value(aChild) {
|
|
552
|
-
|
|
576
|
+
logMissingPortalWarn('appendChild', 'method');
|
|
553
577
|
return appendChild.call(this, aChild);
|
|
554
578
|
},
|
|
555
579
|
}),
|
|
556
580
|
insertBefore: generateDataDescriptor({
|
|
557
581
|
value(newNode, referenceNode) {
|
|
558
582
|
if (!isDomMutationAllowed) {
|
|
559
|
-
|
|
583
|
+
logMissingPortalWarn('insertBefore', 'method');
|
|
560
584
|
}
|
|
561
585
|
return insertBefore.call(this, newNode, referenceNode);
|
|
562
586
|
},
|
|
@@ -564,14 +588,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
564
588
|
removeChild: generateDataDescriptor({
|
|
565
589
|
value(aChild) {
|
|
566
590
|
if (!isDomMutationAllowed) {
|
|
567
|
-
|
|
591
|
+
logMissingPortalWarn('removeChild', 'method');
|
|
568
592
|
}
|
|
569
593
|
return removeChild.call(this, aChild);
|
|
570
594
|
},
|
|
571
595
|
}),
|
|
572
596
|
replaceChild: generateDataDescriptor({
|
|
573
597
|
value(newChild, oldChild) {
|
|
574
|
-
|
|
598
|
+
logMissingPortalWarn('replaceChild', 'method');
|
|
575
599
|
return replaceChild.call(this, newChild, oldChild);
|
|
576
600
|
},
|
|
577
601
|
}),
|
|
@@ -581,7 +605,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
581
605
|
},
|
|
582
606
|
set(value) {
|
|
583
607
|
if (!isDomMutationAllowed) {
|
|
584
|
-
|
|
608
|
+
logMissingPortalWarn('nodeValue', 'property');
|
|
585
609
|
}
|
|
586
610
|
originalNodeValueDescriptor.set.call(this, value);
|
|
587
611
|
},
|
|
@@ -591,7 +615,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
591
615
|
return originalTextContentDescriptor.get.call(this);
|
|
592
616
|
},
|
|
593
617
|
set(value) {
|
|
594
|
-
|
|
618
|
+
logMissingPortalWarn('textContent', 'property');
|
|
595
619
|
originalTextContentDescriptor.set.call(this, value);
|
|
596
620
|
},
|
|
597
621
|
}),
|
|
@@ -600,7 +624,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
600
624
|
return originalInnerHTMLDescriptor.get.call(this);
|
|
601
625
|
},
|
|
602
626
|
set(value) {
|
|
603
|
-
|
|
627
|
+
logMissingPortalWarn('innerHTML', 'property');
|
|
604
628
|
return originalInnerHTMLDescriptor.set.call(this, value);
|
|
605
629
|
},
|
|
606
630
|
}),
|
|
@@ -1458,6 +1482,79 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
|
|
|
1458
1482
|
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.`);
|
|
1459
1483
|
}
|
|
1460
1484
|
}
|
|
1485
|
+
// List of properties on ElementInternals that are formAssociated can be found in the spec:
|
|
1486
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements
|
|
1487
|
+
const formAssociatedProps = new Set([
|
|
1488
|
+
'setFormValue',
|
|
1489
|
+
'form',
|
|
1490
|
+
'setValidity',
|
|
1491
|
+
'willValidate',
|
|
1492
|
+
'validity',
|
|
1493
|
+
'validationMessage',
|
|
1494
|
+
'checkValidity',
|
|
1495
|
+
'reportValidity',
|
|
1496
|
+
'labels',
|
|
1497
|
+
]);
|
|
1498
|
+
// Verify that access to a form-associated property of the ElementInternals proxy has formAssociated set in the LWC.
|
|
1499
|
+
function verifyPropForFormAssociation(propertyKey, isFormAssociated) {
|
|
1500
|
+
if (shared.isString(propertyKey) && formAssociatedProps.has(propertyKey) && !isFormAssociated) {
|
|
1501
|
+
//Note this error message mirrors Chrome and Firefox error messages, in Safari the error is slightly different.
|
|
1502
|
+
throw new DOMException(`Failed to execute '${propertyKey}' on 'ElementInternals': The target element is not a form-associated custom element.`);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
const elementInternalsAccessorAllowList = new Set(['shadowRoot', 'role', ...formAssociatedProps]);
|
|
1506
|
+
// Prevent access to properties not defined in the HTML spec in case browsers decide to
|
|
1507
|
+
// provide new APIs that provide access to form associated properties.
|
|
1508
|
+
// This can be removed along with UpgradeableConstructor.
|
|
1509
|
+
function isAllowedElementInternalAccessor(propertyKey) {
|
|
1510
|
+
let isAllowedAccessor = false;
|
|
1511
|
+
// As of this writing all ElementInternal property keys as described in the spec are implemented with strings
|
|
1512
|
+
// in Chrome, Firefox, and Safari
|
|
1513
|
+
if (shared.isString(propertyKey)) {
|
|
1514
|
+
// Allow list is based on HTML spec:
|
|
1515
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#the-elementinternals-interface
|
|
1516
|
+
isAllowedAccessor =
|
|
1517
|
+
elementInternalsAccessorAllowList.has(propertyKey) || /^aria/.test(propertyKey);
|
|
1518
|
+
if (!isAllowedAccessor && process.env.NODE_ENV !== 'production') {
|
|
1519
|
+
logWarn('Only properties defined in the ElementInternals HTML spec are available.');
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
return isAllowedAccessor;
|
|
1523
|
+
}
|
|
1524
|
+
// Wrap all ElementInternal objects in a proxy to prevent form association when `formAssociated` is not set on an LWC.
|
|
1525
|
+
// This is needed because the 1UpgradeableConstructor1 always sets `formAssociated=true`, which means all
|
|
1526
|
+
// ElementInternal objects will have form-associated properties set when an LWC is placed in a form.
|
|
1527
|
+
// We are doing this to guard against customers taking a dependency on form elements being associated to ElementInternals
|
|
1528
|
+
// when 'formAssociated' has not been set on the LWC.
|
|
1529
|
+
function createElementInternalsProxy(elementInternals, isFormAssociated) {
|
|
1530
|
+
const elementInternalsProxy = new Proxy(elementInternals, {
|
|
1531
|
+
set(target, propertyKey, newValue) {
|
|
1532
|
+
if (isAllowedElementInternalAccessor(propertyKey)) {
|
|
1533
|
+
// Verify that formAssociated is set for form associated properties
|
|
1534
|
+
verifyPropForFormAssociation(propertyKey, isFormAssociated);
|
|
1535
|
+
return Reflect.set(target, propertyKey, newValue);
|
|
1536
|
+
}
|
|
1537
|
+
// As of this writing ElementInternals do not have non-string properties that can be set.
|
|
1538
|
+
return false;
|
|
1539
|
+
},
|
|
1540
|
+
get(target, propertyKey) {
|
|
1541
|
+
if (
|
|
1542
|
+
// Pass through Object.prototype methods such as toString()
|
|
1543
|
+
shared.hasOwnProperty.call(Object.prototype, propertyKey) ||
|
|
1544
|
+
// As of this writing, ElementInternals only uses Symbol.toStringTag which is called
|
|
1545
|
+
// on Object.hasOwnProperty invocations
|
|
1546
|
+
Symbol.for('Symbol.toStringTag') === propertyKey ||
|
|
1547
|
+
// ElementInternals allow listed properties
|
|
1548
|
+
isAllowedElementInternalAccessor(propertyKey)) {
|
|
1549
|
+
// Verify that formAssociated is set for form associated properties
|
|
1550
|
+
verifyPropForFormAssociation(propertyKey, isFormAssociated);
|
|
1551
|
+
const propertyValue = Reflect.get(target, propertyKey);
|
|
1552
|
+
return shared.isFunction(propertyValue) ? propertyValue.bind(target) : propertyValue;
|
|
1553
|
+
}
|
|
1554
|
+
},
|
|
1555
|
+
});
|
|
1556
|
+
return elementInternalsProxy;
|
|
1557
|
+
}
|
|
1461
1558
|
// @ts-ignore
|
|
1462
1559
|
LightningElement.prototype = {
|
|
1463
1560
|
constructor: LightningElement,
|
|
@@ -1549,6 +1646,16 @@ LightningElement.prototype = {
|
|
|
1549
1646
|
}
|
|
1550
1647
|
return getBoundingClientRect(elm);
|
|
1551
1648
|
},
|
|
1649
|
+
attachInternals() {
|
|
1650
|
+
const vm = getAssociatedVM(this);
|
|
1651
|
+
const { elm, def: { formAssociated }, renderer: { attachInternals }, } = vm;
|
|
1652
|
+
if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
1653
|
+
throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
|
|
1654
|
+
}
|
|
1655
|
+
const internals = attachInternals(elm);
|
|
1656
|
+
// #TODO[2970]: remove proxy once `UpgradeableConstructor` has been removed
|
|
1657
|
+
return createElementInternalsProxy(internals, Boolean(formAssociated));
|
|
1658
|
+
},
|
|
1552
1659
|
get isConnected() {
|
|
1553
1660
|
const vm = getAssociatedVM(this);
|
|
1554
1661
|
const { elm, renderer: { isConnected }, } = vm;
|
|
@@ -1737,7 +1844,7 @@ shared.defineProperties(LightningElement.prototype, lightningBasedDescriptors);
|
|
|
1737
1844
|
// Apply ARIA reflection to LightningElement.prototype, on both the browser and server.
|
|
1738
1845
|
// This allows `this.aria*` property accessors to work from inside a component, and to reflect `aria-*` attrs.
|
|
1739
1846
|
// Note this works regardless of whether the global ARIA reflection polyfill is applied or not.
|
|
1740
|
-
|
|
1847
|
+
applyAriaReflection(LightningElement.prototype);
|
|
1741
1848
|
shared.defineProperty(LightningElement, 'CustomElementConstructor', {
|
|
1742
1849
|
get() {
|
|
1743
1850
|
// If required, a runtime-specific implementation must be defined.
|
|
@@ -2549,7 +2656,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
|
|
|
2549
2656
|
this[propName] = newValue;
|
|
2550
2657
|
};
|
|
2551
2658
|
}
|
|
2552
|
-
function
|
|
2659
|
+
function createAccessorThatWarns(propName) {
|
|
2660
|
+
let prop;
|
|
2661
|
+
return {
|
|
2662
|
+
get() {
|
|
2663
|
+
logWarn(`The property "${propName}" is not publicly accessible. Add the @api annotation to the property declaration or getter/setter in the component to make it accessible.`);
|
|
2664
|
+
return prop;
|
|
2665
|
+
},
|
|
2666
|
+
set(value) {
|
|
2667
|
+
logWarn(`The property "${propName}" is not publicly accessible. Add the @api annotation to the property declaration or getter/setter in the component to make it accessible.`);
|
|
2668
|
+
prop = value;
|
|
2669
|
+
},
|
|
2670
|
+
enumerable: true,
|
|
2671
|
+
configurable: true,
|
|
2672
|
+
};
|
|
2673
|
+
}
|
|
2674
|
+
function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto, hasCustomSuperClass) {
|
|
2553
2675
|
const HTMLBridgeElement = class extends SuperClass {
|
|
2554
2676
|
};
|
|
2555
2677
|
// generating the hash table for attributes to avoid duplicate fields and facilitate validation
|
|
@@ -2558,9 +2680,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2558
2680
|
const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
|
|
2559
2681
|
const { observedAttributes: superObservedAttributes = [] } = SuperClass;
|
|
2560
2682
|
const descriptors = shared.create(null);
|
|
2683
|
+
// present a hint message so that developers are aware that they have not decorated property with @api
|
|
2684
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2685
|
+
// TODO [#3761]: enable for components that don't extend from LightningElement
|
|
2686
|
+
if (!shared.isUndefined(proto) && !shared.isNull(proto) && !hasCustomSuperClass) {
|
|
2687
|
+
const nonPublicPropertiesToWarnOn = new Set([
|
|
2688
|
+
// getters, setters, and methods
|
|
2689
|
+
...shared.keys(shared.getOwnPropertyDescriptors(proto)),
|
|
2690
|
+
// class properties
|
|
2691
|
+
...observedFields,
|
|
2692
|
+
]
|
|
2693
|
+
// we don't want to override HTMLElement props because these are meaningful in other ways,
|
|
2694
|
+
// and can break tooling that expects it to be iterable or defined, e.g. Jest:
|
|
2695
|
+
// https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
|
|
2696
|
+
// It also doesn't make sense to override e.g. "constructor".
|
|
2697
|
+
.filter((propName) => !(propName in HTMLElementPrototype)));
|
|
2698
|
+
for (const propName of nonPublicPropertiesToWarnOn) {
|
|
2699
|
+
if (shared.ArrayIndexOf.call(publicProperties, propName) === -1) {
|
|
2700
|
+
descriptors[propName] = createAccessorThatWarns(propName);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2561
2705
|
// expose getters and setters for each public props on the new Element Bridge
|
|
2562
|
-
for (let i = 0, len =
|
|
2563
|
-
const propName =
|
|
2706
|
+
for (let i = 0, len = publicProperties.length; i < len; i += 1) {
|
|
2707
|
+
const propName = publicProperties[i];
|
|
2564
2708
|
attributeToPropMap[shared.htmlPropertyToAttribute(propName)] = propName;
|
|
2565
2709
|
descriptors[propName] = {
|
|
2566
2710
|
get: createGetter(propName),
|
|
@@ -2585,6 +2729,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2585
2729
|
descriptors.attributeChangedCallback = {
|
|
2586
2730
|
value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
|
|
2587
2731
|
};
|
|
2732
|
+
// To avoid leaking private component details, accessing internals from outside a component is not allowed.
|
|
2733
|
+
descriptors.attachInternals = {
|
|
2734
|
+
set() {
|
|
2735
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2736
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2737
|
+
}
|
|
2738
|
+
},
|
|
2739
|
+
get() {
|
|
2740
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2741
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2742
|
+
}
|
|
2743
|
+
},
|
|
2744
|
+
};
|
|
2745
|
+
descriptors.formAssociated = {
|
|
2746
|
+
set() {
|
|
2747
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2748
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2749
|
+
}
|
|
2750
|
+
},
|
|
2751
|
+
get() {
|
|
2752
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2753
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2754
|
+
}
|
|
2755
|
+
},
|
|
2756
|
+
};
|
|
2588
2757
|
// Specify attributes for which we want to reflect changes back to their corresponding
|
|
2589
2758
|
// properties via attributeChangedCallback.
|
|
2590
2759
|
shared.defineProperty(HTMLBridgeElement, 'observedAttributes', {
|
|
@@ -2595,7 +2764,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2595
2764
|
shared.defineProperties(HTMLBridgeElement.prototype, descriptors);
|
|
2596
2765
|
return HTMLBridgeElement;
|
|
2597
2766
|
}
|
|
2598
|
-
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), []);
|
|
2767
|
+
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), [], [], null, false);
|
|
2599
2768
|
if (process.env.IS_BROWSER) {
|
|
2600
2769
|
// This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
|
|
2601
2770
|
// so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
|
|
@@ -2608,7 +2777,7 @@ if (process.env.IS_BROWSER) {
|
|
|
2608
2777
|
//
|
|
2609
2778
|
// Also note that we apply this to BaseBridgeElement.prototype to avoid excessively redefining property
|
|
2610
2779
|
// accessors inside the HTMLBridgeElementFactory.
|
|
2611
|
-
|
|
2780
|
+
applyAriaReflection(BaseBridgeElement.prototype);
|
|
2612
2781
|
}
|
|
2613
2782
|
shared.freeze(BaseBridgeElement);
|
|
2614
2783
|
shared.seal(BaseBridgeElement.prototype);
|
|
@@ -2893,7 +3062,7 @@ function getCtorProto(Ctor) {
|
|
|
2893
3062
|
return proto;
|
|
2894
3063
|
}
|
|
2895
3064
|
function createComponentDef(Ctor) {
|
|
2896
|
-
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode } = Ctor;
|
|
3065
|
+
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
|
|
2897
3066
|
if (process.env.NODE_ENV !== 'production') {
|
|
2898
3067
|
const ctorName = Ctor.name;
|
|
2899
3068
|
// Removing the following assert until https://bugs.webkit.org/show_bug.cgi?id=190140 is fixed.
|
|
@@ -2905,7 +3074,8 @@ function createComponentDef(Ctor) {
|
|
|
2905
3074
|
}
|
|
2906
3075
|
if (!shared.isUndefined(ctorShadowSupportMode) &&
|
|
2907
3076
|
ctorShadowSupportMode !== "any" /* ShadowSupportMode.Any */ &&
|
|
2908
|
-
ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */
|
|
3077
|
+
ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */ &&
|
|
3078
|
+
ctorShadowSupportMode !== "native" /* ShadowSupportMode.Native */) {
|
|
2909
3079
|
logError(`Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
|
|
2910
3080
|
}
|
|
2911
3081
|
if (!shared.isUndefined(ctorRenderMode) &&
|
|
@@ -2917,10 +3087,11 @@ function createComponentDef(Ctor) {
|
|
|
2917
3087
|
const decoratorsMeta = getDecoratorsMeta(Ctor);
|
|
2918
3088
|
const { apiFields, apiFieldsConfig, apiMethods, wiredFields, wiredMethods, observedFields } = decoratorsMeta;
|
|
2919
3089
|
const proto = Ctor.prototype;
|
|
2920
|
-
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
|
|
3090
|
+
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, formAssociatedCallback, formResetCallback, formDisabledCallback, formStateRestoreCallback, render, } = proto;
|
|
2921
3091
|
const superProto = getCtorProto(Ctor);
|
|
2922
|
-
const
|
|
2923
|
-
const
|
|
3092
|
+
const hasCustomSuperClass = superProto !== LightningElement;
|
|
3093
|
+
const superDef = hasCustomSuperClass ? getComponentInternalDef(superProto) : lightingElementDef;
|
|
3094
|
+
const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods), shared.keys(observedFields), proto, hasCustomSuperClass);
|
|
2924
3095
|
const props = shared.assign(shared.create(null), superDef.props, apiFields);
|
|
2925
3096
|
const propsConfig = shared.assign(shared.create(null), superDef.propsConfig, apiFieldsConfig);
|
|
2926
3097
|
const methods = shared.assign(shared.create(null), superDef.methods, apiMethods);
|
|
@@ -2929,6 +3100,10 @@ function createComponentDef(Ctor) {
|
|
|
2929
3100
|
disconnectedCallback = disconnectedCallback || superDef.disconnectedCallback;
|
|
2930
3101
|
renderedCallback = renderedCallback || superDef.renderedCallback;
|
|
2931
3102
|
errorCallback = errorCallback || superDef.errorCallback;
|
|
3103
|
+
formAssociatedCallback = formAssociatedCallback || superDef.formAssociatedCallback;
|
|
3104
|
+
formResetCallback = formResetCallback || superDef.formResetCallback;
|
|
3105
|
+
formDisabledCallback = formDisabledCallback || superDef.formDisabledCallback;
|
|
3106
|
+
formStateRestoreCallback = formStateRestoreCallback || superDef.formStateRestoreCallback;
|
|
2932
3107
|
render = render || superDef.render;
|
|
2933
3108
|
let shadowSupportMode = superDef.shadowSupportMode;
|
|
2934
3109
|
if (!shared.isUndefined(ctorShadowSupportMode)) {
|
|
@@ -2938,6 +3113,10 @@ function createComponentDef(Ctor) {
|
|
|
2938
3113
|
if (!shared.isUndefined(ctorRenderMode)) {
|
|
2939
3114
|
renderMode = ctorRenderMode === 'light' ? 0 /* RenderMode.Light */ : 1 /* RenderMode.Shadow */;
|
|
2940
3115
|
}
|
|
3116
|
+
let formAssociated = superDef.formAssociated;
|
|
3117
|
+
if (!shared.isUndefined(ctorFormAssociated)) {
|
|
3118
|
+
formAssociated = ctorFormAssociated;
|
|
3119
|
+
}
|
|
2941
3120
|
const template = getComponentRegisteredTemplate(Ctor) || superDef.template;
|
|
2942
3121
|
const name = Ctor.name || superDef.name;
|
|
2943
3122
|
// installing observed fields into the prototype.
|
|
@@ -2953,10 +3132,15 @@ function createComponentDef(Ctor) {
|
|
|
2953
3132
|
template,
|
|
2954
3133
|
renderMode,
|
|
2955
3134
|
shadowSupportMode,
|
|
3135
|
+
formAssociated,
|
|
2956
3136
|
connectedCallback,
|
|
2957
3137
|
disconnectedCallback,
|
|
2958
|
-
renderedCallback,
|
|
2959
3138
|
errorCallback,
|
|
3139
|
+
formAssociatedCallback,
|
|
3140
|
+
formDisabledCallback,
|
|
3141
|
+
formResetCallback,
|
|
3142
|
+
formStateRestoreCallback,
|
|
3143
|
+
renderedCallback,
|
|
2960
3144
|
render,
|
|
2961
3145
|
};
|
|
2962
3146
|
// This is a no-op unless Lightning DevTools are enabled.
|
|
@@ -3033,6 +3217,7 @@ const lightingElementDef = {
|
|
|
3033
3217
|
methods: EmptyObject,
|
|
3034
3218
|
renderMode: 1 /* RenderMode.Shadow */,
|
|
3035
3219
|
shadowSupportMode: "reset" /* ShadowSupportMode.Default */,
|
|
3220
|
+
formAssociated: undefined,
|
|
3036
3221
|
wire: EmptyObject,
|
|
3037
3222
|
bridge: BaseBridgeElement,
|
|
3038
3223
|
template: defaultEmptyTemplate,
|
|
@@ -3089,9 +3274,11 @@ function createInlineStyleVNode(content) {
|
|
|
3089
3274
|
},
|
|
3090
3275
|
}, [api.t(content)]);
|
|
3091
3276
|
}
|
|
3092
|
-
|
|
3277
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3278
|
+
function updateStylesheetToken(vm, template, legacy) {
|
|
3093
3279
|
const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
|
|
3094
|
-
const { stylesheets: newStylesheets
|
|
3280
|
+
const { stylesheets: newStylesheets } = template;
|
|
3281
|
+
const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
|
|
3095
3282
|
const { stylesheets: newVmStylesheets } = vm;
|
|
3096
3283
|
const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
3097
3284
|
const { hasScopedStyles } = context;
|
|
@@ -3099,7 +3286,19 @@ function updateStylesheetToken(vm, template) {
|
|
|
3099
3286
|
let newHasTokenInClass;
|
|
3100
3287
|
let newHasTokenInAttribute;
|
|
3101
3288
|
// Reset the styling token applied to the host element.
|
|
3102
|
-
|
|
3289
|
+
let oldToken;
|
|
3290
|
+
let oldHasTokenInClass;
|
|
3291
|
+
let oldHasTokenInAttribute;
|
|
3292
|
+
if (legacy) {
|
|
3293
|
+
oldToken = context.legacyStylesheetToken;
|
|
3294
|
+
oldHasTokenInClass = context.hasLegacyTokenInClass;
|
|
3295
|
+
oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
|
|
3296
|
+
}
|
|
3297
|
+
else {
|
|
3298
|
+
oldToken = context.stylesheetToken;
|
|
3299
|
+
oldHasTokenInClass = context.hasTokenInClass;
|
|
3300
|
+
oldHasTokenInAttribute = context.hasTokenInAttribute;
|
|
3301
|
+
}
|
|
3103
3302
|
if (!shared.isUndefined(oldToken)) {
|
|
3104
3303
|
if (oldHasTokenInClass) {
|
|
3105
3304
|
getClassList(elm).remove(makeHostToken(oldToken));
|
|
@@ -3127,9 +3326,16 @@ function updateStylesheetToken(vm, template) {
|
|
|
3127
3326
|
}
|
|
3128
3327
|
}
|
|
3129
3328
|
// Update the styling tokens present on the context object.
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3329
|
+
if (legacy) {
|
|
3330
|
+
context.legacyStylesheetToken = newToken;
|
|
3331
|
+
context.hasLegacyTokenInClass = newHasTokenInClass;
|
|
3332
|
+
context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
|
|
3333
|
+
}
|
|
3334
|
+
else {
|
|
3335
|
+
context.stylesheetToken = newToken;
|
|
3336
|
+
context.hasTokenInClass = newHasTokenInClass;
|
|
3337
|
+
context.hasTokenInAttribute = newHasTokenInAttribute;
|
|
3338
|
+
}
|
|
3133
3339
|
}
|
|
3134
3340
|
function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
|
|
3135
3341
|
const content = [];
|
|
@@ -3217,9 +3423,12 @@ function getNearestShadowComponent(vm) {
|
|
|
3217
3423
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
3218
3424
|
* it returns null.
|
|
3219
3425
|
*/
|
|
3220
|
-
|
|
3426
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3427
|
+
function getScopeTokenClass(owner, legacy) {
|
|
3221
3428
|
const { cmpTemplate, context } = owner;
|
|
3222
|
-
return (context.hasScopedStyles &&
|
|
3429
|
+
return ((context.hasScopedStyles &&
|
|
3430
|
+
(legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
|
|
3431
|
+
null);
|
|
3223
3432
|
}
|
|
3224
3433
|
/**
|
|
3225
3434
|
* This function returns the host style token for a custom element if it
|
|
@@ -3353,28 +3562,20 @@ function isLiveBindingProp(sel, key) {
|
|
|
3353
3562
|
return sel === 'input' && (key === 'value' || key === 'checked');
|
|
3354
3563
|
}
|
|
3355
3564
|
function patchProps(oldVnode, vnode, renderer) {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
if (shared.isUndefined(props) && shared.isUndefined(spread)) {
|
|
3565
|
+
const { props } = vnode.data;
|
|
3566
|
+
if (shared.isUndefined(props)) {
|
|
3359
3567
|
return;
|
|
3360
3568
|
}
|
|
3361
3569
|
let oldProps;
|
|
3362
3570
|
if (!shared.isNull(oldVnode)) {
|
|
3363
3571
|
oldProps = oldVnode.data.props;
|
|
3364
|
-
const oldSpread = oldVnode.data.spread;
|
|
3365
3572
|
// Props may be the same due to the static content optimization, so we can skip diffing
|
|
3366
|
-
if (oldProps === props
|
|
3573
|
+
if (oldProps === props) {
|
|
3367
3574
|
return;
|
|
3368
3575
|
}
|
|
3369
3576
|
if (shared.isUndefined(oldProps)) {
|
|
3370
3577
|
oldProps = EmptyObject;
|
|
3371
3578
|
}
|
|
3372
|
-
if (!shared.isUndefined(oldSpread)) {
|
|
3373
|
-
oldProps = shared.assign({}, oldProps, oldSpread);
|
|
3374
|
-
}
|
|
3375
|
-
}
|
|
3376
|
-
if (!shared.isUndefined(spread)) {
|
|
3377
|
-
props = shared.assign({}, props, spread);
|
|
3378
3579
|
}
|
|
3379
3580
|
const isFirstPatch = shared.isNull(oldVnode);
|
|
3380
3581
|
const { elm, sel } = vnode;
|
|
@@ -3548,6 +3749,113 @@ function applyStaticStyleAttribute(vnode, renderer) {
|
|
|
3548
3749
|
}
|
|
3549
3750
|
}
|
|
3550
3751
|
|
|
3752
|
+
/*
|
|
3753
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3754
|
+
* All rights reserved.
|
|
3755
|
+
* SPDX-License-Identifier: MIT
|
|
3756
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3757
|
+
*/
|
|
3758
|
+
// Set a ref (lwc:ref) on a VM, from a template API
|
|
3759
|
+
function applyRefs(vnode, owner) {
|
|
3760
|
+
const { data } = vnode;
|
|
3761
|
+
const { ref } = data;
|
|
3762
|
+
if (shared.isUndefined(ref)) {
|
|
3763
|
+
return;
|
|
3764
|
+
}
|
|
3765
|
+
if (process.env.NODE_ENV !== 'production' && shared.isUndefined(owner.refVNodes)) {
|
|
3766
|
+
throw new Error('refVNodes must be defined when setting a ref');
|
|
3767
|
+
}
|
|
3768
|
+
// If this method is called, then vm.refVNodes is set as the template has refs.
|
|
3769
|
+
// If not, then something went wrong and we threw an error above.
|
|
3770
|
+
const refVNodes = owner.refVNodes;
|
|
3771
|
+
// In cases of conflict (two elements with the same ref), prefer the last one,
|
|
3772
|
+
// in depth-first traversal order. This happens automatically due to how we render
|
|
3773
|
+
refVNodes[ref] = vnode;
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
/*
|
|
3777
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3778
|
+
* All rights reserved.
|
|
3779
|
+
* SPDX-License-Identifier: MIT
|
|
3780
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3781
|
+
*/
|
|
3782
|
+
function traverseAndSetElements(root, parts, renderer) {
|
|
3783
|
+
const numParts = parts.length;
|
|
3784
|
+
// Optimization given that, in most cases, there will be one part, and it's just the root
|
|
3785
|
+
if (numParts === 1) {
|
|
3786
|
+
const firstPart = parts[0];
|
|
3787
|
+
if (firstPart.partId === 0) {
|
|
3788
|
+
// 0 means the root node
|
|
3789
|
+
firstPart.elm = root;
|
|
3790
|
+
return;
|
|
3791
|
+
}
|
|
3792
|
+
}
|
|
3793
|
+
const partIdsToParts = new Map();
|
|
3794
|
+
for (const staticPart of parts) {
|
|
3795
|
+
partIdsToParts.set(staticPart.partId, staticPart);
|
|
3796
|
+
}
|
|
3797
|
+
let numFoundParts = 0;
|
|
3798
|
+
const { previousSibling, getLastChild } = renderer;
|
|
3799
|
+
const stack = [root];
|
|
3800
|
+
let partId = -1;
|
|
3801
|
+
// Depth-first traversal. We assign a partId to each element, which is an integer based on traversal order.
|
|
3802
|
+
while (stack.length > 0) {
|
|
3803
|
+
const elm = shared.ArrayShift.call(stack);
|
|
3804
|
+
partId++;
|
|
3805
|
+
const part = partIdsToParts.get(partId);
|
|
3806
|
+
if (!shared.isUndefined(part)) {
|
|
3807
|
+
part.elm = elm;
|
|
3808
|
+
if (++numFoundParts === numParts) {
|
|
3809
|
+
return; // perf optimization - stop traversing once we've found everything we need
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
// For depth-first traversal, prepend to the stack in reverse order
|
|
3813
|
+
// Note that we traverse using `*Child`/`*Sibling` rather than `children` because the browser uses a linked
|
|
3814
|
+
// list under the hood to represent the DOM tree, so it's faster to do this than to create an underlying array
|
|
3815
|
+
// by calling `children`.
|
|
3816
|
+
let child = getLastChild(elm);
|
|
3817
|
+
while (!shared.isNull(child)) {
|
|
3818
|
+
shared.ArrayUnshift.call(stack, child);
|
|
3819
|
+
child = previousSibling(child);
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3823
|
+
shared.assert.isTrue(numFoundParts === numParts, `Should have found all parts by now. Found ${numFoundParts}, needed ${numParts}.`);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
/**
|
|
3827
|
+
* Given an array of static parts, do all the mounting required for these parts.
|
|
3828
|
+
*
|
|
3829
|
+
* @param root - the root element
|
|
3830
|
+
* @param vnode - the parent VStatic
|
|
3831
|
+
* @param renderer - the renderer to use
|
|
3832
|
+
* @param mount - true this is a first (mount) render as opposed to a subsequent (patch) render
|
|
3833
|
+
*/
|
|
3834
|
+
function applyStaticParts(root, vnode, renderer, mount) {
|
|
3835
|
+
// On the server, we don't support ref (because it relies on renderedCallback), nor do we
|
|
3836
|
+
// support event listeners (no interactivity), so traversing parts makes no sense
|
|
3837
|
+
if (!process.env.IS_BROWSER) {
|
|
3838
|
+
return;
|
|
3839
|
+
}
|
|
3840
|
+
const { parts, owner } = vnode;
|
|
3841
|
+
if (shared.isUndefined(parts)) {
|
|
3842
|
+
return;
|
|
3843
|
+
}
|
|
3844
|
+
// This adds `part.elm` to each `part`. We have to do this on every mount/patch because the `parts`
|
|
3845
|
+
// array is recreated from scratch every time, so each `part.elm` is now undefined.
|
|
3846
|
+
// TODO [#3800]: avoid calling traverseAndSetElements on every re-render
|
|
3847
|
+
traverseAndSetElements(root, parts, renderer);
|
|
3848
|
+
// Currently only event listeners and refs are supported for static vnodes
|
|
3849
|
+
for (const part of parts) {
|
|
3850
|
+
if (mount) {
|
|
3851
|
+
// Event listeners only need to be applied once when mounting
|
|
3852
|
+
applyEventListeners(part, renderer);
|
|
3853
|
+
}
|
|
3854
|
+
// Refs must be updated after every render due to refVNodes getting reset before every render
|
|
3855
|
+
applyRefs(part, owner);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
|
|
3551
3859
|
/*
|
|
3552
3860
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
3553
3861
|
* All rights reserved.
|
|
@@ -3590,7 +3898,7 @@ function patch(n1, n2, parent, renderer) {
|
|
|
3590
3898
|
patchComment(n1, n2, renderer);
|
|
3591
3899
|
break;
|
|
3592
3900
|
case 4 /* VNodeType.Static */:
|
|
3593
|
-
n2
|
|
3901
|
+
patchStatic(n1, n2, renderer);
|
|
3594
3902
|
break;
|
|
3595
3903
|
case 5 /* VNodeType.Fragment */:
|
|
3596
3904
|
patchFragment(n1, n2, parent, renderer);
|
|
@@ -3684,13 +3992,18 @@ function mountElement(vnode, parent, anchor, renderer) {
|
|
|
3684
3992
|
applyStyleScoping(elm, owner, renderer);
|
|
3685
3993
|
applyDomManual(elm, vnode);
|
|
3686
3994
|
applyElementRestrictions(elm, vnode);
|
|
3687
|
-
|
|
3995
|
+
patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
|
|
3688
3996
|
insertNode(elm, parent, anchor, renderer);
|
|
3689
3997
|
mountVNodes(vnode.children, elm, renderer, null);
|
|
3690
3998
|
}
|
|
3999
|
+
function patchStatic(n1, n2, renderer) {
|
|
4000
|
+
const elm = (n2.elm = n1.elm);
|
|
4001
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
4002
|
+
applyStaticParts(elm, n2, renderer, false);
|
|
4003
|
+
}
|
|
3691
4004
|
function patchElement(n1, n2, renderer) {
|
|
3692
4005
|
const elm = (n2.elm = n1.elm);
|
|
3693
|
-
|
|
4006
|
+
patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
|
|
3694
4007
|
patchChildren(n1.children, n2.children, elm, renderer);
|
|
3695
4008
|
}
|
|
3696
4009
|
function mountStatic(vnode, parent, anchor, renderer) {
|
|
@@ -3707,8 +4020,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
|
|
|
3707
4020
|
}
|
|
3708
4021
|
}
|
|
3709
4022
|
insertNode(elm, parent, anchor, renderer);
|
|
3710
|
-
|
|
3711
|
-
applyEventListeners(vnode, renderer);
|
|
4023
|
+
applyStaticParts(elm, vnode, renderer, true);
|
|
3712
4024
|
}
|
|
3713
4025
|
function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
3714
4026
|
const { sel, owner } = vnode;
|
|
@@ -3724,22 +4036,38 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3724
4036
|
// the custom element from the registry is expecting an upgrade callback
|
|
3725
4037
|
vm = createViewModelHook(elm, vnode, renderer);
|
|
3726
4038
|
};
|
|
3727
|
-
|
|
3728
|
-
|
|
4039
|
+
let connectedCallback;
|
|
4040
|
+
let disconnectedCallback;
|
|
4041
|
+
let formAssociatedCallback;
|
|
4042
|
+
let formDisabledCallback;
|
|
4043
|
+
let formResetCallback;
|
|
4044
|
+
let formStateRestoreCallback;
|
|
4045
|
+
if (lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
4046
|
+
connectedCallback = (elm) => {
|
|
3729
4047
|
connectRootElement(elm);
|
|
3730
|
-
}
|
|
3731
|
-
|
|
3732
|
-
const disconnectedCallback = (elm) => {
|
|
3733
|
-
if (shouldUseNativeCustomElementLifecycle(vm)) {
|
|
4048
|
+
};
|
|
4049
|
+
disconnectedCallback = (elm) => {
|
|
3734
4050
|
disconnectRootElement(elm);
|
|
3735
|
-
}
|
|
3736
|
-
|
|
4051
|
+
};
|
|
4052
|
+
formAssociatedCallback = (elm) => {
|
|
4053
|
+
runFormAssociatedCallback(elm);
|
|
4054
|
+
};
|
|
4055
|
+
formDisabledCallback = (elm) => {
|
|
4056
|
+
runFormDisabledCallback(elm);
|
|
4057
|
+
};
|
|
4058
|
+
formResetCallback = (elm) => {
|
|
4059
|
+
runFormResetCallback(elm);
|
|
4060
|
+
};
|
|
4061
|
+
formStateRestoreCallback = (elm) => {
|
|
4062
|
+
runFormStateRestoreCallback(elm);
|
|
4063
|
+
};
|
|
4064
|
+
}
|
|
3737
4065
|
// Should never get a tag with upper case letter at this point; the compiler
|
|
3738
4066
|
// should produce only tags with lowercase letters. However, the Java
|
|
3739
4067
|
// compiler may generate tagnames with uppercase letters so - for backwards
|
|
3740
4068
|
// compatibility, we lower case the tagname here.
|
|
3741
4069
|
const normalizedTagname = sel.toLowerCase();
|
|
3742
|
-
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback);
|
|
4070
|
+
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback, formAssociatedCallback, formDisabledCallback, formResetCallback, formStateRestoreCallback);
|
|
3743
4071
|
vnode.elm = elm;
|
|
3744
4072
|
vnode.vm = vm;
|
|
3745
4073
|
linkNodeToShadow(elm, owner, renderer);
|
|
@@ -3747,11 +4075,11 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3747
4075
|
if (vm) {
|
|
3748
4076
|
allocateChildren(vnode, vm);
|
|
3749
4077
|
}
|
|
3750
|
-
|
|
4078
|
+
patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
|
|
3751
4079
|
insertNode(elm, parent, anchor, renderer);
|
|
3752
4080
|
if (vm) {
|
|
3753
4081
|
if (process.env.IS_BROWSER) {
|
|
3754
|
-
if (!
|
|
4082
|
+
if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
3755
4083
|
if (process.env.NODE_ENV !== 'production') {
|
|
3756
4084
|
// With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
|
|
3757
4085
|
// noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
|
|
@@ -3784,7 +4112,7 @@ function patchCustomElement(n1, n2, parent, renderer) {
|
|
|
3784
4112
|
// Otherwise patch the existing component with new props/attrs/etc.
|
|
3785
4113
|
const elm = (n2.elm = n1.elm);
|
|
3786
4114
|
const vm = (n2.vm = n1.vm);
|
|
3787
|
-
|
|
4115
|
+
patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
|
|
3788
4116
|
if (!shared.isUndefined(vm)) {
|
|
3789
4117
|
// in fallback mode, the allocation will always set children to
|
|
3790
4118
|
// empty and delegate the real allocation to the slot elements
|
|
@@ -3931,7 +4259,7 @@ function removeNode(node, parent, renderer) {
|
|
|
3931
4259
|
lockDomMutation();
|
|
3932
4260
|
}
|
|
3933
4261
|
}
|
|
3934
|
-
function
|
|
4262
|
+
function patchElementPropsAndAttrsAndRefs$1(oldVnode, vnode, renderer) {
|
|
3935
4263
|
if (shared.isNull(oldVnode)) {
|
|
3936
4264
|
applyEventListeners(vnode, renderer);
|
|
3937
4265
|
applyStaticClassAttribute(vnode, renderer);
|
|
@@ -3943,20 +4271,39 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
|
|
|
3943
4271
|
patchStyleAttribute(oldVnode, vnode, renderer);
|
|
3944
4272
|
patchAttributes(oldVnode, vnode, renderer);
|
|
3945
4273
|
patchProps(oldVnode, vnode, renderer);
|
|
4274
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
4275
|
+
applyRefs(vnode, vnode.owner);
|
|
3946
4276
|
}
|
|
3947
4277
|
function applyStyleScoping(elm, owner, renderer) {
|
|
4278
|
+
const { getClassList } = renderer;
|
|
3948
4279
|
// Set the class name for `*.scoped.css` style scoping.
|
|
3949
|
-
const scopeToken = getScopeTokenClass(owner);
|
|
4280
|
+
const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
3950
4281
|
if (!shared.isNull(scopeToken)) {
|
|
3951
|
-
const { getClassList } = renderer;
|
|
3952
4282
|
// TODO [#2762]: this dot notation with add is probably problematic
|
|
3953
4283
|
// probably we should have a renderer api for just the add operation
|
|
3954
4284
|
getClassList(elm).add(scopeToken);
|
|
3955
4285
|
}
|
|
4286
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
4287
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4288
|
+
const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
|
|
4289
|
+
if (!shared.isNull(legacyScopeToken)) {
|
|
4290
|
+
// TODO [#2762]: this dot notation with add is probably problematic
|
|
4291
|
+
// probably we should have a renderer api for just the add operation
|
|
4292
|
+
getClassList(elm).add(legacyScopeToken);
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
3956
4295
|
// Set property element for synthetic shadow DOM style scoping.
|
|
3957
4296
|
const { stylesheetToken: syntheticToken } = owner.context;
|
|
3958
|
-
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */
|
|
3959
|
-
|
|
4297
|
+
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
4298
|
+
if (!shared.isUndefined(syntheticToken)) {
|
|
4299
|
+
elm.$shadowToken$ = syntheticToken;
|
|
4300
|
+
}
|
|
4301
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4302
|
+
const legacyToken = owner.context.legacyStylesheetToken;
|
|
4303
|
+
if (!shared.isUndefined(legacyToken)) {
|
|
4304
|
+
elm.$legacyShadowToken$ = legacyToken;
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
3960
4307
|
}
|
|
3961
4308
|
}
|
|
3962
4309
|
function applyDomManual(elm, vnode) {
|
|
@@ -4316,14 +4663,6 @@ function updateStaticChildren(c1, c2, parent, renderer) {
|
|
|
4316
4663
|
}
|
|
4317
4664
|
}
|
|
4318
4665
|
}
|
|
4319
|
-
function shouldUseNativeCustomElementLifecycle(vm) {
|
|
4320
|
-
if (lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
4321
|
-
// temporary "kill switch"
|
|
4322
|
-
return false;
|
|
4323
|
-
}
|
|
4324
|
-
const apiVersion = getComponentAPIVersion(vm.component.constructor);
|
|
4325
|
-
return shared.isAPIFeatureEnabled(5 /* APIFeature.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE */, apiVersion);
|
|
4326
|
-
}
|
|
4327
4666
|
|
|
4328
4667
|
/*
|
|
4329
4668
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -4335,6 +4674,14 @@ const SymbolIterator = Symbol.iterator;
|
|
|
4335
4674
|
function addVNodeToChildLWC(vnode) {
|
|
4336
4675
|
shared.ArrayPush.call(getVMBeingRendered().velements, vnode);
|
|
4337
4676
|
}
|
|
4677
|
+
// [s]tatic [p]art
|
|
4678
|
+
function sp(partId, data) {
|
|
4679
|
+
return {
|
|
4680
|
+
partId,
|
|
4681
|
+
data,
|
|
4682
|
+
elm: undefined, // elm is defined later
|
|
4683
|
+
};
|
|
4684
|
+
}
|
|
4338
4685
|
// [s]coped [s]lot [f]actory
|
|
4339
4686
|
function ssf(slotName, factory) {
|
|
4340
4687
|
return {
|
|
@@ -4348,7 +4695,7 @@ function ssf(slotName, factory) {
|
|
|
4348
4695
|
};
|
|
4349
4696
|
}
|
|
4350
4697
|
// [st]atic node
|
|
4351
|
-
function st(fragment, key,
|
|
4698
|
+
function st(fragment, key, parts) {
|
|
4352
4699
|
const owner = getVMBeingRendered();
|
|
4353
4700
|
const vnode = {
|
|
4354
4701
|
type: 4 /* VNodeType.Static */,
|
|
@@ -4357,12 +4704,8 @@ function st(fragment, key, data) {
|
|
|
4357
4704
|
elm: undefined,
|
|
4358
4705
|
fragment,
|
|
4359
4706
|
owner,
|
|
4360
|
-
|
|
4707
|
+
parts,
|
|
4361
4708
|
};
|
|
4362
|
-
const ref = data === null || data === void 0 ? void 0 : data.ref;
|
|
4363
|
-
if (!shared.isUndefined(ref)) {
|
|
4364
|
-
setRefVNode(owner, ref, vnode);
|
|
4365
|
-
}
|
|
4366
4709
|
return vnode;
|
|
4367
4710
|
}
|
|
4368
4711
|
// [fr]agment node
|
|
@@ -4404,7 +4747,7 @@ function h(sel, data, children = EmptyArray) {
|
|
|
4404
4747
|
}
|
|
4405
4748
|
});
|
|
4406
4749
|
}
|
|
4407
|
-
const { key
|
|
4750
|
+
const { key } = data;
|
|
4408
4751
|
const vnode = {
|
|
4409
4752
|
type: 2 /* VNodeType.Element */,
|
|
4410
4753
|
sel,
|
|
@@ -4414,9 +4757,6 @@ function h(sel, data, children = EmptyArray) {
|
|
|
4414
4757
|
key,
|
|
4415
4758
|
owner: vmBeingRendered,
|
|
4416
4759
|
};
|
|
4417
|
-
if (!shared.isUndefined(ref)) {
|
|
4418
|
-
setRefVNode(vmBeingRendered, ref, vnode);
|
|
4419
|
-
}
|
|
4420
4760
|
return vnode;
|
|
4421
4761
|
}
|
|
4422
4762
|
// [t]ab[i]ndex function
|
|
@@ -4531,7 +4871,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4531
4871
|
});
|
|
4532
4872
|
}
|
|
4533
4873
|
}
|
|
4534
|
-
const { key
|
|
4874
|
+
const { key } = data;
|
|
4535
4875
|
let elm, aChildren, vm;
|
|
4536
4876
|
const vnode = {
|
|
4537
4877
|
type: 3 /* VNodeType.CustomElement */,
|
|
@@ -4547,9 +4887,6 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4547
4887
|
vm,
|
|
4548
4888
|
};
|
|
4549
4889
|
addVNodeToChildLWC(vnode);
|
|
4550
|
-
if (!shared.isUndefined(ref)) {
|
|
4551
|
-
setRefVNode(vmBeingRendered, ref, vnode);
|
|
4552
|
-
}
|
|
4553
4890
|
return vnode;
|
|
4554
4891
|
}
|
|
4555
4892
|
// [i]terable node
|
|
@@ -4840,6 +5177,7 @@ const api = shared.freeze({
|
|
|
4840
5177
|
shc,
|
|
4841
5178
|
ssf,
|
|
4842
5179
|
ddc,
|
|
5180
|
+
sp,
|
|
4843
5181
|
});
|
|
4844
5182
|
|
|
4845
5183
|
/*
|
|
@@ -4997,9 +5335,10 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
4997
5335
|
return (strings, ...keys) => {
|
|
4998
5336
|
const cache = shared.create(null);
|
|
4999
5337
|
return function () {
|
|
5000
|
-
const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5338
|
+
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5001
5339
|
const hasStyleToken = !shared.isUndefined(stylesheetToken);
|
|
5002
5340
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5341
|
+
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
|
|
5003
5342
|
let cacheKey = 0;
|
|
5004
5343
|
if (hasStyleToken && hasScopedStyles) {
|
|
5005
5344
|
cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
|
|
@@ -5007,12 +5346,19 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5007
5346
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5008
5347
|
cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
|
|
5009
5348
|
}
|
|
5349
|
+
if (hasLegacyToken) {
|
|
5350
|
+
// This isn't strictly required for prod, but it's required for our karma tests
|
|
5351
|
+
// since the lwcRuntimeFlag may change over time
|
|
5352
|
+
cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
|
|
5353
|
+
}
|
|
5010
5354
|
if (!shared.isUndefined(cache[cacheKey])) {
|
|
5011
5355
|
return cache[cacheKey];
|
|
5012
5356
|
}
|
|
5013
|
-
|
|
5014
|
-
const
|
|
5015
|
-
const
|
|
5357
|
+
// If legacy stylesheet tokens are required, then add them to the rendered string
|
|
5358
|
+
const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
|
|
5359
|
+
const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
|
|
5360
|
+
const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
|
|
5361
|
+
const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
|
|
5016
5362
|
let htmlFragment = '';
|
|
5017
5363
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
5018
5364
|
switch (keys[i]) {
|
|
@@ -5088,7 +5434,10 @@ function evaluateTemplate(vm, html) {
|
|
|
5088
5434
|
// Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
|
|
5089
5435
|
context.hasScopedStyles = computeHasScopedStyles(html, vm);
|
|
5090
5436
|
// Update the scoping token on the host element.
|
|
5091
|
-
updateStylesheetToken(vm, html);
|
|
5437
|
+
updateStylesheetToken(vm, html, /* legacy */ false);
|
|
5438
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
5439
|
+
updateStylesheetToken(vm, html, /* legacy */ true);
|
|
5440
|
+
}
|
|
5092
5441
|
// Evaluate, create stylesheet and cache the produced VNode for future
|
|
5093
5442
|
// re-rendering.
|
|
5094
5443
|
const stylesheetsContent = getStylesheetsContent(vm, html);
|
|
@@ -5103,8 +5452,6 @@ function evaluateTemplate(vm, html) {
|
|
|
5103
5452
|
// add the VM to the list of host VMs that can be re-rendered if html is swapped
|
|
5104
5453
|
setActiveVM(vm);
|
|
5105
5454
|
}
|
|
5106
|
-
// reset the refs; they will be set during the tmpl() instantiation
|
|
5107
|
-
vm.refVNodes = html.hasRefs ? shared.create(null) : null;
|
|
5108
5455
|
// right before producing the vnodes, we clear up all internal references
|
|
5109
5456
|
// to custom elements from the template.
|
|
5110
5457
|
vm.velements = [];
|
|
@@ -5274,8 +5621,9 @@ function getComponentAPIVersion(Ctor) {
|
|
|
5274
5621
|
const metadata = registeredComponentMap.get(Ctor);
|
|
5275
5622
|
const apiVersion = metadata === null || metadata === void 0 ? void 0 : metadata.apiVersion;
|
|
5276
5623
|
if (shared.isUndefined(apiVersion)) {
|
|
5277
|
-
// This should only occur in
|
|
5278
|
-
//
|
|
5624
|
+
// This should only occur in our Karma tests; in practice every component
|
|
5625
|
+
// is registered, and so this code path should not get hit. But to be safe,
|
|
5626
|
+
// return the lowest possible version.
|
|
5279
5627
|
return shared.LOWEST_API_VERSION;
|
|
5280
5628
|
}
|
|
5281
5629
|
return apiVersion;
|
|
@@ -5323,44 +5671,6 @@ function getWrappedComponentsListener(vm, listener) {
|
|
|
5323
5671
|
return wrappedListener;
|
|
5324
5672
|
}
|
|
5325
5673
|
|
|
5326
|
-
/*
|
|
5327
|
-
* Copyright (c) 2018, salesforce.com, inc.
|
|
5328
|
-
* All rights reserved.
|
|
5329
|
-
* SPDX-License-Identifier: MIT
|
|
5330
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5331
|
-
*/
|
|
5332
|
-
const Services = shared.create(null);
|
|
5333
|
-
const hooks = ['rendered', 'connected', 'disconnected'];
|
|
5334
|
-
/**
|
|
5335
|
-
* EXPERIMENTAL: This function allows for the registration of "services"
|
|
5336
|
-
* in LWC by exposing hooks into the component life-cycle. This API is
|
|
5337
|
-
* subject to change or being removed.
|
|
5338
|
-
*/
|
|
5339
|
-
function register(service) {
|
|
5340
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5341
|
-
shared.assert.isTrue(shared.isObject(service), `Invalid service declaration, ${service}: service must be an object`);
|
|
5342
|
-
}
|
|
5343
|
-
for (let i = 0; i < hooks.length; ++i) {
|
|
5344
|
-
const hookName = hooks[i];
|
|
5345
|
-
if (hookName in service) {
|
|
5346
|
-
let l = Services[hookName];
|
|
5347
|
-
if (shared.isUndefined(l)) {
|
|
5348
|
-
Services[hookName] = l = [];
|
|
5349
|
-
}
|
|
5350
|
-
shared.ArrayPush.call(l, service[hookName]);
|
|
5351
|
-
}
|
|
5352
|
-
}
|
|
5353
|
-
}
|
|
5354
|
-
function invokeServiceHook(vm, cbs) {
|
|
5355
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5356
|
-
shared.assert.isTrue(shared.isArray(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`);
|
|
5357
|
-
}
|
|
5358
|
-
const { component, def, context } = vm;
|
|
5359
|
-
for (let i = 0, len = cbs.length; i < len; ++i) {
|
|
5360
|
-
cbs[i].call(undefined, component, {}, def, context);
|
|
5361
|
-
}
|
|
5362
|
-
}
|
|
5363
|
-
|
|
5364
5674
|
/*
|
|
5365
5675
|
* Copyright (c) 2023, Salesforce.com, inc.
|
|
5366
5676
|
* All rights reserved.
|
|
@@ -5419,12 +5729,18 @@ function resetComponentStateWhenRemoved(vm) {
|
|
|
5419
5729
|
// old vnode.children is removed from the DOM.
|
|
5420
5730
|
function removeVM(vm) {
|
|
5421
5731
|
if (process.env.NODE_ENV !== 'production') {
|
|
5422
|
-
|
|
5732
|
+
if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
5733
|
+
// With native lifecycle, we cannot be certain that connectedCallback was called before a component
|
|
5734
|
+
// was removed from the VDOM. If the component is disconnected, then connectedCallback will not fire
|
|
5735
|
+
// in native mode, although it will fire in synthetic mode due to appendChild triggering it.
|
|
5736
|
+
// See: W-14037619 for details
|
|
5737
|
+
shared.assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
|
|
5738
|
+
}
|
|
5423
5739
|
}
|
|
5424
5740
|
resetComponentStateWhenRemoved(vm);
|
|
5425
5741
|
}
|
|
5426
|
-
function getNearestShadowAncestor(
|
|
5427
|
-
let ancestor =
|
|
5742
|
+
function getNearestShadowAncestor(owner) {
|
|
5743
|
+
let ancestor = owner;
|
|
5428
5744
|
while (!shared.isNull(ancestor) && ancestor.renderMode === 0 /* RenderMode.Light */) {
|
|
5429
5745
|
ancestor = ancestor.owner;
|
|
5430
5746
|
}
|
|
@@ -5458,6 +5774,9 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5458
5774
|
stylesheetToken: undefined,
|
|
5459
5775
|
hasTokenInClass: undefined,
|
|
5460
5776
|
hasTokenInAttribute: undefined,
|
|
5777
|
+
legacyStylesheetToken: undefined,
|
|
5778
|
+
hasLegacyTokenInClass: undefined,
|
|
5779
|
+
hasLegacyTokenInAttribute: undefined,
|
|
5461
5780
|
hasScopedStyles: undefined,
|
|
5462
5781
|
styleVNodes: null,
|
|
5463
5782
|
tplCache: EmptyObject,
|
|
@@ -5482,15 +5801,12 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5482
5801
|
vm.debugInfo = shared.create(null);
|
|
5483
5802
|
}
|
|
5484
5803
|
vm.stylesheets = computeStylesheets(vm, def.ctor);
|
|
5485
|
-
vm.shadowMode = computeShadowMode(vm, renderer);
|
|
5804
|
+
vm.shadowMode = computeShadowMode(def, vm.owner, renderer);
|
|
5486
5805
|
vm.tro = getTemplateReactiveObserver(vm);
|
|
5487
5806
|
if (process.env.NODE_ENV !== 'production') {
|
|
5488
5807
|
vm.toString = () => {
|
|
5489
5808
|
return `[object:vm ${def.name} (${vm.idx})]`;
|
|
5490
5809
|
};
|
|
5491
|
-
if (lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
|
|
5492
|
-
vm.shadowMode = 0 /* ShadowMode.Native */;
|
|
5493
|
-
}
|
|
5494
5810
|
}
|
|
5495
5811
|
// Create component instance associated to the vm and the element.
|
|
5496
5812
|
invokeComponentConstructor(vm, def.ctor);
|
|
@@ -5553,8 +5869,21 @@ function warnOnStylesheetsMutation(ctor) {
|
|
|
5553
5869
|
});
|
|
5554
5870
|
}
|
|
5555
5871
|
}
|
|
5556
|
-
|
|
5557
|
-
|
|
5872
|
+
// Compute the shadowMode/renderMode without creating a VM. This is used in some scenarios like hydration.
|
|
5873
|
+
function computeShadowAndRenderMode(Ctor, renderer) {
|
|
5874
|
+
const def = getComponentInternalDef(Ctor);
|
|
5875
|
+
const { renderMode } = def;
|
|
5876
|
+
// Assume null `owner` - this is what happens in hydration cases anyway
|
|
5877
|
+
const shadowMode = computeShadowMode(def, /* owner */ null, renderer);
|
|
5878
|
+
return { renderMode, shadowMode };
|
|
5879
|
+
}
|
|
5880
|
+
function computeShadowMode(def, owner, renderer) {
|
|
5881
|
+
// Force the shadow mode to always be native. Used for running tests with synthetic shadow patches
|
|
5882
|
+
// on, but components running in actual native shadow mode
|
|
5883
|
+
if (process.env.NODE_ENV !== 'production' &&
|
|
5884
|
+
lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
|
|
5885
|
+
return 0 /* ShadowMode.Native */;
|
|
5886
|
+
}
|
|
5558
5887
|
const { isSyntheticShadowDefined } = renderer;
|
|
5559
5888
|
let shadowMode;
|
|
5560
5889
|
if (isSyntheticShadowDefined) {
|
|
@@ -5563,12 +5892,14 @@ function computeShadowMode(vm, renderer) {
|
|
|
5563
5892
|
// everything defaults to native when the synthetic shadow polyfill is unavailable.
|
|
5564
5893
|
shadowMode = 0 /* ShadowMode.Native */;
|
|
5565
5894
|
}
|
|
5566
|
-
else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE
|
|
5567
|
-
|
|
5895
|
+
else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE ||
|
|
5896
|
+
def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
|
|
5897
|
+
if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */ ||
|
|
5898
|
+
def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
|
|
5568
5899
|
shadowMode = 0 /* ShadowMode.Native */;
|
|
5569
5900
|
}
|
|
5570
5901
|
else {
|
|
5571
|
-
const shadowAncestor = getNearestShadowAncestor(
|
|
5902
|
+
const shadowAncestor = getNearestShadowAncestor(owner);
|
|
5572
5903
|
if (!shared.isNull(shadowAncestor) && shadowAncestor.shadowMode === 0 /* ShadowMode.Native */) {
|
|
5573
5904
|
// Transitive support for native Shadow DOM. A component in native mode
|
|
5574
5905
|
// transitively opts all of its descendants into native.
|
|
@@ -5623,6 +5954,8 @@ function rehydrate(vm) {
|
|
|
5623
5954
|
}
|
|
5624
5955
|
function patchShadowRoot(vm, newCh) {
|
|
5625
5956
|
const { renderRoot, children: oldCh, renderer } = vm;
|
|
5957
|
+
// reset the refs; they will be set during `patchChildren`
|
|
5958
|
+
resetRefVNodes(vm);
|
|
5626
5959
|
// caching the new children collection
|
|
5627
5960
|
vm.children = newCh;
|
|
5628
5961
|
if (newCh.length > 0 || oldCh.length > 0) {
|
|
@@ -5654,10 +5987,6 @@ function runRenderedCallback(vm) {
|
|
|
5654
5987
|
if (!process.env.IS_BROWSER) {
|
|
5655
5988
|
return;
|
|
5656
5989
|
}
|
|
5657
|
-
const { rendered } = Services;
|
|
5658
|
-
if (rendered) {
|
|
5659
|
-
invokeServiceHook(vm, rendered);
|
|
5660
|
-
}
|
|
5661
5990
|
if (!shared.isUndefined(renderedCallback)) {
|
|
5662
5991
|
logOperationStart(4 /* OperationId.RenderedCallback */, vm);
|
|
5663
5992
|
invokeComponentCallback(vm, renderedCallback);
|
|
@@ -5700,11 +6029,6 @@ function runConnectedCallback(vm) {
|
|
|
5700
6029
|
return; // nothing to do since it was already connected
|
|
5701
6030
|
}
|
|
5702
6031
|
vm.state = 1 /* VMState.connected */;
|
|
5703
|
-
// reporting connection
|
|
5704
|
-
const { connected } = Services;
|
|
5705
|
-
if (connected) {
|
|
5706
|
-
invokeServiceHook(vm, connected);
|
|
5707
|
-
}
|
|
5708
6032
|
if (hasWireAdapters(vm)) {
|
|
5709
6033
|
connectWireAdapters(vm);
|
|
5710
6034
|
}
|
|
@@ -5730,11 +6054,6 @@ function runDisconnectedCallback(vm) {
|
|
|
5730
6054
|
vm.isDirty = true;
|
|
5731
6055
|
}
|
|
5732
6056
|
vm.state = 2 /* VMState.disconnected */;
|
|
5733
|
-
// reporting disconnection
|
|
5734
|
-
const { disconnected } = Services;
|
|
5735
|
-
if (disconnected) {
|
|
5736
|
-
invokeServiceHook(vm, disconnected);
|
|
5737
|
-
}
|
|
5738
6057
|
if (hasWireAdapters(vm)) {
|
|
5739
6058
|
disconnectWireAdapters(vm);
|
|
5740
6059
|
}
|
|
@@ -5859,7 +6178,12 @@ function runWithBoundaryProtection(vm, owner, pre, job, post) {
|
|
|
5859
6178
|
if (!shared.isUndefined(error)) {
|
|
5860
6179
|
addErrorComponentStack(vm, error);
|
|
5861
6180
|
const errorBoundaryVm = shared.isNull(owner) ? undefined : getErrorBoundaryVM(owner);
|
|
5862
|
-
|
|
6181
|
+
// Error boundaries are not in effect when server-side rendering. `errorCallback`
|
|
6182
|
+
// is intended to allow recovery from errors - changing the state of a component
|
|
6183
|
+
// and instigating a re-render. That is at odds with the single-pass, synchronous
|
|
6184
|
+
// nature of SSR. For that reason, all errors bubble up to the `renderComponent`
|
|
6185
|
+
// call site.
|
|
6186
|
+
if (!process.env.IS_BROWSER || shared.isUndefined(errorBoundaryVm)) {
|
|
5863
6187
|
throw error; // eslint-disable-line no-unsafe-finally
|
|
5864
6188
|
}
|
|
5865
6189
|
resetComponentRoot(vm); // remove offenders
|
|
@@ -5887,6 +6211,52 @@ function forceRehydration(vm) {
|
|
|
5887
6211
|
scheduleRehydration(vm);
|
|
5888
6212
|
}
|
|
5889
6213
|
}
|
|
6214
|
+
function runFormAssociatedCustomElementCallback(vm, faceCb) {
|
|
6215
|
+
const { renderMode, shadowMode, def: { formAssociated }, } = vm;
|
|
6216
|
+
// Technically the UpgradableConstructor always sets `static formAssociated = true` but silently fail here to match browser behavior.
|
|
6217
|
+
if (shared.isUndefined(formAssociated) || shared.isFalse(formAssociated)) {
|
|
6218
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6219
|
+
logWarn(`Form associated lifecycle methods must have the 'static formAssociated' value set in the component's prototype chain.`);
|
|
6220
|
+
}
|
|
6221
|
+
return;
|
|
6222
|
+
}
|
|
6223
|
+
if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
|
|
6224
|
+
throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
|
|
6225
|
+
}
|
|
6226
|
+
invokeComponentCallback(vm, faceCb);
|
|
6227
|
+
}
|
|
6228
|
+
function runFormAssociatedCallback(elm) {
|
|
6229
|
+
const vm = getAssociatedVM(elm);
|
|
6230
|
+
const { formAssociatedCallback } = vm.def;
|
|
6231
|
+
if (!shared.isUndefined(formAssociatedCallback)) {
|
|
6232
|
+
runFormAssociatedCustomElementCallback(vm, formAssociatedCallback);
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
function runFormDisabledCallback(elm) {
|
|
6236
|
+
const vm = getAssociatedVM(elm);
|
|
6237
|
+
const { formDisabledCallback } = vm.def;
|
|
6238
|
+
if (!shared.isUndefined(formDisabledCallback)) {
|
|
6239
|
+
runFormAssociatedCustomElementCallback(vm, formDisabledCallback);
|
|
6240
|
+
}
|
|
6241
|
+
}
|
|
6242
|
+
function runFormResetCallback(elm) {
|
|
6243
|
+
const vm = getAssociatedVM(elm);
|
|
6244
|
+
const { formResetCallback } = vm.def;
|
|
6245
|
+
if (!shared.isUndefined(formResetCallback)) {
|
|
6246
|
+
runFormAssociatedCustomElementCallback(vm, formResetCallback);
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
function runFormStateRestoreCallback(elm) {
|
|
6250
|
+
const vm = getAssociatedVM(elm);
|
|
6251
|
+
const { formStateRestoreCallback } = vm.def;
|
|
6252
|
+
if (!shared.isUndefined(formStateRestoreCallback)) {
|
|
6253
|
+
runFormAssociatedCustomElementCallback(vm, formStateRestoreCallback);
|
|
6254
|
+
}
|
|
6255
|
+
}
|
|
6256
|
+
function resetRefVNodes(vm) {
|
|
6257
|
+
const { cmpTemplate } = vm;
|
|
6258
|
+
vm.refVNodes = !shared.isNull(cmpTemplate) && cmpTemplate.hasRefs ? shared.create(null) : null;
|
|
6259
|
+
}
|
|
5890
6260
|
|
|
5891
6261
|
/*
|
|
5892
6262
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -6061,6 +6431,12 @@ const NON_STANDARD_ARIA_PROPS = [
|
|
|
6061
6431
|
'ariaLabelledBy',
|
|
6062
6432
|
'ariaOwns',
|
|
6063
6433
|
];
|
|
6434
|
+
function isGlobalAriaPolyfillLoaded() {
|
|
6435
|
+
// Sniff for the legacy polyfill being loaded. The reason this works is because ariaActiveDescendant is a
|
|
6436
|
+
// non-standard ARIA property reflection that is only supported in our legacy polyfill. See
|
|
6437
|
+
// @lwc/aria-reflection/README.md for details.
|
|
6438
|
+
return !shared.isUndefined(shared.getOwnPropertyDescriptor(Element.prototype, 'ariaActiveDescendant'));
|
|
6439
|
+
}
|
|
6064
6440
|
function findVM(elm) {
|
|
6065
6441
|
// If it's a shadow DOM component, then it has a host
|
|
6066
6442
|
const { host } = elm.getRootNode();
|
|
@@ -6120,6 +6496,9 @@ function enableDetection() {
|
|
|
6120
6496
|
}
|
|
6121
6497
|
// @ts-ignore
|
|
6122
6498
|
const { get, set } = descriptor;
|
|
6499
|
+
// It's important for this defineProperty call to happen _after_ ARIA accessors are applied to the
|
|
6500
|
+
// BaseBridgeElement and LightningElement prototypes. Otherwise, we will log/report for access of non-standard
|
|
6501
|
+
// props on these prototypes, which we actually don't want. We only care about access on generic HTMLElements.
|
|
6123
6502
|
shared.defineProperty(prototype, prop, {
|
|
6124
6503
|
get() {
|
|
6125
6504
|
checkAndReportViolation(this, prop, false, undefined);
|
|
@@ -6135,16 +6514,14 @@ function enableDetection() {
|
|
|
6135
6514
|
}
|
|
6136
6515
|
}
|
|
6137
6516
|
// No point in running this code if we're not in a browser, or if the global polyfill is not loaded
|
|
6138
|
-
if (process.env.IS_BROWSER) {
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
onReportingEnabled(enableDetection);
|
|
6147
|
-
}
|
|
6517
|
+
if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
|
|
6518
|
+
// Always run detection in dev mode, so we can at least print to the console
|
|
6519
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6520
|
+
enableDetection();
|
|
6521
|
+
}
|
|
6522
|
+
else {
|
|
6523
|
+
// In prod mode, only enable detection if reporting is enabled
|
|
6524
|
+
onReportingEnabled(enableDetection);
|
|
6148
6525
|
}
|
|
6149
6526
|
}
|
|
6150
6527
|
|
|
@@ -6167,6 +6544,8 @@ function hydrateRoot(vm) {
|
|
|
6167
6544
|
function hydrateVM(vm) {
|
|
6168
6545
|
const children = renderComponent(vm);
|
|
6169
6546
|
vm.children = children;
|
|
6547
|
+
// reset the refs; they will be set during `hydrateChildren`
|
|
6548
|
+
resetRefVNodes(vm);
|
|
6170
6549
|
const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
|
|
6171
6550
|
hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
|
|
6172
6551
|
runRenderedCallback(vm);
|
|
@@ -6275,7 +6654,7 @@ function hydrateStaticElement(elm, vnode, renderer) {
|
|
|
6275
6654
|
return handleMismatch(elm, vnode, renderer);
|
|
6276
6655
|
}
|
|
6277
6656
|
vnode.elm = elm;
|
|
6278
|
-
|
|
6657
|
+
applyStaticParts(elm, vnode, renderer, true);
|
|
6279
6658
|
return elm;
|
|
6280
6659
|
}
|
|
6281
6660
|
function hydrateFragment(elm, vnode, renderer) {
|
|
@@ -6309,7 +6688,7 @@ function hydrateElement(elm, vnode, renderer) {
|
|
|
6309
6688
|
}
|
|
6310
6689
|
}
|
|
6311
6690
|
}
|
|
6312
|
-
|
|
6691
|
+
patchElementPropsAndAttrsAndRefs(vnode, renderer);
|
|
6313
6692
|
if (!isDomManual) {
|
|
6314
6693
|
const { getFirstChild } = renderer;
|
|
6315
6694
|
hydrateChildren(getFirstChild(elm), vnode.children, elm, owner);
|
|
@@ -6333,6 +6712,8 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
6333
6712
|
return handleMismatch(elm, vnode, renderer);
|
|
6334
6713
|
}
|
|
6335
6714
|
const { sel, mode, ctor, owner } = vnode;
|
|
6715
|
+
const { defineCustomElement, getTagName } = renderer;
|
|
6716
|
+
defineCustomElement(shared.StringToLowerCase.call(getTagName(elm)));
|
|
6336
6717
|
const vm = createVM(elm, ctor, renderer, {
|
|
6337
6718
|
mode,
|
|
6338
6719
|
owner,
|
|
@@ -6342,7 +6723,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
6342
6723
|
vnode.elm = elm;
|
|
6343
6724
|
vnode.vm = vm;
|
|
6344
6725
|
allocateChildren(vnode, vm);
|
|
6345
|
-
|
|
6726
|
+
patchElementPropsAndAttrsAndRefs(vnode, renderer);
|
|
6346
6727
|
// Insert hook section:
|
|
6347
6728
|
if (process.env.NODE_ENV !== 'production') {
|
|
6348
6729
|
shared.assert.isTrue(vm.state === 0 /* VMState.created */, `${vm} cannot be recycled.`);
|
|
@@ -6407,9 +6788,11 @@ function handleMismatch(node, vnode, renderer) {
|
|
|
6407
6788
|
removeNode(node, parentNode, renderer);
|
|
6408
6789
|
return vnode.elm;
|
|
6409
6790
|
}
|
|
6410
|
-
function
|
|
6791
|
+
function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
|
|
6411
6792
|
applyEventListeners(vnode, renderer);
|
|
6412
6793
|
patchProps(null, vnode, renderer);
|
|
6794
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
6795
|
+
applyRefs(vnode, vnode.owner);
|
|
6413
6796
|
}
|
|
6414
6797
|
function hasCorrectNodeType(vnode, node, nodeType, renderer) {
|
|
6415
6798
|
const { getProperty } = renderer;
|
|
@@ -6477,7 +6860,8 @@ function validateClassAttr(vnode, elm, renderer) {
|
|
|
6477
6860
|
const { data, owner } = vnode;
|
|
6478
6861
|
let { className, classMap } = data;
|
|
6479
6862
|
const { getProperty, getClassList, getAttribute } = renderer;
|
|
6480
|
-
|
|
6863
|
+
// we don't care about legacy for hydration. it's a new use case
|
|
6864
|
+
const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
6481
6865
|
const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
|
|
6482
6866
|
// Classnames for scoped CSS are added directly to the DOM during rendering,
|
|
6483
6867
|
// or to the VDOM on the server in the case of SSR. As such, these classnames
|
|
@@ -6792,7 +7176,7 @@ function trackMutations(tmpl) {
|
|
|
6792
7176
|
}
|
|
6793
7177
|
function addLegacyStylesheetTokensShim(tmpl) {
|
|
6794
7178
|
// When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
|
|
6795
|
-
// is accessing the old internal API (backwards compat). Details:
|
|
7179
|
+
// is accessing the old internal API (backwards compat). Details: W-14210169
|
|
6796
7180
|
shared.defineProperty(tmpl, 'stylesheetTokens', {
|
|
6797
7181
|
enumerable: true,
|
|
6798
7182
|
configurable: true,
|
|
@@ -6898,6 +7282,7 @@ exports.LightningElement = LightningElement;
|
|
|
6898
7282
|
exports.__unstable__ProfilerControl = profilerControl;
|
|
6899
7283
|
exports.__unstable__ReportingControl = reportingControl;
|
|
6900
7284
|
exports.api = api$1;
|
|
7285
|
+
exports.computeShadowAndRenderMode = computeShadowAndRenderMode;
|
|
6901
7286
|
exports.connectRootElement = connectRootElement;
|
|
6902
7287
|
exports.createContextProviderWithRegister = createContextProviderWithRegister;
|
|
6903
7288
|
exports.createVM = createVM;
|
|
@@ -6913,10 +7298,13 @@ exports.isComponentConstructor = isComponentConstructor;
|
|
|
6913
7298
|
exports.parseFragment = parseFragment;
|
|
6914
7299
|
exports.parseSVGFragment = parseSVGFragment;
|
|
6915
7300
|
exports.readonly = readonly;
|
|
6916
|
-
exports.register = register;
|
|
6917
7301
|
exports.registerComponent = registerComponent;
|
|
6918
7302
|
exports.registerDecorators = registerDecorators;
|
|
6919
7303
|
exports.registerTemplate = registerTemplate;
|
|
7304
|
+
exports.runFormAssociatedCallback = runFormAssociatedCallback;
|
|
7305
|
+
exports.runFormDisabledCallback = runFormDisabledCallback;
|
|
7306
|
+
exports.runFormResetCallback = runFormResetCallback;
|
|
7307
|
+
exports.runFormStateRestoreCallback = runFormStateRestoreCallback;
|
|
6920
7308
|
exports.sanitizeAttribute = sanitizeAttribute;
|
|
6921
7309
|
exports.setHooks = setHooks;
|
|
6922
7310
|
exports.swapComponent = swapComponent;
|
|
@@ -6925,5 +7313,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
6925
7313
|
exports.track = track;
|
|
6926
7314
|
exports.unwrap = unwrap;
|
|
6927
7315
|
exports.wire = wire;
|
|
6928
|
-
/** version: 4.0.0
|
|
7316
|
+
/** version: 4.0.0 */
|
|
6929
7317
|
//# sourceMappingURL=index.cjs.js.map
|