@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.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copyright (C) 2023 salesforce.com, inc.
|
|
3
3
|
*/
|
|
4
|
-
import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isArray as isArray$1, isFunction as isFunction$1, keys, hasOwnProperty as hasOwnProperty$1, globalThis as globalThis$1,
|
|
5
|
-
import { applyAriaReflection } from '@lwc/aria-reflection';
|
|
4
|
+
import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isArray as isArray$1, isFunction as isFunction$1, keys, hasOwnProperty as hasOwnProperty$1, globalThis as globalThis$1, AriaPropNameToAttrNameMap, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, forEach, getPropertyDescriptor, defineProperties, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, assign, isObject, freeze, KEY__SYNTHETIC_MODE, isString, assert, toString as toString$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, getOwnPropertyNames as getOwnPropertyNames$1, getOwnPropertyDescriptors, htmlPropertyToAttribute, ArraySlice, ArrayMap, KEY__SCOPED_CSS, kebabCaseToCamelCase, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, StringSlice, ArrayShift, ArrayUnshift, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, ArrayPop, isAPIFeatureEnabled, isNumber, StringReplace, LOWEST_API_VERSION, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, ID_REFERENCING_ATTRIBUTES_SET, KEY__SHADOW_TOKEN, ArrayFilter, StringSplit, arrayEvery, ArrayIncludes, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse } from '@lwc/shared';
|
|
6
5
|
export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
|
|
7
6
|
|
|
8
7
|
/*
|
|
@@ -388,20 +387,6 @@ function flattenStylesheets(stylesheets) {
|
|
|
388
387
|
}
|
|
389
388
|
return list;
|
|
390
389
|
}
|
|
391
|
-
// Set a ref (lwc:ref) on a VM, from a template API
|
|
392
|
-
function setRefVNode(vm, ref, vnode) {
|
|
393
|
-
if (process.env.NODE_ENV !== 'production' && isUndefined$1(vm.refVNodes)) {
|
|
394
|
-
throw new Error('refVNodes must be defined when setting a ref');
|
|
395
|
-
}
|
|
396
|
-
// If this method is called, then vm.refVNodes is set as the template has refs.
|
|
397
|
-
// If not, then something went wrong and we threw an error above.
|
|
398
|
-
const refVNodes = vm.refVNodes;
|
|
399
|
-
// In cases of conflict (two elements with the same ref), prefer, the last one,
|
|
400
|
-
// in depth-first traversal order.
|
|
401
|
-
if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
|
|
402
|
-
refVNodes[ref] = vnode;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
390
|
// Throw an error if we're running in prod mode. Ensures code is truly removed from prod mode.
|
|
406
391
|
function assertNotProd() {
|
|
407
392
|
/* istanbul ignore if */
|
|
@@ -429,6 +414,45 @@ var _a, _b;
|
|
|
429
414
|
const instrumentDef = (_a = globalThis$1.__lwc_instrument_cmp_def) !== null && _a !== void 0 ? _a : noop;
|
|
430
415
|
const instrumentInstance = (_b = globalThis$1.__lwc_instrument_cmp_instance) !== null && _b !== void 0 ? _b : noop;
|
|
431
416
|
|
|
417
|
+
/*
|
|
418
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
419
|
+
* All rights reserved.
|
|
420
|
+
* SPDX-License-Identifier: MIT
|
|
421
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
422
|
+
*/
|
|
423
|
+
// Apply ARIA string reflection behavior to a prototype.
|
|
424
|
+
// This is deliberately kept separate from @lwc/aria-reflection. @lwc/aria-reflection is a global polyfill that is
|
|
425
|
+
// needed for backwards compatibility in LEX, whereas `applyAriaReflection` is designed to only apply to our own
|
|
426
|
+
// LightningElement/BaseBridgeElement prototypes.
|
|
427
|
+
function applyAriaReflection(prototype) {
|
|
428
|
+
for (const propName of keys(AriaPropNameToAttrNameMap)) {
|
|
429
|
+
const attrName = AriaPropNameToAttrNameMap[propName];
|
|
430
|
+
if (isUndefined$1(getOwnPropertyDescriptor$1(prototype, propName))) {
|
|
431
|
+
// Note that we need to call this.{get,set,has,remove}Attribute rather than dereferencing
|
|
432
|
+
// from Element.prototype, because these methods are overridden in LightningElement.
|
|
433
|
+
defineProperty(prototype, propName, {
|
|
434
|
+
get() {
|
|
435
|
+
return this.getAttribute(attrName);
|
|
436
|
+
},
|
|
437
|
+
set(newValue) {
|
|
438
|
+
// TODO [#3284]: there is disagreement between browsers and the spec on how to treat undefined
|
|
439
|
+
// Our historical behavior is to only treat null as removing the attribute
|
|
440
|
+
// See also https://github.com/w3c/aria/issues/1858
|
|
441
|
+
if (isNull(newValue)) {
|
|
442
|
+
this.removeAttribute(attrName);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
this.setAttribute(attrName, newValue);
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
// configurable and enumerable to allow it to be overridden – this mimics Safari's/Chrome's behavior
|
|
449
|
+
configurable: true,
|
|
450
|
+
enumerable: true,
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
432
456
|
/*
|
|
433
457
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
434
458
|
* All rights reserved.
|
|
@@ -519,8 +543,8 @@ function lockDomMutation() {
|
|
|
519
543
|
assertNotProd(); // this method should never leak to prod
|
|
520
544
|
isDomMutationAllowed = false;
|
|
521
545
|
}
|
|
522
|
-
function
|
|
523
|
-
return
|
|
546
|
+
function logMissingPortalWarn(name, type) {
|
|
547
|
+
return logWarn(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
|
|
524
548
|
}
|
|
525
549
|
function patchElementWithRestrictions(elm, options) {
|
|
526
550
|
assertNotProd(); // this method should never leak to prod
|
|
@@ -545,14 +569,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
545
569
|
assign(descriptors, {
|
|
546
570
|
appendChild: generateDataDescriptor({
|
|
547
571
|
value(aChild) {
|
|
548
|
-
|
|
572
|
+
logMissingPortalWarn('appendChild', 'method');
|
|
549
573
|
return appendChild.call(this, aChild);
|
|
550
574
|
},
|
|
551
575
|
}),
|
|
552
576
|
insertBefore: generateDataDescriptor({
|
|
553
577
|
value(newNode, referenceNode) {
|
|
554
578
|
if (!isDomMutationAllowed) {
|
|
555
|
-
|
|
579
|
+
logMissingPortalWarn('insertBefore', 'method');
|
|
556
580
|
}
|
|
557
581
|
return insertBefore.call(this, newNode, referenceNode);
|
|
558
582
|
},
|
|
@@ -560,14 +584,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
560
584
|
removeChild: generateDataDescriptor({
|
|
561
585
|
value(aChild) {
|
|
562
586
|
if (!isDomMutationAllowed) {
|
|
563
|
-
|
|
587
|
+
logMissingPortalWarn('removeChild', 'method');
|
|
564
588
|
}
|
|
565
589
|
return removeChild.call(this, aChild);
|
|
566
590
|
},
|
|
567
591
|
}),
|
|
568
592
|
replaceChild: generateDataDescriptor({
|
|
569
593
|
value(newChild, oldChild) {
|
|
570
|
-
|
|
594
|
+
logMissingPortalWarn('replaceChild', 'method');
|
|
571
595
|
return replaceChild.call(this, newChild, oldChild);
|
|
572
596
|
},
|
|
573
597
|
}),
|
|
@@ -577,7 +601,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
577
601
|
},
|
|
578
602
|
set(value) {
|
|
579
603
|
if (!isDomMutationAllowed) {
|
|
580
|
-
|
|
604
|
+
logMissingPortalWarn('nodeValue', 'property');
|
|
581
605
|
}
|
|
582
606
|
originalNodeValueDescriptor.set.call(this, value);
|
|
583
607
|
},
|
|
@@ -587,7 +611,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
587
611
|
return originalTextContentDescriptor.get.call(this);
|
|
588
612
|
},
|
|
589
613
|
set(value) {
|
|
590
|
-
|
|
614
|
+
logMissingPortalWarn('textContent', 'property');
|
|
591
615
|
originalTextContentDescriptor.set.call(this, value);
|
|
592
616
|
},
|
|
593
617
|
}),
|
|
@@ -596,7 +620,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
596
620
|
return originalInnerHTMLDescriptor.get.call(this);
|
|
597
621
|
},
|
|
598
622
|
set(value) {
|
|
599
|
-
|
|
623
|
+
logMissingPortalWarn('innerHTML', 'property');
|
|
600
624
|
return originalInnerHTMLDescriptor.set.call(this, value);
|
|
601
625
|
},
|
|
602
626
|
}),
|
|
@@ -1454,6 +1478,79 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
|
|
|
1454
1478
|
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.`);
|
|
1455
1479
|
}
|
|
1456
1480
|
}
|
|
1481
|
+
// List of properties on ElementInternals that are formAssociated can be found in the spec:
|
|
1482
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements
|
|
1483
|
+
const formAssociatedProps = new Set([
|
|
1484
|
+
'setFormValue',
|
|
1485
|
+
'form',
|
|
1486
|
+
'setValidity',
|
|
1487
|
+
'willValidate',
|
|
1488
|
+
'validity',
|
|
1489
|
+
'validationMessage',
|
|
1490
|
+
'checkValidity',
|
|
1491
|
+
'reportValidity',
|
|
1492
|
+
'labels',
|
|
1493
|
+
]);
|
|
1494
|
+
// Verify that access to a form-associated property of the ElementInternals proxy has formAssociated set in the LWC.
|
|
1495
|
+
function verifyPropForFormAssociation(propertyKey, isFormAssociated) {
|
|
1496
|
+
if (isString(propertyKey) && formAssociatedProps.has(propertyKey) && !isFormAssociated) {
|
|
1497
|
+
//Note this error message mirrors Chrome and Firefox error messages, in Safari the error is slightly different.
|
|
1498
|
+
throw new DOMException(`Failed to execute '${propertyKey}' on 'ElementInternals': The target element is not a form-associated custom element.`);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
const elementInternalsAccessorAllowList = new Set(['shadowRoot', 'role', ...formAssociatedProps]);
|
|
1502
|
+
// Prevent access to properties not defined in the HTML spec in case browsers decide to
|
|
1503
|
+
// provide new APIs that provide access to form associated properties.
|
|
1504
|
+
// This can be removed along with UpgradeableConstructor.
|
|
1505
|
+
function isAllowedElementInternalAccessor(propertyKey) {
|
|
1506
|
+
let isAllowedAccessor = false;
|
|
1507
|
+
// As of this writing all ElementInternal property keys as described in the spec are implemented with strings
|
|
1508
|
+
// in Chrome, Firefox, and Safari
|
|
1509
|
+
if (isString(propertyKey)) {
|
|
1510
|
+
// Allow list is based on HTML spec:
|
|
1511
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#the-elementinternals-interface
|
|
1512
|
+
isAllowedAccessor =
|
|
1513
|
+
elementInternalsAccessorAllowList.has(propertyKey) || /^aria/.test(propertyKey);
|
|
1514
|
+
if (!isAllowedAccessor && process.env.NODE_ENV !== 'production') {
|
|
1515
|
+
logWarn('Only properties defined in the ElementInternals HTML spec are available.');
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
return isAllowedAccessor;
|
|
1519
|
+
}
|
|
1520
|
+
// Wrap all ElementInternal objects in a proxy to prevent form association when `formAssociated` is not set on an LWC.
|
|
1521
|
+
// This is needed because the 1UpgradeableConstructor1 always sets `formAssociated=true`, which means all
|
|
1522
|
+
// ElementInternal objects will have form-associated properties set when an LWC is placed in a form.
|
|
1523
|
+
// We are doing this to guard against customers taking a dependency on form elements being associated to ElementInternals
|
|
1524
|
+
// when 'formAssociated' has not been set on the LWC.
|
|
1525
|
+
function createElementInternalsProxy(elementInternals, isFormAssociated) {
|
|
1526
|
+
const elementInternalsProxy = new Proxy(elementInternals, {
|
|
1527
|
+
set(target, propertyKey, newValue) {
|
|
1528
|
+
if (isAllowedElementInternalAccessor(propertyKey)) {
|
|
1529
|
+
// Verify that formAssociated is set for form associated properties
|
|
1530
|
+
verifyPropForFormAssociation(propertyKey, isFormAssociated);
|
|
1531
|
+
return Reflect.set(target, propertyKey, newValue);
|
|
1532
|
+
}
|
|
1533
|
+
// As of this writing ElementInternals do not have non-string properties that can be set.
|
|
1534
|
+
return false;
|
|
1535
|
+
},
|
|
1536
|
+
get(target, propertyKey) {
|
|
1537
|
+
if (
|
|
1538
|
+
// Pass through Object.prototype methods such as toString()
|
|
1539
|
+
hasOwnProperty$1.call(Object.prototype, propertyKey) ||
|
|
1540
|
+
// As of this writing, ElementInternals only uses Symbol.toStringTag which is called
|
|
1541
|
+
// on Object.hasOwnProperty invocations
|
|
1542
|
+
Symbol.for('Symbol.toStringTag') === propertyKey ||
|
|
1543
|
+
// ElementInternals allow listed properties
|
|
1544
|
+
isAllowedElementInternalAccessor(propertyKey)) {
|
|
1545
|
+
// Verify that formAssociated is set for form associated properties
|
|
1546
|
+
verifyPropForFormAssociation(propertyKey, isFormAssociated);
|
|
1547
|
+
const propertyValue = Reflect.get(target, propertyKey);
|
|
1548
|
+
return isFunction$1(propertyValue) ? propertyValue.bind(target) : propertyValue;
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
});
|
|
1552
|
+
return elementInternalsProxy;
|
|
1553
|
+
}
|
|
1457
1554
|
// @ts-ignore
|
|
1458
1555
|
LightningElement.prototype = {
|
|
1459
1556
|
constructor: LightningElement,
|
|
@@ -1545,6 +1642,16 @@ LightningElement.prototype = {
|
|
|
1545
1642
|
}
|
|
1546
1643
|
return getBoundingClientRect(elm);
|
|
1547
1644
|
},
|
|
1645
|
+
attachInternals() {
|
|
1646
|
+
const vm = getAssociatedVM(this);
|
|
1647
|
+
const { elm, def: { formAssociated }, renderer: { attachInternals }, } = vm;
|
|
1648
|
+
if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
1649
|
+
throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
|
|
1650
|
+
}
|
|
1651
|
+
const internals = attachInternals(elm);
|
|
1652
|
+
// #TODO[2970]: remove proxy once `UpgradeableConstructor` has been removed
|
|
1653
|
+
return createElementInternalsProxy(internals, Boolean(formAssociated));
|
|
1654
|
+
},
|
|
1548
1655
|
get isConnected() {
|
|
1549
1656
|
const vm = getAssociatedVM(this);
|
|
1550
1657
|
const { elm, renderer: { isConnected }, } = vm;
|
|
@@ -2545,7 +2652,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
|
|
|
2545
2652
|
this[propName] = newValue;
|
|
2546
2653
|
};
|
|
2547
2654
|
}
|
|
2548
|
-
function
|
|
2655
|
+
function createAccessorThatWarns(propName) {
|
|
2656
|
+
let prop;
|
|
2657
|
+
return {
|
|
2658
|
+
get() {
|
|
2659
|
+
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.`);
|
|
2660
|
+
return prop;
|
|
2661
|
+
},
|
|
2662
|
+
set(value) {
|
|
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
|
+
prop = value;
|
|
2665
|
+
},
|
|
2666
|
+
enumerable: true,
|
|
2667
|
+
configurable: true,
|
|
2668
|
+
};
|
|
2669
|
+
}
|
|
2670
|
+
function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto, hasCustomSuperClass) {
|
|
2549
2671
|
const HTMLBridgeElement = class extends SuperClass {
|
|
2550
2672
|
};
|
|
2551
2673
|
// generating the hash table for attributes to avoid duplicate fields and facilitate validation
|
|
@@ -2554,9 +2676,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2554
2676
|
const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
|
|
2555
2677
|
const { observedAttributes: superObservedAttributes = [] } = SuperClass;
|
|
2556
2678
|
const descriptors = create(null);
|
|
2679
|
+
// present a hint message so that developers are aware that they have not decorated property with @api
|
|
2680
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2681
|
+
// TODO [#3761]: enable for components that don't extend from LightningElement
|
|
2682
|
+
if (!isUndefined$1(proto) && !isNull(proto) && !hasCustomSuperClass) {
|
|
2683
|
+
const nonPublicPropertiesToWarnOn = new Set([
|
|
2684
|
+
// getters, setters, and methods
|
|
2685
|
+
...keys(getOwnPropertyDescriptors(proto)),
|
|
2686
|
+
// class properties
|
|
2687
|
+
...observedFields,
|
|
2688
|
+
]
|
|
2689
|
+
// we don't want to override HTMLElement props because these are meaningful in other ways,
|
|
2690
|
+
// and can break tooling that expects it to be iterable or defined, e.g. Jest:
|
|
2691
|
+
// https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
|
|
2692
|
+
// It also doesn't make sense to override e.g. "constructor".
|
|
2693
|
+
.filter((propName) => !(propName in HTMLElementPrototype)));
|
|
2694
|
+
for (const propName of nonPublicPropertiesToWarnOn) {
|
|
2695
|
+
if (ArrayIndexOf.call(publicProperties, propName) === -1) {
|
|
2696
|
+
descriptors[propName] = createAccessorThatWarns(propName);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2557
2701
|
// expose getters and setters for each public props on the new Element Bridge
|
|
2558
|
-
for (let i = 0, len =
|
|
2559
|
-
const propName =
|
|
2702
|
+
for (let i = 0, len = publicProperties.length; i < len; i += 1) {
|
|
2703
|
+
const propName = publicProperties[i];
|
|
2560
2704
|
attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
|
|
2561
2705
|
descriptors[propName] = {
|
|
2562
2706
|
get: createGetter(propName),
|
|
@@ -2581,6 +2725,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2581
2725
|
descriptors.attributeChangedCallback = {
|
|
2582
2726
|
value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
|
|
2583
2727
|
};
|
|
2728
|
+
// To avoid leaking private component details, accessing internals from outside a component is not allowed.
|
|
2729
|
+
descriptors.attachInternals = {
|
|
2730
|
+
set() {
|
|
2731
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2732
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2733
|
+
}
|
|
2734
|
+
},
|
|
2735
|
+
get() {
|
|
2736
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2737
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2738
|
+
}
|
|
2739
|
+
},
|
|
2740
|
+
};
|
|
2741
|
+
descriptors.formAssociated = {
|
|
2742
|
+
set() {
|
|
2743
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2744
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2745
|
+
}
|
|
2746
|
+
},
|
|
2747
|
+
get() {
|
|
2748
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2749
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2750
|
+
}
|
|
2751
|
+
},
|
|
2752
|
+
};
|
|
2584
2753
|
// Specify attributes for which we want to reflect changes back to their corresponding
|
|
2585
2754
|
// properties via attributeChangedCallback.
|
|
2586
2755
|
defineProperty(HTMLBridgeElement, 'observedAttributes', {
|
|
@@ -2591,7 +2760,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2591
2760
|
defineProperties(HTMLBridgeElement.prototype, descriptors);
|
|
2592
2761
|
return HTMLBridgeElement;
|
|
2593
2762
|
}
|
|
2594
|
-
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), []);
|
|
2763
|
+
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), [], [], null, false);
|
|
2595
2764
|
if (process.env.IS_BROWSER) {
|
|
2596
2765
|
// This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
|
|
2597
2766
|
// so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
|
|
@@ -2889,7 +3058,7 @@ function getCtorProto(Ctor) {
|
|
|
2889
3058
|
return proto;
|
|
2890
3059
|
}
|
|
2891
3060
|
function createComponentDef(Ctor) {
|
|
2892
|
-
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode } = Ctor;
|
|
3061
|
+
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
|
|
2893
3062
|
if (process.env.NODE_ENV !== 'production') {
|
|
2894
3063
|
const ctorName = Ctor.name;
|
|
2895
3064
|
// Removing the following assert until https://bugs.webkit.org/show_bug.cgi?id=190140 is fixed.
|
|
@@ -2901,7 +3070,8 @@ function createComponentDef(Ctor) {
|
|
|
2901
3070
|
}
|
|
2902
3071
|
if (!isUndefined$1(ctorShadowSupportMode) &&
|
|
2903
3072
|
ctorShadowSupportMode !== "any" /* ShadowSupportMode.Any */ &&
|
|
2904
|
-
ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */
|
|
3073
|
+
ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */ &&
|
|
3074
|
+
ctorShadowSupportMode !== "native" /* ShadowSupportMode.Native */) {
|
|
2905
3075
|
logError(`Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
|
|
2906
3076
|
}
|
|
2907
3077
|
if (!isUndefined$1(ctorRenderMode) &&
|
|
@@ -2913,10 +3083,11 @@ function createComponentDef(Ctor) {
|
|
|
2913
3083
|
const decoratorsMeta = getDecoratorsMeta(Ctor);
|
|
2914
3084
|
const { apiFields, apiFieldsConfig, apiMethods, wiredFields, wiredMethods, observedFields } = decoratorsMeta;
|
|
2915
3085
|
const proto = Ctor.prototype;
|
|
2916
|
-
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
|
|
3086
|
+
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, formAssociatedCallback, formResetCallback, formDisabledCallback, formStateRestoreCallback, render, } = proto;
|
|
2917
3087
|
const superProto = getCtorProto(Ctor);
|
|
2918
|
-
const
|
|
2919
|
-
const
|
|
3088
|
+
const hasCustomSuperClass = superProto !== LightningElement;
|
|
3089
|
+
const superDef = hasCustomSuperClass ? getComponentInternalDef(superProto) : lightingElementDef;
|
|
3090
|
+
const bridge = HTMLBridgeElementFactory(superDef.bridge, keys(apiFields), keys(apiMethods), keys(observedFields), proto, hasCustomSuperClass);
|
|
2920
3091
|
const props = assign(create(null), superDef.props, apiFields);
|
|
2921
3092
|
const propsConfig = assign(create(null), superDef.propsConfig, apiFieldsConfig);
|
|
2922
3093
|
const methods = assign(create(null), superDef.methods, apiMethods);
|
|
@@ -2925,6 +3096,10 @@ function createComponentDef(Ctor) {
|
|
|
2925
3096
|
disconnectedCallback = disconnectedCallback || superDef.disconnectedCallback;
|
|
2926
3097
|
renderedCallback = renderedCallback || superDef.renderedCallback;
|
|
2927
3098
|
errorCallback = errorCallback || superDef.errorCallback;
|
|
3099
|
+
formAssociatedCallback = formAssociatedCallback || superDef.formAssociatedCallback;
|
|
3100
|
+
formResetCallback = formResetCallback || superDef.formResetCallback;
|
|
3101
|
+
formDisabledCallback = formDisabledCallback || superDef.formDisabledCallback;
|
|
3102
|
+
formStateRestoreCallback = formStateRestoreCallback || superDef.formStateRestoreCallback;
|
|
2928
3103
|
render = render || superDef.render;
|
|
2929
3104
|
let shadowSupportMode = superDef.shadowSupportMode;
|
|
2930
3105
|
if (!isUndefined$1(ctorShadowSupportMode)) {
|
|
@@ -2934,6 +3109,10 @@ function createComponentDef(Ctor) {
|
|
|
2934
3109
|
if (!isUndefined$1(ctorRenderMode)) {
|
|
2935
3110
|
renderMode = ctorRenderMode === 'light' ? 0 /* RenderMode.Light */ : 1 /* RenderMode.Shadow */;
|
|
2936
3111
|
}
|
|
3112
|
+
let formAssociated = superDef.formAssociated;
|
|
3113
|
+
if (!isUndefined$1(ctorFormAssociated)) {
|
|
3114
|
+
formAssociated = ctorFormAssociated;
|
|
3115
|
+
}
|
|
2937
3116
|
const template = getComponentRegisteredTemplate(Ctor) || superDef.template;
|
|
2938
3117
|
const name = Ctor.name || superDef.name;
|
|
2939
3118
|
// installing observed fields into the prototype.
|
|
@@ -2949,10 +3128,15 @@ function createComponentDef(Ctor) {
|
|
|
2949
3128
|
template,
|
|
2950
3129
|
renderMode,
|
|
2951
3130
|
shadowSupportMode,
|
|
3131
|
+
formAssociated,
|
|
2952
3132
|
connectedCallback,
|
|
2953
3133
|
disconnectedCallback,
|
|
2954
|
-
renderedCallback,
|
|
2955
3134
|
errorCallback,
|
|
3135
|
+
formAssociatedCallback,
|
|
3136
|
+
formDisabledCallback,
|
|
3137
|
+
formResetCallback,
|
|
3138
|
+
formStateRestoreCallback,
|
|
3139
|
+
renderedCallback,
|
|
2956
3140
|
render,
|
|
2957
3141
|
};
|
|
2958
3142
|
// This is a no-op unless Lightning DevTools are enabled.
|
|
@@ -3029,6 +3213,7 @@ const lightingElementDef = {
|
|
|
3029
3213
|
methods: EmptyObject,
|
|
3030
3214
|
renderMode: 1 /* RenderMode.Shadow */,
|
|
3031
3215
|
shadowSupportMode: "reset" /* ShadowSupportMode.Default */,
|
|
3216
|
+
formAssociated: undefined,
|
|
3032
3217
|
wire: EmptyObject,
|
|
3033
3218
|
bridge: BaseBridgeElement,
|
|
3034
3219
|
template: defaultEmptyTemplate,
|
|
@@ -3085,9 +3270,11 @@ function createInlineStyleVNode(content) {
|
|
|
3085
3270
|
},
|
|
3086
3271
|
}, [api.t(content)]);
|
|
3087
3272
|
}
|
|
3088
|
-
|
|
3273
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3274
|
+
function updateStylesheetToken(vm, template, legacy) {
|
|
3089
3275
|
const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
|
|
3090
|
-
const { stylesheets: newStylesheets
|
|
3276
|
+
const { stylesheets: newStylesheets } = template;
|
|
3277
|
+
const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
|
|
3091
3278
|
const { stylesheets: newVmStylesheets } = vm;
|
|
3092
3279
|
const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
3093
3280
|
const { hasScopedStyles } = context;
|
|
@@ -3095,7 +3282,19 @@ function updateStylesheetToken(vm, template) {
|
|
|
3095
3282
|
let newHasTokenInClass;
|
|
3096
3283
|
let newHasTokenInAttribute;
|
|
3097
3284
|
// Reset the styling token applied to the host element.
|
|
3098
|
-
|
|
3285
|
+
let oldToken;
|
|
3286
|
+
let oldHasTokenInClass;
|
|
3287
|
+
let oldHasTokenInAttribute;
|
|
3288
|
+
if (legacy) {
|
|
3289
|
+
oldToken = context.legacyStylesheetToken;
|
|
3290
|
+
oldHasTokenInClass = context.hasLegacyTokenInClass;
|
|
3291
|
+
oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
|
|
3292
|
+
}
|
|
3293
|
+
else {
|
|
3294
|
+
oldToken = context.stylesheetToken;
|
|
3295
|
+
oldHasTokenInClass = context.hasTokenInClass;
|
|
3296
|
+
oldHasTokenInAttribute = context.hasTokenInAttribute;
|
|
3297
|
+
}
|
|
3099
3298
|
if (!isUndefined$1(oldToken)) {
|
|
3100
3299
|
if (oldHasTokenInClass) {
|
|
3101
3300
|
getClassList(elm).remove(makeHostToken(oldToken));
|
|
@@ -3123,9 +3322,16 @@ function updateStylesheetToken(vm, template) {
|
|
|
3123
3322
|
}
|
|
3124
3323
|
}
|
|
3125
3324
|
// Update the styling tokens present on the context object.
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3325
|
+
if (legacy) {
|
|
3326
|
+
context.legacyStylesheetToken = newToken;
|
|
3327
|
+
context.hasLegacyTokenInClass = newHasTokenInClass;
|
|
3328
|
+
context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
|
|
3329
|
+
}
|
|
3330
|
+
else {
|
|
3331
|
+
context.stylesheetToken = newToken;
|
|
3332
|
+
context.hasTokenInClass = newHasTokenInClass;
|
|
3333
|
+
context.hasTokenInAttribute = newHasTokenInAttribute;
|
|
3334
|
+
}
|
|
3129
3335
|
}
|
|
3130
3336
|
function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
|
|
3131
3337
|
const content = [];
|
|
@@ -3213,9 +3419,12 @@ function getNearestShadowComponent(vm) {
|
|
|
3213
3419
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
3214
3420
|
* it returns null.
|
|
3215
3421
|
*/
|
|
3216
|
-
|
|
3422
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3423
|
+
function getScopeTokenClass(owner, legacy) {
|
|
3217
3424
|
const { cmpTemplate, context } = owner;
|
|
3218
|
-
return (context.hasScopedStyles &&
|
|
3425
|
+
return ((context.hasScopedStyles &&
|
|
3426
|
+
(legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
|
|
3427
|
+
null);
|
|
3219
3428
|
}
|
|
3220
3429
|
/**
|
|
3221
3430
|
* This function returns the host style token for a custom element if it
|
|
@@ -3349,28 +3558,20 @@ function isLiveBindingProp(sel, key) {
|
|
|
3349
3558
|
return sel === 'input' && (key === 'value' || key === 'checked');
|
|
3350
3559
|
}
|
|
3351
3560
|
function patchProps(oldVnode, vnode, renderer) {
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
if (isUndefined$1(props) && isUndefined$1(spread)) {
|
|
3561
|
+
const { props } = vnode.data;
|
|
3562
|
+
if (isUndefined$1(props)) {
|
|
3355
3563
|
return;
|
|
3356
3564
|
}
|
|
3357
3565
|
let oldProps;
|
|
3358
3566
|
if (!isNull(oldVnode)) {
|
|
3359
3567
|
oldProps = oldVnode.data.props;
|
|
3360
|
-
const oldSpread = oldVnode.data.spread;
|
|
3361
3568
|
// Props may be the same due to the static content optimization, so we can skip diffing
|
|
3362
|
-
if (oldProps === props
|
|
3569
|
+
if (oldProps === props) {
|
|
3363
3570
|
return;
|
|
3364
3571
|
}
|
|
3365
3572
|
if (isUndefined$1(oldProps)) {
|
|
3366
3573
|
oldProps = EmptyObject;
|
|
3367
3574
|
}
|
|
3368
|
-
if (!isUndefined$1(oldSpread)) {
|
|
3369
|
-
oldProps = assign({}, oldProps, oldSpread);
|
|
3370
|
-
}
|
|
3371
|
-
}
|
|
3372
|
-
if (!isUndefined$1(spread)) {
|
|
3373
|
-
props = assign({}, props, spread);
|
|
3374
3575
|
}
|
|
3375
3576
|
const isFirstPatch = isNull(oldVnode);
|
|
3376
3577
|
const { elm, sel } = vnode;
|
|
@@ -3544,6 +3745,113 @@ function applyStaticStyleAttribute(vnode, renderer) {
|
|
|
3544
3745
|
}
|
|
3545
3746
|
}
|
|
3546
3747
|
|
|
3748
|
+
/*
|
|
3749
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3750
|
+
* All rights reserved.
|
|
3751
|
+
* SPDX-License-Identifier: MIT
|
|
3752
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3753
|
+
*/
|
|
3754
|
+
// Set a ref (lwc:ref) on a VM, from a template API
|
|
3755
|
+
function applyRefs(vnode, owner) {
|
|
3756
|
+
const { data } = vnode;
|
|
3757
|
+
const { ref } = data;
|
|
3758
|
+
if (isUndefined$1(ref)) {
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
if (process.env.NODE_ENV !== 'production' && isUndefined$1(owner.refVNodes)) {
|
|
3762
|
+
throw new Error('refVNodes must be defined when setting a ref');
|
|
3763
|
+
}
|
|
3764
|
+
// If this method is called, then vm.refVNodes is set as the template has refs.
|
|
3765
|
+
// If not, then something went wrong and we threw an error above.
|
|
3766
|
+
const refVNodes = owner.refVNodes;
|
|
3767
|
+
// In cases of conflict (two elements with the same ref), prefer the last one,
|
|
3768
|
+
// in depth-first traversal order. This happens automatically due to how we render
|
|
3769
|
+
refVNodes[ref] = vnode;
|
|
3770
|
+
}
|
|
3771
|
+
|
|
3772
|
+
/*
|
|
3773
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3774
|
+
* All rights reserved.
|
|
3775
|
+
* SPDX-License-Identifier: MIT
|
|
3776
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3777
|
+
*/
|
|
3778
|
+
function traverseAndSetElements(root, parts, renderer) {
|
|
3779
|
+
const numParts = parts.length;
|
|
3780
|
+
// Optimization given that, in most cases, there will be one part, and it's just the root
|
|
3781
|
+
if (numParts === 1) {
|
|
3782
|
+
const firstPart = parts[0];
|
|
3783
|
+
if (firstPart.partId === 0) {
|
|
3784
|
+
// 0 means the root node
|
|
3785
|
+
firstPart.elm = root;
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3789
|
+
const partIdsToParts = new Map();
|
|
3790
|
+
for (const staticPart of parts) {
|
|
3791
|
+
partIdsToParts.set(staticPart.partId, staticPart);
|
|
3792
|
+
}
|
|
3793
|
+
let numFoundParts = 0;
|
|
3794
|
+
const { previousSibling, getLastChild } = renderer;
|
|
3795
|
+
const stack = [root];
|
|
3796
|
+
let partId = -1;
|
|
3797
|
+
// Depth-first traversal. We assign a partId to each element, which is an integer based on traversal order.
|
|
3798
|
+
while (stack.length > 0) {
|
|
3799
|
+
const elm = ArrayShift.call(stack);
|
|
3800
|
+
partId++;
|
|
3801
|
+
const part = partIdsToParts.get(partId);
|
|
3802
|
+
if (!isUndefined$1(part)) {
|
|
3803
|
+
part.elm = elm;
|
|
3804
|
+
if (++numFoundParts === numParts) {
|
|
3805
|
+
return; // perf optimization - stop traversing once we've found everything we need
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
// For depth-first traversal, prepend to the stack in reverse order
|
|
3809
|
+
// Note that we traverse using `*Child`/`*Sibling` rather than `children` because the browser uses a linked
|
|
3810
|
+
// list under the hood to represent the DOM tree, so it's faster to do this than to create an underlying array
|
|
3811
|
+
// by calling `children`.
|
|
3812
|
+
let child = getLastChild(elm);
|
|
3813
|
+
while (!isNull(child)) {
|
|
3814
|
+
ArrayUnshift.call(stack, child);
|
|
3815
|
+
child = previousSibling(child);
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3819
|
+
assert.isTrue(numFoundParts === numParts, `Should have found all parts by now. Found ${numFoundParts}, needed ${numParts}.`);
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Given an array of static parts, do all the mounting required for these parts.
|
|
3824
|
+
*
|
|
3825
|
+
* @param root - the root element
|
|
3826
|
+
* @param vnode - the parent VStatic
|
|
3827
|
+
* @param renderer - the renderer to use
|
|
3828
|
+
* @param mount - true this is a first (mount) render as opposed to a subsequent (patch) render
|
|
3829
|
+
*/
|
|
3830
|
+
function applyStaticParts(root, vnode, renderer, mount) {
|
|
3831
|
+
// On the server, we don't support ref (because it relies on renderedCallback), nor do we
|
|
3832
|
+
// support event listeners (no interactivity), so traversing parts makes no sense
|
|
3833
|
+
if (!process.env.IS_BROWSER) {
|
|
3834
|
+
return;
|
|
3835
|
+
}
|
|
3836
|
+
const { parts, owner } = vnode;
|
|
3837
|
+
if (isUndefined$1(parts)) {
|
|
3838
|
+
return;
|
|
3839
|
+
}
|
|
3840
|
+
// This adds `part.elm` to each `part`. We have to do this on every mount/patch because the `parts`
|
|
3841
|
+
// array is recreated from scratch every time, so each `part.elm` is now undefined.
|
|
3842
|
+
// TODO [#3800]: avoid calling traverseAndSetElements on every re-render
|
|
3843
|
+
traverseAndSetElements(root, parts, renderer);
|
|
3844
|
+
// Currently only event listeners and refs are supported for static vnodes
|
|
3845
|
+
for (const part of parts) {
|
|
3846
|
+
if (mount) {
|
|
3847
|
+
// Event listeners only need to be applied once when mounting
|
|
3848
|
+
applyEventListeners(part, renderer);
|
|
3849
|
+
}
|
|
3850
|
+
// Refs must be updated after every render due to refVNodes getting reset before every render
|
|
3851
|
+
applyRefs(part, owner);
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
|
|
3547
3855
|
/*
|
|
3548
3856
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
3549
3857
|
* All rights reserved.
|
|
@@ -3586,7 +3894,7 @@ function patch(n1, n2, parent, renderer) {
|
|
|
3586
3894
|
patchComment(n1, n2, renderer);
|
|
3587
3895
|
break;
|
|
3588
3896
|
case 4 /* VNodeType.Static */:
|
|
3589
|
-
n2
|
|
3897
|
+
patchStatic(n1, n2, renderer);
|
|
3590
3898
|
break;
|
|
3591
3899
|
case 5 /* VNodeType.Fragment */:
|
|
3592
3900
|
patchFragment(n1, n2, parent, renderer);
|
|
@@ -3680,13 +3988,18 @@ function mountElement(vnode, parent, anchor, renderer) {
|
|
|
3680
3988
|
applyStyleScoping(elm, owner, renderer);
|
|
3681
3989
|
applyDomManual(elm, vnode);
|
|
3682
3990
|
applyElementRestrictions(elm, vnode);
|
|
3683
|
-
|
|
3991
|
+
patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
|
|
3684
3992
|
insertNode(elm, parent, anchor, renderer);
|
|
3685
3993
|
mountVNodes(vnode.children, elm, renderer, null);
|
|
3686
3994
|
}
|
|
3995
|
+
function patchStatic(n1, n2, renderer) {
|
|
3996
|
+
const elm = (n2.elm = n1.elm);
|
|
3997
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
3998
|
+
applyStaticParts(elm, n2, renderer, false);
|
|
3999
|
+
}
|
|
3687
4000
|
function patchElement(n1, n2, renderer) {
|
|
3688
4001
|
const elm = (n2.elm = n1.elm);
|
|
3689
|
-
|
|
4002
|
+
patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
|
|
3690
4003
|
patchChildren(n1.children, n2.children, elm, renderer);
|
|
3691
4004
|
}
|
|
3692
4005
|
function mountStatic(vnode, parent, anchor, renderer) {
|
|
@@ -3703,8 +4016,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
|
|
|
3703
4016
|
}
|
|
3704
4017
|
}
|
|
3705
4018
|
insertNode(elm, parent, anchor, renderer);
|
|
3706
|
-
|
|
3707
|
-
applyEventListeners(vnode, renderer);
|
|
4019
|
+
applyStaticParts(elm, vnode, renderer, true);
|
|
3708
4020
|
}
|
|
3709
4021
|
function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
3710
4022
|
const { sel, owner } = vnode;
|
|
@@ -3720,22 +4032,38 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3720
4032
|
// the custom element from the registry is expecting an upgrade callback
|
|
3721
4033
|
vm = createViewModelHook(elm, vnode, renderer);
|
|
3722
4034
|
};
|
|
3723
|
-
|
|
3724
|
-
|
|
4035
|
+
let connectedCallback;
|
|
4036
|
+
let disconnectedCallback;
|
|
4037
|
+
let formAssociatedCallback;
|
|
4038
|
+
let formDisabledCallback;
|
|
4039
|
+
let formResetCallback;
|
|
4040
|
+
let formStateRestoreCallback;
|
|
4041
|
+
if (lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
4042
|
+
connectedCallback = (elm) => {
|
|
3725
4043
|
connectRootElement(elm);
|
|
3726
|
-
}
|
|
3727
|
-
|
|
3728
|
-
const disconnectedCallback = (elm) => {
|
|
3729
|
-
if (shouldUseNativeCustomElementLifecycle(vm)) {
|
|
4044
|
+
};
|
|
4045
|
+
disconnectedCallback = (elm) => {
|
|
3730
4046
|
disconnectRootElement(elm);
|
|
3731
|
-
}
|
|
3732
|
-
|
|
4047
|
+
};
|
|
4048
|
+
formAssociatedCallback = (elm) => {
|
|
4049
|
+
runFormAssociatedCallback(elm);
|
|
4050
|
+
};
|
|
4051
|
+
formDisabledCallback = (elm) => {
|
|
4052
|
+
runFormDisabledCallback(elm);
|
|
4053
|
+
};
|
|
4054
|
+
formResetCallback = (elm) => {
|
|
4055
|
+
runFormResetCallback(elm);
|
|
4056
|
+
};
|
|
4057
|
+
formStateRestoreCallback = (elm) => {
|
|
4058
|
+
runFormStateRestoreCallback(elm);
|
|
4059
|
+
};
|
|
4060
|
+
}
|
|
3733
4061
|
// Should never get a tag with upper case letter at this point; the compiler
|
|
3734
4062
|
// should produce only tags with lowercase letters. However, the Java
|
|
3735
4063
|
// compiler may generate tagnames with uppercase letters so - for backwards
|
|
3736
4064
|
// compatibility, we lower case the tagname here.
|
|
3737
4065
|
const normalizedTagname = sel.toLowerCase();
|
|
3738
|
-
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback);
|
|
4066
|
+
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback, formAssociatedCallback, formDisabledCallback, formResetCallback, formStateRestoreCallback);
|
|
3739
4067
|
vnode.elm = elm;
|
|
3740
4068
|
vnode.vm = vm;
|
|
3741
4069
|
linkNodeToShadow(elm, owner, renderer);
|
|
@@ -3743,11 +4071,11 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3743
4071
|
if (vm) {
|
|
3744
4072
|
allocateChildren(vnode, vm);
|
|
3745
4073
|
}
|
|
3746
|
-
|
|
4074
|
+
patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
|
|
3747
4075
|
insertNode(elm, parent, anchor, renderer);
|
|
3748
4076
|
if (vm) {
|
|
3749
4077
|
if (process.env.IS_BROWSER) {
|
|
3750
|
-
if (!
|
|
4078
|
+
if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
3751
4079
|
if (process.env.NODE_ENV !== 'production') {
|
|
3752
4080
|
// With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
|
|
3753
4081
|
// noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
|
|
@@ -3780,7 +4108,7 @@ function patchCustomElement(n1, n2, parent, renderer) {
|
|
|
3780
4108
|
// Otherwise patch the existing component with new props/attrs/etc.
|
|
3781
4109
|
const elm = (n2.elm = n1.elm);
|
|
3782
4110
|
const vm = (n2.vm = n1.vm);
|
|
3783
|
-
|
|
4111
|
+
patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
|
|
3784
4112
|
if (!isUndefined$1(vm)) {
|
|
3785
4113
|
// in fallback mode, the allocation will always set children to
|
|
3786
4114
|
// empty and delegate the real allocation to the slot elements
|
|
@@ -3927,7 +4255,7 @@ function removeNode(node, parent, renderer) {
|
|
|
3927
4255
|
lockDomMutation();
|
|
3928
4256
|
}
|
|
3929
4257
|
}
|
|
3930
|
-
function
|
|
4258
|
+
function patchElementPropsAndAttrsAndRefs$1(oldVnode, vnode, renderer) {
|
|
3931
4259
|
if (isNull(oldVnode)) {
|
|
3932
4260
|
applyEventListeners(vnode, renderer);
|
|
3933
4261
|
applyStaticClassAttribute(vnode, renderer);
|
|
@@ -3939,20 +4267,39 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
|
|
|
3939
4267
|
patchStyleAttribute(oldVnode, vnode, renderer);
|
|
3940
4268
|
patchAttributes(oldVnode, vnode, renderer);
|
|
3941
4269
|
patchProps(oldVnode, vnode, renderer);
|
|
4270
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
4271
|
+
applyRefs(vnode, vnode.owner);
|
|
3942
4272
|
}
|
|
3943
4273
|
function applyStyleScoping(elm, owner, renderer) {
|
|
4274
|
+
const { getClassList } = renderer;
|
|
3944
4275
|
// Set the class name for `*.scoped.css` style scoping.
|
|
3945
|
-
const scopeToken = getScopeTokenClass(owner);
|
|
4276
|
+
const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
3946
4277
|
if (!isNull(scopeToken)) {
|
|
3947
|
-
const { getClassList } = renderer;
|
|
3948
4278
|
// TODO [#2762]: this dot notation with add is probably problematic
|
|
3949
4279
|
// probably we should have a renderer api for just the add operation
|
|
3950
4280
|
getClassList(elm).add(scopeToken);
|
|
3951
4281
|
}
|
|
4282
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
4283
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4284
|
+
const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
|
|
4285
|
+
if (!isNull(legacyScopeToken)) {
|
|
4286
|
+
// TODO [#2762]: this dot notation with add is probably problematic
|
|
4287
|
+
// probably we should have a renderer api for just the add operation
|
|
4288
|
+
getClassList(elm).add(legacyScopeToken);
|
|
4289
|
+
}
|
|
4290
|
+
}
|
|
3952
4291
|
// Set property element for synthetic shadow DOM style scoping.
|
|
3953
4292
|
const { stylesheetToken: syntheticToken } = owner.context;
|
|
3954
|
-
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */
|
|
3955
|
-
|
|
4293
|
+
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
4294
|
+
if (!isUndefined$1(syntheticToken)) {
|
|
4295
|
+
elm.$shadowToken$ = syntheticToken;
|
|
4296
|
+
}
|
|
4297
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4298
|
+
const legacyToken = owner.context.legacyStylesheetToken;
|
|
4299
|
+
if (!isUndefined$1(legacyToken)) {
|
|
4300
|
+
elm.$legacyShadowToken$ = legacyToken;
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
3956
4303
|
}
|
|
3957
4304
|
}
|
|
3958
4305
|
function applyDomManual(elm, vnode) {
|
|
@@ -4312,14 +4659,6 @@ function updateStaticChildren(c1, c2, parent, renderer) {
|
|
|
4312
4659
|
}
|
|
4313
4660
|
}
|
|
4314
4661
|
}
|
|
4315
|
-
function shouldUseNativeCustomElementLifecycle(vm) {
|
|
4316
|
-
if (lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
4317
|
-
// temporary "kill switch"
|
|
4318
|
-
return false;
|
|
4319
|
-
}
|
|
4320
|
-
const apiVersion = getComponentAPIVersion(vm.component.constructor);
|
|
4321
|
-
return isAPIFeatureEnabled(5 /* APIFeature.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE */, apiVersion);
|
|
4322
|
-
}
|
|
4323
4662
|
|
|
4324
4663
|
/*
|
|
4325
4664
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -4331,6 +4670,14 @@ const SymbolIterator = Symbol.iterator;
|
|
|
4331
4670
|
function addVNodeToChildLWC(vnode) {
|
|
4332
4671
|
ArrayPush$1.call(getVMBeingRendered().velements, vnode);
|
|
4333
4672
|
}
|
|
4673
|
+
// [s]tatic [p]art
|
|
4674
|
+
function sp(partId, data) {
|
|
4675
|
+
return {
|
|
4676
|
+
partId,
|
|
4677
|
+
data,
|
|
4678
|
+
elm: undefined, // elm is defined later
|
|
4679
|
+
};
|
|
4680
|
+
}
|
|
4334
4681
|
// [s]coped [s]lot [f]actory
|
|
4335
4682
|
function ssf(slotName, factory) {
|
|
4336
4683
|
return {
|
|
@@ -4344,7 +4691,7 @@ function ssf(slotName, factory) {
|
|
|
4344
4691
|
};
|
|
4345
4692
|
}
|
|
4346
4693
|
// [st]atic node
|
|
4347
|
-
function st(fragment, key,
|
|
4694
|
+
function st(fragment, key, parts) {
|
|
4348
4695
|
const owner = getVMBeingRendered();
|
|
4349
4696
|
const vnode = {
|
|
4350
4697
|
type: 4 /* VNodeType.Static */,
|
|
@@ -4353,12 +4700,8 @@ function st(fragment, key, data) {
|
|
|
4353
4700
|
elm: undefined,
|
|
4354
4701
|
fragment,
|
|
4355
4702
|
owner,
|
|
4356
|
-
|
|
4703
|
+
parts,
|
|
4357
4704
|
};
|
|
4358
|
-
const ref = data === null || data === void 0 ? void 0 : data.ref;
|
|
4359
|
-
if (!isUndefined$1(ref)) {
|
|
4360
|
-
setRefVNode(owner, ref, vnode);
|
|
4361
|
-
}
|
|
4362
4705
|
return vnode;
|
|
4363
4706
|
}
|
|
4364
4707
|
// [fr]agment node
|
|
@@ -4400,7 +4743,7 @@ function h(sel, data, children = EmptyArray) {
|
|
|
4400
4743
|
}
|
|
4401
4744
|
});
|
|
4402
4745
|
}
|
|
4403
|
-
const { key
|
|
4746
|
+
const { key } = data;
|
|
4404
4747
|
const vnode = {
|
|
4405
4748
|
type: 2 /* VNodeType.Element */,
|
|
4406
4749
|
sel,
|
|
@@ -4410,9 +4753,6 @@ function h(sel, data, children = EmptyArray) {
|
|
|
4410
4753
|
key,
|
|
4411
4754
|
owner: vmBeingRendered,
|
|
4412
4755
|
};
|
|
4413
|
-
if (!isUndefined$1(ref)) {
|
|
4414
|
-
setRefVNode(vmBeingRendered, ref, vnode);
|
|
4415
|
-
}
|
|
4416
4756
|
return vnode;
|
|
4417
4757
|
}
|
|
4418
4758
|
// [t]ab[i]ndex function
|
|
@@ -4527,7 +4867,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4527
4867
|
});
|
|
4528
4868
|
}
|
|
4529
4869
|
}
|
|
4530
|
-
const { key
|
|
4870
|
+
const { key } = data;
|
|
4531
4871
|
let elm, aChildren, vm;
|
|
4532
4872
|
const vnode = {
|
|
4533
4873
|
type: 3 /* VNodeType.CustomElement */,
|
|
@@ -4543,9 +4883,6 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4543
4883
|
vm,
|
|
4544
4884
|
};
|
|
4545
4885
|
addVNodeToChildLWC(vnode);
|
|
4546
|
-
if (!isUndefined$1(ref)) {
|
|
4547
|
-
setRefVNode(vmBeingRendered, ref, vnode);
|
|
4548
|
-
}
|
|
4549
4886
|
return vnode;
|
|
4550
4887
|
}
|
|
4551
4888
|
// [i]terable node
|
|
@@ -4836,6 +5173,7 @@ const api = freeze({
|
|
|
4836
5173
|
shc,
|
|
4837
5174
|
ssf,
|
|
4838
5175
|
ddc,
|
|
5176
|
+
sp,
|
|
4839
5177
|
});
|
|
4840
5178
|
|
|
4841
5179
|
/*
|
|
@@ -4993,9 +5331,10 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
4993
5331
|
return (strings, ...keys) => {
|
|
4994
5332
|
const cache = create(null);
|
|
4995
5333
|
return function () {
|
|
4996
|
-
const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5334
|
+
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
4997
5335
|
const hasStyleToken = !isUndefined$1(stylesheetToken);
|
|
4998
5336
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5337
|
+
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !isUndefined$1(legacyStylesheetToken);
|
|
4999
5338
|
let cacheKey = 0;
|
|
5000
5339
|
if (hasStyleToken && hasScopedStyles) {
|
|
5001
5340
|
cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
|
|
@@ -5003,12 +5342,19 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5003
5342
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5004
5343
|
cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
|
|
5005
5344
|
}
|
|
5345
|
+
if (hasLegacyToken) {
|
|
5346
|
+
// This isn't strictly required for prod, but it's required for our karma tests
|
|
5347
|
+
// since the lwcRuntimeFlag may change over time
|
|
5348
|
+
cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
|
|
5349
|
+
}
|
|
5006
5350
|
if (!isUndefined$1(cache[cacheKey])) {
|
|
5007
5351
|
return cache[cacheKey];
|
|
5008
5352
|
}
|
|
5009
|
-
|
|
5010
|
-
const
|
|
5011
|
-
const
|
|
5353
|
+
// If legacy stylesheet tokens are required, then add them to the rendered string
|
|
5354
|
+
const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
|
|
5355
|
+
const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
|
|
5356
|
+
const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
|
|
5357
|
+
const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
|
|
5012
5358
|
let htmlFragment = '';
|
|
5013
5359
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
5014
5360
|
switch (keys[i]) {
|
|
@@ -5084,7 +5430,10 @@ function evaluateTemplate(vm, html) {
|
|
|
5084
5430
|
// Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
|
|
5085
5431
|
context.hasScopedStyles = computeHasScopedStyles(html, vm);
|
|
5086
5432
|
// Update the scoping token on the host element.
|
|
5087
|
-
updateStylesheetToken(vm, html);
|
|
5433
|
+
updateStylesheetToken(vm, html, /* legacy */ false);
|
|
5434
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
5435
|
+
updateStylesheetToken(vm, html, /* legacy */ true);
|
|
5436
|
+
}
|
|
5088
5437
|
// Evaluate, create stylesheet and cache the produced VNode for future
|
|
5089
5438
|
// re-rendering.
|
|
5090
5439
|
const stylesheetsContent = getStylesheetsContent(vm, html);
|
|
@@ -5099,8 +5448,6 @@ function evaluateTemplate(vm, html) {
|
|
|
5099
5448
|
// add the VM to the list of host VMs that can be re-rendered if html is swapped
|
|
5100
5449
|
setActiveVM(vm);
|
|
5101
5450
|
}
|
|
5102
|
-
// reset the refs; they will be set during the tmpl() instantiation
|
|
5103
|
-
vm.refVNodes = html.hasRefs ? create(null) : null;
|
|
5104
5451
|
// right before producing the vnodes, we clear up all internal references
|
|
5105
5452
|
// to custom elements from the template.
|
|
5106
5453
|
vm.velements = [];
|
|
@@ -5270,8 +5617,9 @@ function getComponentAPIVersion(Ctor) {
|
|
|
5270
5617
|
const metadata = registeredComponentMap.get(Ctor);
|
|
5271
5618
|
const apiVersion = metadata === null || metadata === void 0 ? void 0 : metadata.apiVersion;
|
|
5272
5619
|
if (isUndefined$1(apiVersion)) {
|
|
5273
|
-
// This should only occur in
|
|
5274
|
-
//
|
|
5620
|
+
// This should only occur in our Karma tests; in practice every component
|
|
5621
|
+
// is registered, and so this code path should not get hit. But to be safe,
|
|
5622
|
+
// return the lowest possible version.
|
|
5275
5623
|
return LOWEST_API_VERSION;
|
|
5276
5624
|
}
|
|
5277
5625
|
return apiVersion;
|
|
@@ -5319,44 +5667,6 @@ function getWrappedComponentsListener(vm, listener) {
|
|
|
5319
5667
|
return wrappedListener;
|
|
5320
5668
|
}
|
|
5321
5669
|
|
|
5322
|
-
/*
|
|
5323
|
-
* Copyright (c) 2018, salesforce.com, inc.
|
|
5324
|
-
* All rights reserved.
|
|
5325
|
-
* SPDX-License-Identifier: MIT
|
|
5326
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5327
|
-
*/
|
|
5328
|
-
const Services = create(null);
|
|
5329
|
-
const hooks = ['rendered', 'connected', 'disconnected'];
|
|
5330
|
-
/**
|
|
5331
|
-
* EXPERIMENTAL: This function allows for the registration of "services"
|
|
5332
|
-
* in LWC by exposing hooks into the component life-cycle. This API is
|
|
5333
|
-
* subject to change or being removed.
|
|
5334
|
-
*/
|
|
5335
|
-
function register(service) {
|
|
5336
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5337
|
-
assert.isTrue(isObject(service), `Invalid service declaration, ${service}: service must be an object`);
|
|
5338
|
-
}
|
|
5339
|
-
for (let i = 0; i < hooks.length; ++i) {
|
|
5340
|
-
const hookName = hooks[i];
|
|
5341
|
-
if (hookName in service) {
|
|
5342
|
-
let l = Services[hookName];
|
|
5343
|
-
if (isUndefined$1(l)) {
|
|
5344
|
-
Services[hookName] = l = [];
|
|
5345
|
-
}
|
|
5346
|
-
ArrayPush$1.call(l, service[hookName]);
|
|
5347
|
-
}
|
|
5348
|
-
}
|
|
5349
|
-
}
|
|
5350
|
-
function invokeServiceHook(vm, cbs) {
|
|
5351
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5352
|
-
assert.isTrue(isArray$1(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`);
|
|
5353
|
-
}
|
|
5354
|
-
const { component, def, context } = vm;
|
|
5355
|
-
for (let i = 0, len = cbs.length; i < len; ++i) {
|
|
5356
|
-
cbs[i].call(undefined, component, {}, def, context);
|
|
5357
|
-
}
|
|
5358
|
-
}
|
|
5359
|
-
|
|
5360
5670
|
/*
|
|
5361
5671
|
* Copyright (c) 2023, Salesforce.com, inc.
|
|
5362
5672
|
* All rights reserved.
|
|
@@ -5415,12 +5725,18 @@ function resetComponentStateWhenRemoved(vm) {
|
|
|
5415
5725
|
// old vnode.children is removed from the DOM.
|
|
5416
5726
|
function removeVM(vm) {
|
|
5417
5727
|
if (process.env.NODE_ENV !== 'production') {
|
|
5418
|
-
|
|
5728
|
+
if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
5729
|
+
// With native lifecycle, we cannot be certain that connectedCallback was called before a component
|
|
5730
|
+
// was removed from the VDOM. If the component is disconnected, then connectedCallback will not fire
|
|
5731
|
+
// in native mode, although it will fire in synthetic mode due to appendChild triggering it.
|
|
5732
|
+
// See: W-14037619 for details
|
|
5733
|
+
assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
|
|
5734
|
+
}
|
|
5419
5735
|
}
|
|
5420
5736
|
resetComponentStateWhenRemoved(vm);
|
|
5421
5737
|
}
|
|
5422
|
-
function getNearestShadowAncestor(
|
|
5423
|
-
let ancestor =
|
|
5738
|
+
function getNearestShadowAncestor(owner) {
|
|
5739
|
+
let ancestor = owner;
|
|
5424
5740
|
while (!isNull(ancestor) && ancestor.renderMode === 0 /* RenderMode.Light */) {
|
|
5425
5741
|
ancestor = ancestor.owner;
|
|
5426
5742
|
}
|
|
@@ -5454,6 +5770,9 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5454
5770
|
stylesheetToken: undefined,
|
|
5455
5771
|
hasTokenInClass: undefined,
|
|
5456
5772
|
hasTokenInAttribute: undefined,
|
|
5773
|
+
legacyStylesheetToken: undefined,
|
|
5774
|
+
hasLegacyTokenInClass: undefined,
|
|
5775
|
+
hasLegacyTokenInAttribute: undefined,
|
|
5457
5776
|
hasScopedStyles: undefined,
|
|
5458
5777
|
styleVNodes: null,
|
|
5459
5778
|
tplCache: EmptyObject,
|
|
@@ -5478,15 +5797,12 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5478
5797
|
vm.debugInfo = create(null);
|
|
5479
5798
|
}
|
|
5480
5799
|
vm.stylesheets = computeStylesheets(vm, def.ctor);
|
|
5481
|
-
vm.shadowMode = computeShadowMode(vm, renderer);
|
|
5800
|
+
vm.shadowMode = computeShadowMode(def, vm.owner, renderer);
|
|
5482
5801
|
vm.tro = getTemplateReactiveObserver(vm);
|
|
5483
5802
|
if (process.env.NODE_ENV !== 'production') {
|
|
5484
5803
|
vm.toString = () => {
|
|
5485
5804
|
return `[object:vm ${def.name} (${vm.idx})]`;
|
|
5486
5805
|
};
|
|
5487
|
-
if (lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
|
|
5488
|
-
vm.shadowMode = 0 /* ShadowMode.Native */;
|
|
5489
|
-
}
|
|
5490
5806
|
}
|
|
5491
5807
|
// Create component instance associated to the vm and the element.
|
|
5492
5808
|
invokeComponentConstructor(vm, def.ctor);
|
|
@@ -5549,8 +5865,21 @@ function warnOnStylesheetsMutation(ctor) {
|
|
|
5549
5865
|
});
|
|
5550
5866
|
}
|
|
5551
5867
|
}
|
|
5552
|
-
|
|
5553
|
-
|
|
5868
|
+
// Compute the shadowMode/renderMode without creating a VM. This is used in some scenarios like hydration.
|
|
5869
|
+
function computeShadowAndRenderMode(Ctor, renderer) {
|
|
5870
|
+
const def = getComponentInternalDef(Ctor);
|
|
5871
|
+
const { renderMode } = def;
|
|
5872
|
+
// Assume null `owner` - this is what happens in hydration cases anyway
|
|
5873
|
+
const shadowMode = computeShadowMode(def, /* owner */ null, renderer);
|
|
5874
|
+
return { renderMode, shadowMode };
|
|
5875
|
+
}
|
|
5876
|
+
function computeShadowMode(def, owner, renderer) {
|
|
5877
|
+
// Force the shadow mode to always be native. Used for running tests with synthetic shadow patches
|
|
5878
|
+
// on, but components running in actual native shadow mode
|
|
5879
|
+
if (process.env.NODE_ENV !== 'production' &&
|
|
5880
|
+
lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
|
|
5881
|
+
return 0 /* ShadowMode.Native */;
|
|
5882
|
+
}
|
|
5554
5883
|
const { isSyntheticShadowDefined } = renderer;
|
|
5555
5884
|
let shadowMode;
|
|
5556
5885
|
if (isSyntheticShadowDefined) {
|
|
@@ -5559,12 +5888,14 @@ function computeShadowMode(vm, renderer) {
|
|
|
5559
5888
|
// everything defaults to native when the synthetic shadow polyfill is unavailable.
|
|
5560
5889
|
shadowMode = 0 /* ShadowMode.Native */;
|
|
5561
5890
|
}
|
|
5562
|
-
else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE
|
|
5563
|
-
|
|
5891
|
+
else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE ||
|
|
5892
|
+
def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
|
|
5893
|
+
if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */ ||
|
|
5894
|
+
def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
|
|
5564
5895
|
shadowMode = 0 /* ShadowMode.Native */;
|
|
5565
5896
|
}
|
|
5566
5897
|
else {
|
|
5567
|
-
const shadowAncestor = getNearestShadowAncestor(
|
|
5898
|
+
const shadowAncestor = getNearestShadowAncestor(owner);
|
|
5568
5899
|
if (!isNull(shadowAncestor) && shadowAncestor.shadowMode === 0 /* ShadowMode.Native */) {
|
|
5569
5900
|
// Transitive support for native Shadow DOM. A component in native mode
|
|
5570
5901
|
// transitively opts all of its descendants into native.
|
|
@@ -5619,6 +5950,8 @@ function rehydrate(vm) {
|
|
|
5619
5950
|
}
|
|
5620
5951
|
function patchShadowRoot(vm, newCh) {
|
|
5621
5952
|
const { renderRoot, children: oldCh, renderer } = vm;
|
|
5953
|
+
// reset the refs; they will be set during `patchChildren`
|
|
5954
|
+
resetRefVNodes(vm);
|
|
5622
5955
|
// caching the new children collection
|
|
5623
5956
|
vm.children = newCh;
|
|
5624
5957
|
if (newCh.length > 0 || oldCh.length > 0) {
|
|
@@ -5650,10 +5983,6 @@ function runRenderedCallback(vm) {
|
|
|
5650
5983
|
if (!process.env.IS_BROWSER) {
|
|
5651
5984
|
return;
|
|
5652
5985
|
}
|
|
5653
|
-
const { rendered } = Services;
|
|
5654
|
-
if (rendered) {
|
|
5655
|
-
invokeServiceHook(vm, rendered);
|
|
5656
|
-
}
|
|
5657
5986
|
if (!isUndefined$1(renderedCallback)) {
|
|
5658
5987
|
logOperationStart(4 /* OperationId.RenderedCallback */, vm);
|
|
5659
5988
|
invokeComponentCallback(vm, renderedCallback);
|
|
@@ -5696,11 +6025,6 @@ function runConnectedCallback(vm) {
|
|
|
5696
6025
|
return; // nothing to do since it was already connected
|
|
5697
6026
|
}
|
|
5698
6027
|
vm.state = 1 /* VMState.connected */;
|
|
5699
|
-
// reporting connection
|
|
5700
|
-
const { connected } = Services;
|
|
5701
|
-
if (connected) {
|
|
5702
|
-
invokeServiceHook(vm, connected);
|
|
5703
|
-
}
|
|
5704
6028
|
if (hasWireAdapters(vm)) {
|
|
5705
6029
|
connectWireAdapters(vm);
|
|
5706
6030
|
}
|
|
@@ -5726,11 +6050,6 @@ function runDisconnectedCallback(vm) {
|
|
|
5726
6050
|
vm.isDirty = true;
|
|
5727
6051
|
}
|
|
5728
6052
|
vm.state = 2 /* VMState.disconnected */;
|
|
5729
|
-
// reporting disconnection
|
|
5730
|
-
const { disconnected } = Services;
|
|
5731
|
-
if (disconnected) {
|
|
5732
|
-
invokeServiceHook(vm, disconnected);
|
|
5733
|
-
}
|
|
5734
6053
|
if (hasWireAdapters(vm)) {
|
|
5735
6054
|
disconnectWireAdapters(vm);
|
|
5736
6055
|
}
|
|
@@ -5855,7 +6174,12 @@ function runWithBoundaryProtection(vm, owner, pre, job, post) {
|
|
|
5855
6174
|
if (!isUndefined$1(error)) {
|
|
5856
6175
|
addErrorComponentStack(vm, error);
|
|
5857
6176
|
const errorBoundaryVm = isNull(owner) ? undefined : getErrorBoundaryVM(owner);
|
|
5858
|
-
|
|
6177
|
+
// Error boundaries are not in effect when server-side rendering. `errorCallback`
|
|
6178
|
+
// is intended to allow recovery from errors - changing the state of a component
|
|
6179
|
+
// and instigating a re-render. That is at odds with the single-pass, synchronous
|
|
6180
|
+
// nature of SSR. For that reason, all errors bubble up to the `renderComponent`
|
|
6181
|
+
// call site.
|
|
6182
|
+
if (!process.env.IS_BROWSER || isUndefined$1(errorBoundaryVm)) {
|
|
5859
6183
|
throw error; // eslint-disable-line no-unsafe-finally
|
|
5860
6184
|
}
|
|
5861
6185
|
resetComponentRoot(vm); // remove offenders
|
|
@@ -5883,6 +6207,52 @@ function forceRehydration(vm) {
|
|
|
5883
6207
|
scheduleRehydration(vm);
|
|
5884
6208
|
}
|
|
5885
6209
|
}
|
|
6210
|
+
function runFormAssociatedCustomElementCallback(vm, faceCb) {
|
|
6211
|
+
const { renderMode, shadowMode, def: { formAssociated }, } = vm;
|
|
6212
|
+
// Technically the UpgradableConstructor always sets `static formAssociated = true` but silently fail here to match browser behavior.
|
|
6213
|
+
if (isUndefined$1(formAssociated) || isFalse(formAssociated)) {
|
|
6214
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6215
|
+
logWarn(`Form associated lifecycle methods must have the 'static formAssociated' value set in the component's prototype chain.`);
|
|
6216
|
+
}
|
|
6217
|
+
return;
|
|
6218
|
+
}
|
|
6219
|
+
if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
|
|
6220
|
+
throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
|
|
6221
|
+
}
|
|
6222
|
+
invokeComponentCallback(vm, faceCb);
|
|
6223
|
+
}
|
|
6224
|
+
function runFormAssociatedCallback(elm) {
|
|
6225
|
+
const vm = getAssociatedVM(elm);
|
|
6226
|
+
const { formAssociatedCallback } = vm.def;
|
|
6227
|
+
if (!isUndefined$1(formAssociatedCallback)) {
|
|
6228
|
+
runFormAssociatedCustomElementCallback(vm, formAssociatedCallback);
|
|
6229
|
+
}
|
|
6230
|
+
}
|
|
6231
|
+
function runFormDisabledCallback(elm) {
|
|
6232
|
+
const vm = getAssociatedVM(elm);
|
|
6233
|
+
const { formDisabledCallback } = vm.def;
|
|
6234
|
+
if (!isUndefined$1(formDisabledCallback)) {
|
|
6235
|
+
runFormAssociatedCustomElementCallback(vm, formDisabledCallback);
|
|
6236
|
+
}
|
|
6237
|
+
}
|
|
6238
|
+
function runFormResetCallback(elm) {
|
|
6239
|
+
const vm = getAssociatedVM(elm);
|
|
6240
|
+
const { formResetCallback } = vm.def;
|
|
6241
|
+
if (!isUndefined$1(formResetCallback)) {
|
|
6242
|
+
runFormAssociatedCustomElementCallback(vm, formResetCallback);
|
|
6243
|
+
}
|
|
6244
|
+
}
|
|
6245
|
+
function runFormStateRestoreCallback(elm) {
|
|
6246
|
+
const vm = getAssociatedVM(elm);
|
|
6247
|
+
const { formStateRestoreCallback } = vm.def;
|
|
6248
|
+
if (!isUndefined$1(formStateRestoreCallback)) {
|
|
6249
|
+
runFormAssociatedCustomElementCallback(vm, formStateRestoreCallback);
|
|
6250
|
+
}
|
|
6251
|
+
}
|
|
6252
|
+
function resetRefVNodes(vm) {
|
|
6253
|
+
const { cmpTemplate } = vm;
|
|
6254
|
+
vm.refVNodes = !isNull(cmpTemplate) && cmpTemplate.hasRefs ? create(null) : null;
|
|
6255
|
+
}
|
|
5886
6256
|
|
|
5887
6257
|
/*
|
|
5888
6258
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -6057,6 +6427,12 @@ const NON_STANDARD_ARIA_PROPS = [
|
|
|
6057
6427
|
'ariaLabelledBy',
|
|
6058
6428
|
'ariaOwns',
|
|
6059
6429
|
];
|
|
6430
|
+
function isGlobalAriaPolyfillLoaded() {
|
|
6431
|
+
// Sniff for the legacy polyfill being loaded. The reason this works is because ariaActiveDescendant is a
|
|
6432
|
+
// non-standard ARIA property reflection that is only supported in our legacy polyfill. See
|
|
6433
|
+
// @lwc/aria-reflection/README.md for details.
|
|
6434
|
+
return !isUndefined$1(getOwnPropertyDescriptor$1(Element.prototype, 'ariaActiveDescendant'));
|
|
6435
|
+
}
|
|
6060
6436
|
function findVM(elm) {
|
|
6061
6437
|
// If it's a shadow DOM component, then it has a host
|
|
6062
6438
|
const { host } = elm.getRootNode();
|
|
@@ -6116,6 +6492,9 @@ function enableDetection() {
|
|
|
6116
6492
|
}
|
|
6117
6493
|
// @ts-ignore
|
|
6118
6494
|
const { get, set } = descriptor;
|
|
6495
|
+
// It's important for this defineProperty call to happen _after_ ARIA accessors are applied to the
|
|
6496
|
+
// BaseBridgeElement and LightningElement prototypes. Otherwise, we will log/report for access of non-standard
|
|
6497
|
+
// props on these prototypes, which we actually don't want. We only care about access on generic HTMLElements.
|
|
6119
6498
|
defineProperty(prototype, prop, {
|
|
6120
6499
|
get() {
|
|
6121
6500
|
checkAndReportViolation(this, prop, false, undefined);
|
|
@@ -6131,16 +6510,14 @@ function enableDetection() {
|
|
|
6131
6510
|
}
|
|
6132
6511
|
}
|
|
6133
6512
|
// No point in running this code if we're not in a browser, or if the global polyfill is not loaded
|
|
6134
|
-
if (process.env.IS_BROWSER) {
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
onReportingEnabled(enableDetection);
|
|
6143
|
-
}
|
|
6513
|
+
if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
|
|
6514
|
+
// Always run detection in dev mode, so we can at least print to the console
|
|
6515
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6516
|
+
enableDetection();
|
|
6517
|
+
}
|
|
6518
|
+
else {
|
|
6519
|
+
// In prod mode, only enable detection if reporting is enabled
|
|
6520
|
+
onReportingEnabled(enableDetection);
|
|
6144
6521
|
}
|
|
6145
6522
|
}
|
|
6146
6523
|
|
|
@@ -6163,6 +6540,8 @@ function hydrateRoot(vm) {
|
|
|
6163
6540
|
function hydrateVM(vm) {
|
|
6164
6541
|
const children = renderComponent(vm);
|
|
6165
6542
|
vm.children = children;
|
|
6543
|
+
// reset the refs; they will be set during `hydrateChildren`
|
|
6544
|
+
resetRefVNodes(vm);
|
|
6166
6545
|
const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
|
|
6167
6546
|
hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
|
|
6168
6547
|
runRenderedCallback(vm);
|
|
@@ -6271,7 +6650,7 @@ function hydrateStaticElement(elm, vnode, renderer) {
|
|
|
6271
6650
|
return handleMismatch(elm, vnode, renderer);
|
|
6272
6651
|
}
|
|
6273
6652
|
vnode.elm = elm;
|
|
6274
|
-
|
|
6653
|
+
applyStaticParts(elm, vnode, renderer, true);
|
|
6275
6654
|
return elm;
|
|
6276
6655
|
}
|
|
6277
6656
|
function hydrateFragment(elm, vnode, renderer) {
|
|
@@ -6305,7 +6684,7 @@ function hydrateElement(elm, vnode, renderer) {
|
|
|
6305
6684
|
}
|
|
6306
6685
|
}
|
|
6307
6686
|
}
|
|
6308
|
-
|
|
6687
|
+
patchElementPropsAndAttrsAndRefs(vnode, renderer);
|
|
6309
6688
|
if (!isDomManual) {
|
|
6310
6689
|
const { getFirstChild } = renderer;
|
|
6311
6690
|
hydrateChildren(getFirstChild(elm), vnode.children, elm, owner);
|
|
@@ -6329,6 +6708,8 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
6329
6708
|
return handleMismatch(elm, vnode, renderer);
|
|
6330
6709
|
}
|
|
6331
6710
|
const { sel, mode, ctor, owner } = vnode;
|
|
6711
|
+
const { defineCustomElement, getTagName } = renderer;
|
|
6712
|
+
defineCustomElement(StringToLowerCase.call(getTagName(elm)));
|
|
6332
6713
|
const vm = createVM(elm, ctor, renderer, {
|
|
6333
6714
|
mode,
|
|
6334
6715
|
owner,
|
|
@@ -6338,7 +6719,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
6338
6719
|
vnode.elm = elm;
|
|
6339
6720
|
vnode.vm = vm;
|
|
6340
6721
|
allocateChildren(vnode, vm);
|
|
6341
|
-
|
|
6722
|
+
patchElementPropsAndAttrsAndRefs(vnode, renderer);
|
|
6342
6723
|
// Insert hook section:
|
|
6343
6724
|
if (process.env.NODE_ENV !== 'production') {
|
|
6344
6725
|
assert.isTrue(vm.state === 0 /* VMState.created */, `${vm} cannot be recycled.`);
|
|
@@ -6403,9 +6784,11 @@ function handleMismatch(node, vnode, renderer) {
|
|
|
6403
6784
|
removeNode(node, parentNode, renderer);
|
|
6404
6785
|
return vnode.elm;
|
|
6405
6786
|
}
|
|
6406
|
-
function
|
|
6787
|
+
function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
|
|
6407
6788
|
applyEventListeners(vnode, renderer);
|
|
6408
6789
|
patchProps(null, vnode, renderer);
|
|
6790
|
+
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
6791
|
+
applyRefs(vnode, vnode.owner);
|
|
6409
6792
|
}
|
|
6410
6793
|
function hasCorrectNodeType(vnode, node, nodeType, renderer) {
|
|
6411
6794
|
const { getProperty } = renderer;
|
|
@@ -6473,7 +6856,8 @@ function validateClassAttr(vnode, elm, renderer) {
|
|
|
6473
6856
|
const { data, owner } = vnode;
|
|
6474
6857
|
let { className, classMap } = data;
|
|
6475
6858
|
const { getProperty, getClassList, getAttribute } = renderer;
|
|
6476
|
-
|
|
6859
|
+
// we don't care about legacy for hydration. it's a new use case
|
|
6860
|
+
const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
6477
6861
|
const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
|
|
6478
6862
|
// Classnames for scoped CSS are added directly to the DOM during rendering,
|
|
6479
6863
|
// or to the VDOM on the server in the case of SSR. As such, these classnames
|
|
@@ -6788,7 +7172,7 @@ function trackMutations(tmpl) {
|
|
|
6788
7172
|
}
|
|
6789
7173
|
function addLegacyStylesheetTokensShim(tmpl) {
|
|
6790
7174
|
// When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
|
|
6791
|
-
// is accessing the old internal API (backwards compat). Details:
|
|
7175
|
+
// is accessing the old internal API (backwards compat). Details: W-14210169
|
|
6792
7176
|
defineProperty(tmpl, 'stylesheetTokens', {
|
|
6793
7177
|
enumerable: true,
|
|
6794
7178
|
configurable: true,
|
|
@@ -6882,6 +7266,6 @@ function readonly(obj) {
|
|
|
6882
7266
|
return getReadOnlyProxy(obj);
|
|
6883
7267
|
}
|
|
6884
7268
|
|
|
6885
|
-
export { LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly,
|
|
6886
|
-
/** version: 4.0.0
|
|
7269
|
+
export { LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, computeShadowAndRenderMode, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, runFormAssociatedCallback, runFormDisabledCallback, runFormResetCallback, runFormStateRestoreCallback, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
|
|
7270
|
+
/** version: 4.0.0 */
|
|
6887
7271
|
//# sourceMappingURL=index.js.map
|