@lwc/engine-core 3.3.2 → 3.4.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/stylesheet.d.ts +2 -2
- package/dist/framework/template.d.ts +2 -0
- package/dist/framework/vm.d.ts +6 -0
- package/dist/index.cjs.js +116 -24
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +117 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { LightningElement } from './base-lightning-element';
|
|
1
2
|
export interface HTMLElementConstructor {
|
|
2
3
|
prototype: HTMLElement;
|
|
3
4
|
new (): HTMLElement;
|
|
4
5
|
}
|
|
5
|
-
export declare function HTMLBridgeElementFactory(SuperClass: HTMLElementConstructor,
|
|
6
|
+
export declare function HTMLBridgeElementFactory(SuperClass: HTMLElementConstructor, publicProperties: string[], methods: string[], observedFields: string[], proto: LightningElement | null): HTMLElementConstructor;
|
|
6
7
|
export declare const BaseBridgeElement: HTMLElementConstructor;
|
|
@@ -12,14 +12,14 @@ export type StylesheetFactory = (stylesheetToken: string | undefined, useActualH
|
|
|
12
12
|
* @import CSS declaration).
|
|
13
13
|
*/
|
|
14
14
|
export type TemplateStylesheetFactories = Array<StylesheetFactory | TemplateStylesheetFactories>;
|
|
15
|
-
export declare function updateStylesheetToken(vm: VM, template: Template): void;
|
|
15
|
+
export declare function updateStylesheetToken(vm: VM, template: Template, legacy: boolean): void;
|
|
16
16
|
export declare function getStylesheetsContent(vm: VM, template: Template): string[];
|
|
17
17
|
/**
|
|
18
18
|
* If the component that is currently being rendered uses scoped styles,
|
|
19
19
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
20
20
|
* it returns null.
|
|
21
21
|
*/
|
|
22
|
-
export declare function getScopeTokenClass(owner: VM): string | null;
|
|
22
|
+
export declare function getScopeTokenClass(owner: VM, legacy: boolean): string | null;
|
|
23
23
|
/**
|
|
24
24
|
* This function returns the host style token for a custom element if it
|
|
25
25
|
* exists. Otherwise it returns null.
|
|
@@ -10,6 +10,8 @@ export interface Template {
|
|
|
10
10
|
stylesheets?: TemplateStylesheetFactories;
|
|
11
11
|
/** The string used for synthetic shadow style scoping and light DOM style scoping. */
|
|
12
12
|
stylesheetToken?: string;
|
|
13
|
+
/** Same as the above, but for legacy use cases (pre-LWC v3.0.0) */
|
|
14
|
+
legacyStylesheetToken?: string;
|
|
13
15
|
/** Render mode for the template. Could be light or undefined (which means it's shadow) */
|
|
14
16
|
renderMode?: 'light';
|
|
15
17
|
/** True if this template contains template refs, undefined or false otherwise */
|
package/dist/framework/vm.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ export interface Context {
|
|
|
42
42
|
hasTokenInClass: boolean | undefined;
|
|
43
43
|
/** True if a stylesheetToken was added to the host attributes */
|
|
44
44
|
hasTokenInAttribute: boolean | undefined;
|
|
45
|
+
/** The legacy string used for synthetic shadow DOM and light DOM style scoping. */
|
|
46
|
+
legacyStylesheetToken: string | undefined;
|
|
47
|
+
/** True if a legacyStylesheetToken was added to the host class */
|
|
48
|
+
hasLegacyTokenInClass: boolean | undefined;
|
|
49
|
+
/** True if a legacyStylesheetToken was added to the host attributes */
|
|
50
|
+
hasLegacyTokenInAttribute: boolean | undefined;
|
|
45
51
|
/** Whether or not light DOM scoped styles are present in the stylesheets. */
|
|
46
52
|
hasScopedStyles: boolean | undefined;
|
|
47
53
|
/** The VNodes injected in all the shadow trees to apply the associated component stylesheets. */
|
package/dist/index.cjs.js
CHANGED
|
@@ -2567,7 +2567,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
|
|
|
2567
2567
|
this[propName] = newValue;
|
|
2568
2568
|
};
|
|
2569
2569
|
}
|
|
2570
|
-
function
|
|
2570
|
+
function createAccessorThatWarns(propName) {
|
|
2571
|
+
let prop;
|
|
2572
|
+
return {
|
|
2573
|
+
get() {
|
|
2574
|
+
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.`);
|
|
2575
|
+
return prop;
|
|
2576
|
+
},
|
|
2577
|
+
set(value) {
|
|
2578
|
+
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.`);
|
|
2579
|
+
prop = value;
|
|
2580
|
+
},
|
|
2581
|
+
enumerable: true,
|
|
2582
|
+
configurable: true,
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto) {
|
|
2571
2586
|
const HTMLBridgeElement = class extends SuperClass {
|
|
2572
2587
|
};
|
|
2573
2588
|
// generating the hash table for attributes to avoid duplicate fields and facilitate validation
|
|
@@ -2576,9 +2591,30 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2576
2591
|
const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
|
|
2577
2592
|
const { observedAttributes: superObservedAttributes = [] } = SuperClass;
|
|
2578
2593
|
const descriptors = shared.create(null);
|
|
2594
|
+
// present a hint message so that developers are aware that they have not decorated property with @api
|
|
2595
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2596
|
+
if (!shared.isUndefined(proto) && !shared.isNull(proto)) {
|
|
2597
|
+
const nonPublicPropertiesToWarnOn = new Set([
|
|
2598
|
+
// getters, setters, and methods
|
|
2599
|
+
...shared.keys(shared.getOwnPropertyDescriptors(proto)),
|
|
2600
|
+
// class properties
|
|
2601
|
+
...observedFields,
|
|
2602
|
+
]
|
|
2603
|
+
// we don't want to override HTMLElement props because these are meaningful in other ways,
|
|
2604
|
+
// and can break tooling that expects it to be iterable or defined, e.g. Jest:
|
|
2605
|
+
// https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
|
|
2606
|
+
// It also doesn't make sense to override e.g. "constructor".
|
|
2607
|
+
.filter((propName) => !(propName in HTMLElementPrototype)));
|
|
2608
|
+
for (const propName of nonPublicPropertiesToWarnOn) {
|
|
2609
|
+
if (shared.ArrayIndexOf.call(publicProperties, propName) === -1) {
|
|
2610
|
+
descriptors[propName] = createAccessorThatWarns(propName);
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2579
2615
|
// expose getters and setters for each public props on the new Element Bridge
|
|
2580
|
-
for (let i = 0, len =
|
|
2581
|
-
const propName =
|
|
2616
|
+
for (let i = 0, len = publicProperties.length; i < len; i += 1) {
|
|
2617
|
+
const propName = publicProperties[i];
|
|
2582
2618
|
attributeToPropMap[shared.htmlPropertyToAttribute(propName)] = propName;
|
|
2583
2619
|
descriptors[propName] = {
|
|
2584
2620
|
get: createGetter(propName),
|
|
@@ -2621,7 +2657,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
|
|
|
2621
2657
|
shared.defineProperties(HTMLBridgeElement.prototype, descriptors);
|
|
2622
2658
|
return HTMLBridgeElement;
|
|
2623
2659
|
}
|
|
2624
|
-
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), []);
|
|
2660
|
+
const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), [], [], null);
|
|
2625
2661
|
if (process.env.IS_BROWSER) {
|
|
2626
2662
|
// This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
|
|
2627
2663
|
// so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
|
|
@@ -2946,7 +2982,7 @@ function createComponentDef(Ctor) {
|
|
|
2946
2982
|
let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
|
|
2947
2983
|
const superProto = getCtorProto(Ctor);
|
|
2948
2984
|
const superDef = superProto !== LightningElement ? getComponentInternalDef(superProto) : lightingElementDef;
|
|
2949
|
-
const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods));
|
|
2985
|
+
const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods), shared.keys(observedFields), proto);
|
|
2950
2986
|
const props = shared.assign(shared.create(null), superDef.props, apiFields);
|
|
2951
2987
|
const propsConfig = shared.assign(shared.create(null), superDef.propsConfig, apiFieldsConfig);
|
|
2952
2988
|
const methods = shared.assign(shared.create(null), superDef.methods, apiMethods);
|
|
@@ -3115,9 +3151,11 @@ function createInlineStyleVNode(content) {
|
|
|
3115
3151
|
},
|
|
3116
3152
|
}, [api.t(content)]);
|
|
3117
3153
|
}
|
|
3118
|
-
|
|
3154
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3155
|
+
function updateStylesheetToken(vm, template, legacy) {
|
|
3119
3156
|
const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
|
|
3120
|
-
const { stylesheets: newStylesheets
|
|
3157
|
+
const { stylesheets: newStylesheets } = template;
|
|
3158
|
+
const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
|
|
3121
3159
|
const { stylesheets: newVmStylesheets } = vm;
|
|
3122
3160
|
const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
3123
3161
|
const { hasScopedStyles } = context;
|
|
@@ -3125,7 +3163,19 @@ function updateStylesheetToken(vm, template) {
|
|
|
3125
3163
|
let newHasTokenInClass;
|
|
3126
3164
|
let newHasTokenInAttribute;
|
|
3127
3165
|
// Reset the styling token applied to the host element.
|
|
3128
|
-
|
|
3166
|
+
let oldToken;
|
|
3167
|
+
let oldHasTokenInClass;
|
|
3168
|
+
let oldHasTokenInAttribute;
|
|
3169
|
+
if (legacy) {
|
|
3170
|
+
oldToken = context.legacyStylesheetToken;
|
|
3171
|
+
oldHasTokenInClass = context.hasLegacyTokenInClass;
|
|
3172
|
+
oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
|
|
3173
|
+
}
|
|
3174
|
+
else {
|
|
3175
|
+
oldToken = context.stylesheetToken;
|
|
3176
|
+
oldHasTokenInClass = context.hasTokenInClass;
|
|
3177
|
+
oldHasTokenInAttribute = context.hasTokenInAttribute;
|
|
3178
|
+
}
|
|
3129
3179
|
if (!shared.isUndefined(oldToken)) {
|
|
3130
3180
|
if (oldHasTokenInClass) {
|
|
3131
3181
|
getClassList(elm).remove(makeHostToken(oldToken));
|
|
@@ -3153,9 +3203,16 @@ function updateStylesheetToken(vm, template) {
|
|
|
3153
3203
|
}
|
|
3154
3204
|
}
|
|
3155
3205
|
// Update the styling tokens present on the context object.
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3206
|
+
if (legacy) {
|
|
3207
|
+
context.legacyStylesheetToken = newToken;
|
|
3208
|
+
context.hasLegacyTokenInClass = newHasTokenInClass;
|
|
3209
|
+
context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
|
|
3210
|
+
}
|
|
3211
|
+
else {
|
|
3212
|
+
context.stylesheetToken = newToken;
|
|
3213
|
+
context.hasTokenInClass = newHasTokenInClass;
|
|
3214
|
+
context.hasTokenInAttribute = newHasTokenInAttribute;
|
|
3215
|
+
}
|
|
3159
3216
|
}
|
|
3160
3217
|
function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
|
|
3161
3218
|
const content = [];
|
|
@@ -3243,9 +3300,12 @@ function getNearestShadowComponent(vm) {
|
|
|
3243
3300
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
3244
3301
|
* it returns null.
|
|
3245
3302
|
*/
|
|
3246
|
-
|
|
3303
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
3304
|
+
function getScopeTokenClass(owner, legacy) {
|
|
3247
3305
|
const { cmpTemplate, context } = owner;
|
|
3248
|
-
return (context.hasScopedStyles &&
|
|
3306
|
+
return ((context.hasScopedStyles &&
|
|
3307
|
+
(legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
|
|
3308
|
+
null);
|
|
3249
3309
|
}
|
|
3250
3310
|
/**
|
|
3251
3311
|
* This function returns the host style token for a custom element if it
|
|
@@ -3963,18 +4023,35 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
|
|
|
3963
4023
|
patchProps(oldVnode, vnode, renderer);
|
|
3964
4024
|
}
|
|
3965
4025
|
function applyStyleScoping(elm, owner, renderer) {
|
|
4026
|
+
const { getClassList } = renderer;
|
|
3966
4027
|
// Set the class name for `*.scoped.css` style scoping.
|
|
3967
|
-
const scopeToken = getScopeTokenClass(owner);
|
|
4028
|
+
const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
3968
4029
|
if (!shared.isNull(scopeToken)) {
|
|
3969
|
-
const { getClassList } = renderer;
|
|
3970
4030
|
// TODO [#2762]: this dot notation with add is probably problematic
|
|
3971
4031
|
// probably we should have a renderer api for just the add operation
|
|
3972
4032
|
getClassList(elm).add(scopeToken);
|
|
3973
4033
|
}
|
|
4034
|
+
// TODO [#3733]: remove support for legacy scope tokens
|
|
4035
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4036
|
+
const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
|
|
4037
|
+
if (!shared.isNull(legacyScopeToken)) {
|
|
4038
|
+
// TODO [#2762]: this dot notation with add is probably problematic
|
|
4039
|
+
// probably we should have a renderer api for just the add operation
|
|
4040
|
+
getClassList(elm).add(legacyScopeToken);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
3974
4043
|
// Set property element for synthetic shadow DOM style scoping.
|
|
3975
4044
|
const { stylesheetToken: syntheticToken } = owner.context;
|
|
3976
|
-
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */
|
|
3977
|
-
|
|
4045
|
+
if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
|
|
4046
|
+
if (!shared.isUndefined(syntheticToken)) {
|
|
4047
|
+
elm.$shadowToken$ = syntheticToken;
|
|
4048
|
+
}
|
|
4049
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
4050
|
+
const legacyToken = owner.context.legacyStylesheetToken;
|
|
4051
|
+
if (!shared.isUndefined(legacyToken)) {
|
|
4052
|
+
elm.$legacyShadowToken$ = legacyToken;
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
3978
4055
|
}
|
|
3979
4056
|
}
|
|
3980
4057
|
function applyDomManual(elm, vnode) {
|
|
@@ -5001,9 +5078,10 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5001
5078
|
return (strings, ...keys) => {
|
|
5002
5079
|
const cache = shared.create(null);
|
|
5003
5080
|
return function () {
|
|
5004
|
-
const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5081
|
+
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5005
5082
|
const hasStyleToken = !shared.isUndefined(stylesheetToken);
|
|
5006
5083
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5084
|
+
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
|
|
5007
5085
|
let cacheKey = 0;
|
|
5008
5086
|
if (hasStyleToken && hasScopedStyles) {
|
|
5009
5087
|
cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
|
|
@@ -5011,12 +5089,19 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
5011
5089
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5012
5090
|
cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
|
|
5013
5091
|
}
|
|
5092
|
+
if (hasLegacyToken) {
|
|
5093
|
+
// This isn't strictly required for prod, but it's required for our karma tests
|
|
5094
|
+
// since the lwcRuntimeFlag may change over time
|
|
5095
|
+
cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
|
|
5096
|
+
}
|
|
5014
5097
|
if (!shared.isUndefined(cache[cacheKey])) {
|
|
5015
5098
|
return cache[cacheKey];
|
|
5016
5099
|
}
|
|
5017
|
-
|
|
5018
|
-
const
|
|
5019
|
-
const
|
|
5100
|
+
// If legacy stylesheet tokens are required, then add them to the rendered string
|
|
5101
|
+
const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
|
|
5102
|
+
const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
|
|
5103
|
+
const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
|
|
5104
|
+
const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
|
|
5020
5105
|
let htmlFragment = '';
|
|
5021
5106
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
5022
5107
|
switch (keys[i]) {
|
|
@@ -5092,7 +5177,10 @@ function evaluateTemplate(vm, html) {
|
|
|
5092
5177
|
// Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
|
|
5093
5178
|
context.hasScopedStyles = computeHasScopedStyles(html, vm);
|
|
5094
5179
|
// Update the scoping token on the host element.
|
|
5095
|
-
updateStylesheetToken(vm, html);
|
|
5180
|
+
updateStylesheetToken(vm, html, /* legacy */ false);
|
|
5181
|
+
if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
|
|
5182
|
+
updateStylesheetToken(vm, html, /* legacy */ true);
|
|
5183
|
+
}
|
|
5096
5184
|
// Evaluate, create stylesheet and cache the produced VNode for future
|
|
5097
5185
|
// re-rendering.
|
|
5098
5186
|
const stylesheetsContent = getStylesheetsContent(vm, html);
|
|
@@ -5430,6 +5518,9 @@ function createVM(elm, ctor, renderer, options) {
|
|
|
5430
5518
|
stylesheetToken: undefined,
|
|
5431
5519
|
hasTokenInClass: undefined,
|
|
5432
5520
|
hasTokenInAttribute: undefined,
|
|
5521
|
+
legacyStylesheetToken: undefined,
|
|
5522
|
+
hasLegacyTokenInClass: undefined,
|
|
5523
|
+
hasLegacyTokenInAttribute: undefined,
|
|
5433
5524
|
hasScopedStyles: undefined,
|
|
5434
5525
|
styleVNodes: null,
|
|
5435
5526
|
tplCache: EmptyObject,
|
|
@@ -6450,7 +6541,8 @@ function validateClassAttr(vnode, elm, renderer) {
|
|
|
6450
6541
|
const { data, owner } = vnode;
|
|
6451
6542
|
let { className, classMap } = data;
|
|
6452
6543
|
const { getProperty, getClassList, getAttribute } = renderer;
|
|
6453
|
-
|
|
6544
|
+
// we don't care about legacy for hydration. it's a new use case
|
|
6545
|
+
const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
|
|
6454
6546
|
const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
|
|
6455
6547
|
// Classnames for scoped CSS are added directly to the DOM during rendering,
|
|
6456
6548
|
// or to the VDOM on the server in the case of SSR. As such, these classnames
|
|
@@ -6898,5 +6990,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
6898
6990
|
exports.track = track;
|
|
6899
6991
|
exports.unwrap = unwrap;
|
|
6900
6992
|
exports.wire = wire;
|
|
6901
|
-
/** version: 3.
|
|
6993
|
+
/** version: 3.4.0 */
|
|
6902
6994
|
//# sourceMappingURL=index.cjs.js.map
|