@lwc/engine-core 3.3.3 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/framework/base-bridge-element.d.ts +2 -1
- package/dist/framework/base-lightning-element.d.ts +5 -0
- package/dist/framework/def.d.ts +5 -0
- package/dist/framework/main.d.ts +1 -1
- package/dist/framework/renderer.d.ts +1 -1
- package/dist/framework/stylesheet.d.ts +2 -2
- package/dist/framework/template.d.ts +2 -0
- package/dist/framework/vm.d.ts +11 -0
- package/dist/index.cjs.js +274 -47
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +272 -49
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs.js
CHANGED
|
@@ -523,8 +523,8 @@ function lockDomMutation() {
|
|
|
523
523
|
assertNotProd(); // this method should never leak to prod
|
|
524
524
|
isDomMutationAllowed = false;
|
|
525
525
|
}
|
|
526
|
-
function
|
|
527
|
-
return
|
|
526
|
+
function logMissingPortalWarn(name, type) {
|
|
527
|
+
return logWarn(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
|
|
528
528
|
}
|
|
529
529
|
function patchElementWithRestrictions(elm, options) {
|
|
530
530
|
assertNotProd(); // this method should never leak to prod
|
|
@@ -549,14 +549,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
549
549
|
shared.assign(descriptors, {
|
|
550
550
|
appendChild: generateDataDescriptor({
|
|
551
551
|
value(aChild) {
|
|
552
|
-
|
|
552
|
+
logMissingPortalWarn('appendChild', 'method');
|
|
553
553
|
return appendChild.call(this, aChild);
|
|
554
554
|
},
|
|
555
555
|
}),
|
|
556
556
|
insertBefore: generateDataDescriptor({
|
|
557
557
|
value(newNode, referenceNode) {
|
|
558
558
|
if (!isDomMutationAllowed) {
|
|
559
|
-
|
|
559
|
+
logMissingPortalWarn('insertBefore', 'method');
|
|
560
560
|
}
|
|
561
561
|
return insertBefore.call(this, newNode, referenceNode);
|
|
562
562
|
},
|
|
@@ -564,14 +564,14 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
564
564
|
removeChild: generateDataDescriptor({
|
|
565
565
|
value(aChild) {
|
|
566
566
|
if (!isDomMutationAllowed) {
|
|
567
|
-
|
|
567
|
+
logMissingPortalWarn('removeChild', 'method');
|
|
568
568
|
}
|
|
569
569
|
return removeChild.call(this, aChild);
|
|
570
570
|
},
|
|
571
571
|
}),
|
|
572
572
|
replaceChild: generateDataDescriptor({
|
|
573
573
|
value(newChild, oldChild) {
|
|
574
|
-
|
|
574
|
+
logMissingPortalWarn('replaceChild', 'method');
|
|
575
575
|
return replaceChild.call(this, newChild, oldChild);
|
|
576
576
|
},
|
|
577
577
|
}),
|
|
@@ -581,7 +581,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
581
581
|
},
|
|
582
582
|
set(value) {
|
|
583
583
|
if (!isDomMutationAllowed) {
|
|
584
|
-
|
|
584
|
+
logMissingPortalWarn('nodeValue', 'property');
|
|
585
585
|
}
|
|
586
586
|
originalNodeValueDescriptor.set.call(this, value);
|
|
587
587
|
},
|
|
@@ -591,7 +591,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
591
591
|
return originalTextContentDescriptor.get.call(this);
|
|
592
592
|
},
|
|
593
593
|
set(value) {
|
|
594
|
-
|
|
594
|
+
logMissingPortalWarn('textContent', 'property');
|
|
595
595
|
originalTextContentDescriptor.set.call(this, value);
|
|
596
596
|
},
|
|
597
597
|
}),
|
|
@@ -600,7 +600,7 @@ function patchElementWithRestrictions(elm, options) {
|
|
|
600
600
|
return originalInnerHTMLDescriptor.get.call(this);
|
|
601
601
|
},
|
|
602
602
|
set(value) {
|
|
603
|
-
|
|
603
|
+
logMissingPortalWarn('innerHTML', 'property');
|
|
604
604
|
return originalInnerHTMLDescriptor.set.call(this, value);
|
|
605
605
|
},
|
|
606
606
|
}),
|
|
@@ -1458,7 +1458,51 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
|
|
|
1458
1458
|
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
1459
|
}
|
|
1460
1460
|
}
|
|
1461
|
-
|
|
1461
|
+
// List of properties on ElementInternals that are formAssociated can be found in the spec:
|
|
1462
|
+
// https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements
|
|
1463
|
+
const formAssociatedProps = new Set([
|
|
1464
|
+
'setFormValue',
|
|
1465
|
+
'form',
|
|
1466
|
+
'setValidity',
|
|
1467
|
+
'willValidate',
|
|
1468
|
+
'validity',
|
|
1469
|
+
'validationMessage',
|
|
1470
|
+
'checkValidity',
|
|
1471
|
+
'reportValidity',
|
|
1472
|
+
'labels',
|
|
1473
|
+
]);
|
|
1474
|
+
// Verify that access to a form-associated property of the ElementInternals proxy has formAssociated set in the LWC.
|
|
1475
|
+
function assertFormAssociatedPropertySet(propertyKey, isFormAssociated) {
|
|
1476
|
+
if (formAssociatedProps.has(propertyKey) && !isFormAssociated) {
|
|
1477
|
+
//Note this error message mirrors Chrome and Firefox error messages, in Safari the error is slightly different.
|
|
1478
|
+
throw new DOMException(`Failed to execute '${propertyKey}' on 'ElementInternals': The target element is not a form-associated custom element.`);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
// Wrap all ElementInternal objects in a proxy to prevent form association when `formAssociated` is not set on an LWC.
|
|
1482
|
+
// This is needed because the 1UpgradeableConstructor1 always sets `formAssociated=true`, which means all
|
|
1483
|
+
// ElementInternal objects will have form-associated properties set when an LWC is placed in a form.
|
|
1484
|
+
// We are doing this to guard against customers taking a dependency on form elements being associated to ElementInternals
|
|
1485
|
+
// when 'formAssociated' has not been set on the LWC.
|
|
1486
|
+
function createElementInternalsProxy(elementInternals, isFormAssociated) {
|
|
1487
|
+
const elementInternalsProxy = new Proxy(elementInternals, {
|
|
1488
|
+
set(target, propertyKey, newValue) {
|
|
1489
|
+
// ElementInternals implementation uses strings as property keys exclusively in chrome, firefox, and safari
|
|
1490
|
+
assertFormAssociatedPropertySet(propertyKey, isFormAssociated);
|
|
1491
|
+
return Reflect.set(target, propertyKey, newValue);
|
|
1492
|
+
},
|
|
1493
|
+
get(target, propertyKey) {
|
|
1494
|
+
// ElementInternals implementation uses strings as property keys exclusively in chrome, firefox, and safari
|
|
1495
|
+
assertFormAssociatedPropertySet(propertyKey, isFormAssociated);
|
|
1496
|
+
const internalsPropertyValue = Reflect.get(target, propertyKey);
|
|
1497
|
+
// Bind the property value to the target so that function invocations are called with the
|
|
1498
|
+
// correct context ('this' value).
|
|
1499
|
+
return typeof internalsPropertyValue === 'function'
|
|
1500
|
+
? internalsPropertyValue.bind(target)
|
|
1501
|
+
: internalsPropertyValue;
|
|
1502
|
+
},
|
|
1503
|
+
});
|
|
1504
|
+
return elementInternalsProxy;
|
|
1505
|
+
}
|
|
1462
1506
|
// @ts-ignore
|
|
1463
1507
|
LightningElement.prototype = {
|
|
1464
1508
|
constructor: LightningElement,
|
|
@@ -1552,15 +1596,13 @@ LightningElement.prototype = {
|
|
|
1552
1596
|
},
|
|
1553
1597
|
attachInternals() {
|
|
1554
1598
|
const vm = getAssociatedVM(this);
|
|
1555
|
-
const { elm, renderer: { attachInternals }, } = vm;
|
|
1556
|
-
if (
|
|
1557
|
-
// Browsers that don't support attachInternals will need to be polyfilled before LWC is loaded.
|
|
1558
|
-
throw new Error('attachInternals API is not supported in this browser environment.');
|
|
1559
|
-
}
|
|
1560
|
-
if (vm.renderMode === 0 /* RenderMode.Light */ || vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
1599
|
+
const { elm, def: { formAssociated }, renderer: { attachInternals }, } = vm;
|
|
1600
|
+
if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
1561
1601
|
throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
|
|
1562
1602
|
}
|
|
1563
|
-
|
|
1603
|
+
const internals = attachInternals(elm);
|
|
1604
|
+
// #TODO[2970]: remove proxy once `UpgradeableConstructor` has been removed
|
|
1605
|
+
return createElementInternalsProxy(internals, Boolean(formAssociated));
|
|
1564
1606
|
},
|
|
1565
1607
|
get isConnected() {
|
|
1566
1608
|
const vm = getAssociatedVM(this);
|
|
@@ -2567,7 +2609,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
|
|
|
2567
2609
|
this[propName] = newValue;
|
|
2568
2610
|
};
|
|
2569
2611
|
}
|
|
2570
|
-
function
|
|
2612
|
+
function createAccessorThatWarns(propName) {
|
|
2613
|
+
let prop;
|
|
2614
|
+
return {
|
|
2615
|
+
get() {
|
|
2616
|
+
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.`);
|
|
2617
|
+
return prop;
|
|
2618
|
+
},
|
|
2619
|
+
set(value) {
|
|
2620
|
+
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.`);
|
|
2621
|
+
prop = value;
|
|
2622
|
+
},
|
|
2623
|
+
enumerable: true,
|
|
2624
|
+
configurable: true,
|
|
2625
|
+
};
|
|
2626
|
+
}
|
|
2627
|
+
function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto) {
|
|
2571
2628
|
const HTMLBridgeElement = class extends SuperClass {
|
|
2572
2629
|
};
|
|
2573
2630
|
// generating the hash table for attributes to avoid duplicate fields and facilitate validation
|
|
@@ -2576,9 +2633,30 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2576
2633
|
const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
|
|
2577
2634
|
const { observedAttributes: superObservedAttributes = [] } = SuperClass;
|
|
2578
2635
|
const descriptors = shared.create(null);
|
|
2636
|
+
// present a hint message so that developers are aware that they have not decorated property with @api
|
|
2637
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2638
|
+
if (!shared.isUndefined(proto) && !shared.isNull(proto)) {
|
|
2639
|
+
const nonPublicPropertiesToWarnOn = new Set([
|
|
2640
|
+
// getters, setters, and methods
|
|
2641
|
+
...shared.keys(shared.getOwnPropertyDescriptors(proto)),
|
|
2642
|
+
// class properties
|
|
2643
|
+
...observedFields,
|
|
2644
|
+
]
|
|
2645
|
+
// we don't want to override HTMLElement props because these are meaningful in other ways,
|
|
2646
|
+
// and can break tooling that expects it to be iterable or defined, e.g. Jest:
|
|
2647
|
+
// https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
|
|
2648
|
+
// It also doesn't make sense to override e.g. "constructor".
|
|
2649
|
+
.filter((propName) => !(propName in HTMLElementPrototype)));
|
|
2650
|
+
for (const propName of nonPublicPropertiesToWarnOn) {
|
|
2651
|
+
if (shared.ArrayIndexOf.call(publicProperties, propName) === -1) {
|
|
2652
|
+
descriptors[propName] = createAccessorThatWarns(propName);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2579
2657
|
// expose getters and setters for each public props on the new Element Bridge
|
|
2580
|
-
for (let i = 0, len =
|
|
2581
|
-
const propName =
|
|
2658
|
+
for (let i = 0, len = publicProperties.length; i < len; i += 1) {
|
|
2659
|
+
const propName = publicProperties[i];
|
|
2582
2660
|
attributeToPropMap[shared.htmlPropertyToAttribute(propName)] = propName;
|
|
2583
2661
|
descriptors[propName] = {
|
|
2584
2662
|
get: createGetter(propName),
|
|
@@ -2605,9 +2683,26 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2605
2683
|
};
|
|
2606
2684
|
// To avoid leaking private component details, accessing internals from outside a component is not allowed.
|
|
2607
2685
|
descriptors.attachInternals = {
|
|
2686
|
+
set() {
|
|
2687
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2688
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2689
|
+
}
|
|
2690
|
+
},
|
|
2608
2691
|
get() {
|
|
2609
2692
|
if (process.env.NODE_ENV !== 'production') {
|
|
2610
|
-
|
|
2693
|
+
logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
|
|
2694
|
+
}
|
|
2695
|
+
},
|
|
2696
|
+
};
|
|
2697
|
+
descriptors.formAssociated = {
|
|
2698
|
+
set() {
|
|
2699
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2700
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2701
|
+
}
|
|
2702
|
+
},
|
|
2703
|
+
get() {
|
|
2704
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2705
|
+
logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
|
|
2611
2706
|
}
|
|
2612
2707
|
},
|
|
2613
2708
|
};
|
|
@@ -2621,7 +2716,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2621
2716
|
shared.defineProperties(HTMLBridgeElement.prototype, descriptors);
|
|
2622
2717
|
return HTMLBridgeElement;
|
|
2623
2718
|
}
|
|
2624
|
-
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), []);
|
|
2719
|
+
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), [], [], null);
|
|
2625
2720
|
if (process.env.IS_BROWSER) {
|
|
2626
2721
|
// This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
|
|
2627
2722
|
// so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
|
|
@@ -2919,7 +3014,7 @@ function getCtorProto(Ctor) {
|
|
|
2919
3014
|
return proto;
|
|
2920
3015
|
}
|
|
2921
3016
|
function createComponentDef(Ctor) {
|
|
2922
|
-
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode } = Ctor;
|
|
3017
|
+
const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
|
|
2923
3018
|
if (process.env.NODE_ENV !== 'production') {
|
|
2924
3019
|
const ctorName = Ctor.name;
|
|
2925
3020
|
// Removing the following assert until https://bugs.webkit.org/show_bug.cgi?id=190140 is fixed.
|
|
@@ -2943,10 +3038,10 @@ function createComponentDef(Ctor) {
|
|
|
2943
3038
|
const decoratorsMeta = getDecoratorsMeta(Ctor);
|
|
2944
3039
|
const { apiFields, apiFieldsConfig, apiMethods, wiredFields, wiredMethods, observedFields } = decoratorsMeta;
|
|
2945
3040
|
const proto = Ctor.prototype;
|
|
2946
|
-
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
|
|
3041
|
+
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, formAssociatedCallback, formResetCallback, formDisabledCallback, formStateRestoreCallback, render, } = proto;
|
|
2947
3042
|
const superProto = getCtorProto(Ctor);
|
|
2948
3043
|
const superDef = superProto !== LightningElement ? getComponentInternalDef(superProto) : lightingElementDef;
|
|
2949
|
-
const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods));
|
|
3044
|
+
const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods), shared.keys(observedFields), proto);
|
|
2950
3045
|
const props = shared.assign(shared.create(null), superDef.props, apiFields);
|
|
2951
3046
|
const propsConfig = shared.assign(shared.create(null), superDef.propsConfig, apiFieldsConfig);
|
|
2952
3047
|
const methods = shared.assign(shared.create(null), superDef.methods, apiMethods);
|
|
@@ -2955,6 +3050,10 @@ function createComponentDef(Ctor) {
|
|
|
2955
3050
|
disconnectedCallback = disconnectedCallback || superDef.disconnectedCallback;
|
|
2956
3051
|
renderedCallback = renderedCallback || superDef.renderedCallback;
|
|
2957
3052
|
errorCallback = errorCallback || superDef.errorCallback;
|
|
3053
|
+
formAssociatedCallback = formAssociatedCallback || superDef.formAssociatedCallback;
|
|
3054
|
+
formResetCallback = formResetCallback || superDef.formResetCallback;
|
|
3055
|
+
formDisabledCallback = formDisabledCallback || superDef.formDisabledCallback;
|
|
3056
|
+
formStateRestoreCallback = formStateRestoreCallback || superDef.formStateRestoreCallback;
|
|
2958
3057
|
render = render || superDef.render;
|
|
2959
3058
|
let shadowSupportMode = superDef.shadowSupportMode;
|
|
2960
3059
|
if (!shared.isUndefined(ctorShadowSupportMode)) {
|
|
@@ -2964,6 +3063,10 @@ function createComponentDef(Ctor) {
|
|
|
2964
3063
|
if (!shared.isUndefined(ctorRenderMode)) {
|
|
2965
3064
|
renderMode = ctorRenderMode === 'light' ? 0 /* RenderMode.Light */ : 1 /* RenderMode.Shadow */;
|
|
2966
3065
|
}
|
|
3066
|
+
let formAssociated = superDef.formAssociated;
|
|
3067
|
+
if (!shared.isUndefined(ctorFormAssociated)) {
|
|
3068
|
+
formAssociated = ctorFormAssociated;
|
|
3069
|
+
}
|
|
2967
3070
|
const template = getComponentRegisteredTemplate(Ctor) || superDef.template;
|
|
2968
3071
|
const name = Ctor.name || superDef.name;
|
|
2969
3072
|
// installing observed fields into the prototype.
|
|
@@ -2979,10 +3082,15 @@ function createComponentDef(Ctor) {
|
|
|
2979
3082
|
template,
|
|
2980
3083
|
renderMode,
|
|
2981
3084
|
shadowSupportMode,
|
|
3085
|
+
formAssociated,
|
|
2982
3086
|
connectedCallback,
|
|
2983
3087
|
disconnectedCallback,
|
|
2984
|
-
renderedCallback,
|
|
2985
3088
|
errorCallback,
|
|
3089
|
+
formAssociatedCallback,
|
|
3090
|
+
formDisabledCallback,
|
|
3091
|
+
formResetCallback,
|
|
3092
|
+
formStateRestoreCallback,
|
|
3093
|
+
renderedCallback,
|
|
2986
3094
|
render,
|
|
2987
3095
|
};
|
|
2988
3096
|
// This is a no-op unless Lightning DevTools are enabled.
|
|
@@ -3059,6 +3167,7 @@ const lightingElementDef = {
|
|
|
3059
3167
|
methods: EmptyObject,
|
|
3060
3168
|
renderMode: 1 /* RenderMode.Shadow */,
|
|
3061
3169
|
shadowSupportMode: "reset" /* ShadowSupportMode.Default */,
|
|
3170
|
+
formAssociated: undefined,
|
|
3062
3171
|
wire: EmptyObject,
|
|
3063
3172
|
bridge: BaseBridgeElement,
|
|
3064
3173
|
template: defaultEmptyTemplate,
|
|
@@ -3115,9 +3224,11 @@ function createInlineStyleVNode(content) {
|
|
|
3115
3224
|
},
|
|
3116
3225
|
}, [api.t(content)]);
|
|
3117
3226
|
}
|
|
3118
|
-
|
|
3227
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3228
|
+
function updateStylesheetToken(vm, template, legacy) {
|
|
3119
3229
|
const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
|
|
3120
|
-
const { stylesheets: newStylesheets
|
|
3230
|
+
const { stylesheets: newStylesheets } = template;
|
|
3231
|
+
const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
|
|
3121
3232
|
const { stylesheets: newVmStylesheets } = vm;
|
|
3122
3233
|
const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
3123
3234
|
const { hasScopedStyles } = context;
|
|
@@ -3125,7 +3236,19 @@ function updateStylesheetToken(vm, template) {
|
|
|
3125
3236
|
let newHasTokenInClass;
|
|
3126
3237
|
let newHasTokenInAttribute;
|
|
3127
3238
|
// Reset the styling token applied to the host element.
|
|
3128
|
-
|
|
3239
|
+
let oldToken;
|
|
3240
|
+
let oldHasTokenInClass;
|
|
3241
|
+
let oldHasTokenInAttribute;
|
|
3242
|
+
if (legacy) {
|
|
3243
|
+
oldToken = context.legacyStylesheetToken;
|
|
3244
|
+
oldHasTokenInClass = context.hasLegacyTokenInClass;
|
|
3245
|
+
oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
|
|
3246
|
+
}
|
|
3247
|
+
else {
|
|
3248
|
+
oldToken = context.stylesheetToken;
|
|
3249
|
+
oldHasTokenInClass = context.hasTokenInClass;
|
|
3250
|
+
oldHasTokenInAttribute = context.hasTokenInAttribute;
|
|
3251
|
+
}
|
|
3129
3252
|
if (!shared.isUndefined(oldToken)) {
|
|
3130
3253
|
if (oldHasTokenInClass) {
|
|
3131
3254
|
getClassList(elm).remove(makeHostToken(oldToken));
|
|
@@ -3153,9 +3276,16 @@ function updateStylesheetToken(vm, template) {
|
|
|
3153
3276
|
}
|
|
3154
3277
|
}
|
|
3155
3278
|
// Update the styling tokens present on the context object.
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3279
|
+
if (legacy) {
|
|
3280
|
+
context.legacyStylesheetToken = newToken;
|
|
3281
|
+
context.hasLegacyTokenInClass = newHasTokenInClass;
|
|
3282
|
+
context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
|
|
3283
|
+
}
|
|
3284
|
+
else {
|
|
3285
|
+
context.stylesheetToken = newToken;
|
|
3286
|
+
context.hasTokenInClass = newHasTokenInClass;
|
|
3287
|
+
context.hasTokenInAttribute = newHasTokenInAttribute;
|
|
3288
|
+
}
|
|
3159
3289
|
}
|
|
3160
3290
|
function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
|
|
3161
3291
|
const content = [];
|
|
@@ -3243,9 +3373,12 @@ function getNearestShadowComponent(vm) {
|
|
|
3243
3373
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
3244
3374
|
* it returns null.
|
|
3245
3375
|
*/
|
|
3246
|
-
|
|
3376
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3377
|
+
function getScopeTokenClass(owner, legacy) {
|
|
3247
3378
|
const { cmpTemplate, context } = owner;
|
|
3248
|
-
return (context.hasScopedStyles &&
|
|
3379
|
+
return ((context.hasScopedStyles &&
|
|
3380
|
+
(legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
|
|
3381
|
+
null);
|
|
3249
3382
|
}
|
|
3250
3383
|
/**
|
|
3251
3384
|
* This function returns the host style token for a custom element if it
|
|
@@ -3744,6 +3877,10 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3744
3877
|
};
|
|
3745
3878
|
let connectedCallback;
|
|
3746
3879
|
let disconnectedCallback;
|
|
3880
|
+
let formAssociatedCallback;
|
|
3881
|
+
let formDisabledCallback;
|
|
3882
|
+
let formResetCallback;
|
|
3883
|
+
let formStateRestoreCallback;
|
|
3747
3884
|
if (lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
|
|
3748
3885
|
connectedCallback = (elm) => {
|
|
3749
3886
|
connectRootElement(elm);
|
|
@@ -3751,13 +3888,25 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
|
|
|
3751
3888
|
disconnectedCallback = (elm) => {
|
|
3752
3889
|
disconnectRootElement(elm);
|
|
3753
3890
|
};
|
|
3891
|
+
formAssociatedCallback = (elm) => {
|
|
3892
|
+
runFormAssociatedCallback(elm);
|
|
3893
|
+
};
|
|
3894
|
+
formDisabledCallback = (elm) => {
|
|
3895
|
+
runFormDisabledCallback(elm);
|
|
3896
|
+
};
|
|
3897
|
+
formResetCallback = (elm) => {
|
|
3898
|
+
runFormResetCallback(elm);
|
|
3899
|
+
};
|
|
3900
|
+
formStateRestoreCallback = (elm) => {
|
|
3901
|
+
runFormStateRestoreCallback(elm);
|
|
3902
|
+
};
|
|
3754
3903
|
}
|
|
3755
3904
|
// Should never get a tag with upper case letter at this point; the compiler
|
|
3756
3905
|
// should produce only tags with lowercase letters. However, the Java
|
|
3757
3906
|
// compiler may generate tagnames with uppercase letters so - for backwards
|
|
3758
3907
|
// compatibility, we lower case the tagname here.
|
|
3759
3908
|
const normalizedTagname = sel.toLowerCase();
|
|
3760
|
-
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback);
|
|
3909
|
+
const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback, formAssociatedCallback, formDisabledCallback, formResetCallback, formStateRestoreCallback);
|
|
3761
3910
|
vnode.elm = elm;
|
|
3762
3911
|
vnode.vm = vm;
|
|
3763
3912
|
linkNodeToShadow(elm, owner, renderer);
|
|
@@ -3963,18 +4112,35 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
|
|
|
3963
4112
|
patchProps(oldVnode, vnode, renderer);
|
|
3964
4113
|
}
|
|
3965
4114
|
function applyStyleScoping(elm, owner, renderer) {
|
|
4115
|
+
const { getClassList } = renderer;
|
|
3966
4116
|
// Set the class name for `*.scoped.css` style scoping.
|
|
3967
|
-
const scopeToken = getScopeTokenClass(owner);
|
|
4117
|
+
const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
3968
4118
|
if (!shared.isNull(scopeToken)) {
|
|
3969
|
-
const { getClassList } = renderer;
|
|
3970
4119
|
// TODO [#2762]: this dot notation with add is probably problematic
|
|
3971
4120
|
// probably we should have a renderer api for just the add operation
|
|
3972
4121
|
getClassList(elm).add(scopeToken);
|
|
3973
4122
|
}
|
|
4123
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
4124
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4125
|
+
const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
|
|
4126
|
+
if (!shared.isNull(legacyScopeToken)) {
|
|
4127
|
+
// TODO [#2762]: this dot notation with add is probably problematic
|
|
4128
|
+
// probably we should have a renderer api for just the add operation
|
|
4129
|
+
getClassList(elm).add(legacyScopeToken);
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
3974
4132
|
// Set property element for synthetic shadow DOM style scoping.
|
|
3975
4133
|
const { stylesheetToken: syntheticToken } = owner.context;
|
|
3976
|
-
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */
|
|
3977
|
-
|
|
4134
|
+
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
4135
|
+
if (!shared.isUndefined(syntheticToken)) {
|
|
4136
|
+
elm.$shadowToken$ = syntheticToken;
|
|
4137
|
+
}
|
|
4138
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4139
|
+
const legacyToken = owner.context.legacyStylesheetToken;
|
|
4140
|
+
if (!shared.isUndefined(legacyToken)) {
|
|
4141
|
+
elm.$legacyShadowToken$ = legacyToken;
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
3978
4144
|
}
|
|
3979
4145
|
}
|
|
3980
4146
|
function applyDomManual(elm, vnode) {
|
|
@@ -5001,9 +5167,10 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5001
5167
|
return (strings, ...keys) => {
|
|
5002
5168
|
const cache = shared.create(null);
|
|
5003
5169
|
return function () {
|
|
5004
|
-
const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5170
|
+
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5005
5171
|
const hasStyleToken = !shared.isUndefined(stylesheetToken);
|
|
5006
5172
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5173
|
+
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
|
|
5007
5174
|
let cacheKey = 0;
|
|
5008
5175
|
if (hasStyleToken && hasScopedStyles) {
|
|
5009
5176
|
cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
|
|
@@ -5011,12 +5178,19 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5011
5178
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5012
5179
|
cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
|
|
5013
5180
|
}
|
|
5181
|
+
if (hasLegacyToken) {
|
|
5182
|
+
// This isn't strictly required for prod, but it's required for our karma tests
|
|
5183
|
+
// since the lwcRuntimeFlag may change over time
|
|
5184
|
+
cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
|
|
5185
|
+
}
|
|
5014
5186
|
if (!shared.isUndefined(cache[cacheKey])) {
|
|
5015
5187
|
return cache[cacheKey];
|
|
5016
5188
|
}
|
|
5017
|
-
|
|
5018
|
-
const
|
|
5019
|
-
const
|
|
5189
|
+
// If legacy stylesheet tokens are required, then add them to the rendered string
|
|
5190
|
+
const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
|
|
5191
|
+
const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
|
|
5192
|
+
const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
|
|
5193
|
+
const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
|
|
5020
5194
|
let htmlFragment = '';
|
|
5021
5195
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
5022
5196
|
switch (keys[i]) {
|
|
@@ -5092,7 +5266,10 @@ function evaluateTemplate(vm, html) {
|
|
|
5092
5266
|
// Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
|
|
5093
5267
|
context.hasScopedStyles = computeHasScopedStyles(html, vm);
|
|
5094
5268
|
// Update the scoping token on the host element.
|
|
5095
|
-
updateStylesheetToken(vm, html);
|
|
5269
|
+
updateStylesheetToken(vm, html, /* legacy */ false);
|
|
5270
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
5271
|
+
updateStylesheetToken(vm, html, /* legacy */ true);
|
|
5272
|
+
}
|
|
5096
5273
|
// Evaluate, create stylesheet and cache the produced VNode for future
|
|
5097
5274
|
// re-rendering.
|
|
5098
5275
|
const stylesheetsContent = getStylesheetsContent(vm, html);
|
|
@@ -5430,6 +5607,9 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5430
5607
|
stylesheetToken: undefined,
|
|
5431
5608
|
hasTokenInClass: undefined,
|
|
5432
5609
|
hasTokenInAttribute: undefined,
|
|
5610
|
+
legacyStylesheetToken: undefined,
|
|
5611
|
+
hasLegacyTokenInClass: undefined,
|
|
5612
|
+
hasLegacyTokenInAttribute: undefined,
|
|
5433
5613
|
hasScopedStyles: undefined,
|
|
5434
5614
|
styleVNodes: null,
|
|
5435
5615
|
tplCache: EmptyObject,
|
|
@@ -5854,6 +6034,48 @@ function forceRehydration(vm) {
|
|
|
5854
6034
|
scheduleRehydration(vm);
|
|
5855
6035
|
}
|
|
5856
6036
|
}
|
|
6037
|
+
function runFormAssociatedCustomElementCallback(vm, faceCb) {
|
|
6038
|
+
const { renderMode, shadowMode, def: { formAssociated }, } = vm;
|
|
6039
|
+
// Technically the UpgradableConstructor always sets `static formAssociated = true` but silently fail here to match browser behavior.
|
|
6040
|
+
if (shared.isUndefined(formAssociated) || shared.isFalse(formAssociated)) {
|
|
6041
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6042
|
+
logWarn(`Form associated lifecycle methods must have the 'static formAssociated' value set in the component's prototype chain.`);
|
|
6043
|
+
}
|
|
6044
|
+
return;
|
|
6045
|
+
}
|
|
6046
|
+
if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
|
|
6047
|
+
throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
|
|
6048
|
+
}
|
|
6049
|
+
invokeComponentCallback(vm, faceCb);
|
|
6050
|
+
}
|
|
6051
|
+
function runFormAssociatedCallback(elm) {
|
|
6052
|
+
const vm = getAssociatedVM(elm);
|
|
6053
|
+
const { formAssociatedCallback } = vm.def;
|
|
6054
|
+
if (!shared.isUndefined(formAssociatedCallback)) {
|
|
6055
|
+
runFormAssociatedCustomElementCallback(vm, formAssociatedCallback);
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
function runFormDisabledCallback(elm) {
|
|
6059
|
+
const vm = getAssociatedVM(elm);
|
|
6060
|
+
const { formDisabledCallback } = vm.def;
|
|
6061
|
+
if (!shared.isUndefined(formDisabledCallback)) {
|
|
6062
|
+
runFormAssociatedCustomElementCallback(vm, formDisabledCallback);
|
|
6063
|
+
}
|
|
6064
|
+
}
|
|
6065
|
+
function runFormResetCallback(elm) {
|
|
6066
|
+
const vm = getAssociatedVM(elm);
|
|
6067
|
+
const { formResetCallback } = vm.def;
|
|
6068
|
+
if (!shared.isUndefined(formResetCallback)) {
|
|
6069
|
+
runFormAssociatedCustomElementCallback(vm, formResetCallback);
|
|
6070
|
+
}
|
|
6071
|
+
}
|
|
6072
|
+
function runFormStateRestoreCallback(elm) {
|
|
6073
|
+
const vm = getAssociatedVM(elm);
|
|
6074
|
+
const { formStateRestoreCallback } = vm.def;
|
|
6075
|
+
if (!shared.isUndefined(formStateRestoreCallback)) {
|
|
6076
|
+
runFormAssociatedCustomElementCallback(vm, formStateRestoreCallback);
|
|
6077
|
+
}
|
|
6078
|
+
}
|
|
5857
6079
|
|
|
5858
6080
|
/*
|
|
5859
6081
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -6450,7 +6672,8 @@ function validateClassAttr(vnode, elm, renderer) {
|
|
|
6450
6672
|
const { data, owner } = vnode;
|
|
6451
6673
|
let { className, classMap } = data;
|
|
6452
6674
|
const { getProperty, getClassList, getAttribute } = renderer;
|
|
6453
|
-
|
|
6675
|
+
// we don't care about legacy for hydration. it's a new use case
|
|
6676
|
+
const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
6454
6677
|
const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
|
|
6455
6678
|
// Classnames for scoped CSS are added directly to the DOM during rendering,
|
|
6456
6679
|
// or to the VDOM on the server in the case of SSR. As such, these classnames
|
|
@@ -6765,7 +6988,7 @@ function trackMutations(tmpl) {
|
|
|
6765
6988
|
}
|
|
6766
6989
|
function addLegacyStylesheetTokensShim(tmpl) {
|
|
6767
6990
|
// When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
|
|
6768
|
-
// is accessing the old internal API (backwards compat). Details:
|
|
6991
|
+
// is accessing the old internal API (backwards compat). Details: W-14210169
|
|
6769
6992
|
shared.defineProperty(tmpl, 'stylesheetTokens', {
|
|
6770
6993
|
enumerable: true,
|
|
6771
6994
|
configurable: true,
|
|
@@ -6890,6 +7113,10 @@ exports.readonly = readonly;
|
|
|
6890
7113
|
exports.registerComponent = registerComponent;
|
|
6891
7114
|
exports.registerDecorators = registerDecorators;
|
|
6892
7115
|
exports.registerTemplate = registerTemplate;
|
|
7116
|
+
exports.runFormAssociatedCallback = runFormAssociatedCallback;
|
|
7117
|
+
exports.runFormDisabledCallback = runFormDisabledCallback;
|
|
7118
|
+
exports.runFormResetCallback = runFormResetCallback;
|
|
7119
|
+
exports.runFormStateRestoreCallback = runFormStateRestoreCallback;
|
|
6893
7120
|
exports.sanitizeAttribute = sanitizeAttribute;
|
|
6894
7121
|
exports.setHooks = setHooks;
|
|
6895
7122
|
exports.swapComponent = swapComponent;
|
|
@@ -6898,5 +7125,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
6898
7125
|
exports.track = track;
|
|
6899
7126
|
exports.unwrap = unwrap;
|
|
6900
7127
|
exports.wire = wire;
|
|
6901
|
-
/** version: 3.
|
|
7128
|
+
/** version: 3.5.0 */
|
|
6902
7129
|
//# sourceMappingURL=index.cjs.js.map
|