@lwc/engine-core 7.2.0 → 7.2.2
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/fragment-cache.d.ts +6 -0
- package/dist/framework/stylesheet.d.ts +2 -2
- package/dist/index.cjs.js +93 -61
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +94 -62
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const enum FragmentCacheKey {
|
|
2
|
+
HAS_SCOPED_STYLE = 1,
|
|
3
|
+
SHADOW_MODE_SYNTHETIC = 2
|
|
4
|
+
}
|
|
5
|
+
export declare function getFromFragmentCache(cacheKey: number, strings: string[]): Element | undefined;
|
|
6
|
+
export declare function setInFragmentCache(cacheKey: number, strings: string[], element: Element): void;
|
|
@@ -12,7 +12,7 @@ export type Stylesheet = (stylesheetToken: string | undefined, useActualHostSele
|
|
|
12
12
|
*/
|
|
13
13
|
export type Stylesheets = Array<Stylesheet | Stylesheets>;
|
|
14
14
|
export declare function updateStylesheetToken(vm: VM, template: Template, legacy: boolean): void;
|
|
15
|
-
export declare function getStylesheetsContent(vm: VM, template: Template): string
|
|
15
|
+
export declare function getStylesheetsContent(vm: VM, template: Template): ReadonlyArray<string>;
|
|
16
16
|
/**
|
|
17
17
|
* If the component that is currently being rendered uses scoped styles,
|
|
18
18
|
* this returns the unique token for that scoped stylesheet. Otherwise
|
|
@@ -29,5 +29,5 @@ export declare function getScopeTokenClass(owner: VM, legacy: boolean): string |
|
|
|
29
29
|
* @param vnode
|
|
30
30
|
*/
|
|
31
31
|
export declare function getStylesheetTokenHost(vnode: VCustomElement): string | null;
|
|
32
|
-
export declare function createStylesheet(vm: VM, stylesheets: string
|
|
32
|
+
export declare function createStylesheet(vm: VM, stylesheets: ReadonlyArray<string>): VNode[] | null;
|
|
33
33
|
export declare function unrenderStylesheet(stylesheet: Stylesheet): void;
|
package/dist/index.cjs.js
CHANGED
|
@@ -155,7 +155,7 @@ function log(method, message, vm, once) {
|
|
|
155
155
|
}
|
|
156
156
|
alreadyLoggedMessages.add(msg);
|
|
157
157
|
}
|
|
158
|
-
// In
|
|
158
|
+
// In Vitest tests, reduce the warning and error verbosity by not printing the callstack
|
|
159
159
|
if (process.env.NODE_ENV === 'test') {
|
|
160
160
|
/* eslint-disable-next-line no-console */
|
|
161
161
|
console[method](msg);
|
|
@@ -3133,15 +3133,22 @@ function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
|
|
|
3133
3133
|
function getStylesheetsContent(vm, template) {
|
|
3134
3134
|
const { stylesheets, stylesheetToken } = template;
|
|
3135
3135
|
const { stylesheets: vmStylesheets } = vm;
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3136
|
+
const hasTemplateStyles = hasStyles(stylesheets);
|
|
3137
|
+
const hasVmStyles = hasStyles(vmStylesheets);
|
|
3138
|
+
if (hasTemplateStyles) {
|
|
3139
|
+
const content = evaluateStylesheetsContent(stylesheets, stylesheetToken, vm);
|
|
3140
|
+
if (hasVmStyles) {
|
|
3141
|
+
// Slow path – merge the template styles and vm styles
|
|
3142
|
+
shared.ArrayPush.apply(content, evaluateStylesheetsContent(vmStylesheets, stylesheetToken, vm));
|
|
3143
|
+
}
|
|
3144
|
+
return content;
|
|
3139
3145
|
}
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3146
|
+
if (hasVmStyles) {
|
|
3147
|
+
// No template styles, so return vm styles directly
|
|
3148
|
+
return evaluateStylesheetsContent(vmStylesheets, stylesheetToken, vm);
|
|
3143
3149
|
}
|
|
3144
|
-
return
|
|
3150
|
+
// Fastest path - no styles, so return an empty array
|
|
3151
|
+
return EmptyArray;
|
|
3145
3152
|
}
|
|
3146
3153
|
// It might be worth caching this to avoid doing the lookup repeatedly, but
|
|
3147
3154
|
// perf testing has not shown it to be a huge improvement yet:
|
|
@@ -5252,22 +5259,30 @@ function s(slotName, data, children, slotset) {
|
|
|
5252
5259
|
if (renderMode === 0 /* RenderMode.Light */ &&
|
|
5253
5260
|
shared.isAPIFeatureEnabled(6 /* APIFeature.USE_LIGHT_DOM_SLOT_FORWARDING */, apiVersion) &&
|
|
5254
5261
|
(isVBaseElement(vnode) || isVStatic(vnode)) &&
|
|
5255
|
-
// We only need to copy the vnodes when the slot assignment changes, copying every time causes issues with
|
|
5256
|
-
// disconnected/connected callback firing.
|
|
5257
5262
|
vnode.slotAssignment !== data.slotAssignment) {
|
|
5258
|
-
// When the light DOM slot assignment (slot attribute) changes we can't use the same reference
|
|
5259
|
-
// to the vnode because the current way the diffing algo works, it will replace the original
|
|
5260
|
-
// to the host element with a new one. This means the new element will be mounted and
|
|
5261
|
-
// Creating a copy of the vnode
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5263
|
+
// When the light DOM slot assignment (slot attribute) changes, we can't use the same reference
|
|
5264
|
+
// to the vnode because the current way the diffing algo works, it will replace the original
|
|
5265
|
+
// reference to the host element with a new one. This means the new element will be mounted and
|
|
5266
|
+
// immediately unmounted. Creating a copy of the vnode preserves a reference to the previous
|
|
5267
|
+
// host element.
|
|
5268
|
+
clonedVNode = { ...vnode, slotAssignment: data.slotAssignment };
|
|
5269
|
+
// For disconnectedCallback to work correctly in synthetic lifecycle mode, we need to link the
|
|
5270
|
+
// current VM's velements to the clone, so that when the VM unmounts, the clone also unmounts.
|
|
5271
|
+
// Note this only applies to VCustomElements, since those are the elements that we manually need
|
|
5272
|
+
// to call disconnectedCallback for, when running in synthetic lifecycle mode.
|
|
5273
|
+
//
|
|
5274
|
+
// You might think it would make more sense to add the clonedVNode to the same velements array
|
|
5275
|
+
// as the original vnode's VM (i.e. `vnode.owner.velements`) rather than the current VM (i.e.
|
|
5276
|
+
// `vmBeingRendered.velements`), but this actually might not trigger disconnectedCallback
|
|
5277
|
+
// in synthetic lifecycle mode. The reason for this is that a reactivity change may cause
|
|
5278
|
+
// the slottable component to unmount, but _not_ the slotter component (see issue #4446).
|
|
5279
|
+
//
|
|
5280
|
+
// If this occurs, then the slottable component (i.e .this component we are rendering right
|
|
5281
|
+
// now) is the one that needs to own the clone. Whereas if a reactivity change higher in the
|
|
5282
|
+
// tree causes the slotter to unmount, then the slottable will also unmount. So using the
|
|
5283
|
+
// current VM works either way.
|
|
5284
|
+
if (isVCustomElement(vnode)) {
|
|
5285
|
+
addVNodeToChildLWC(clonedVNode);
|
|
5271
5286
|
}
|
|
5272
5287
|
}
|
|
5273
5288
|
// If the slot content is standard type, the content is static, no additional
|
|
@@ -5345,14 +5360,14 @@ function i(iterable, factory) {
|
|
|
5345
5360
|
// TODO [#1276]: compiler should give us some sort of indicator when a vnodes collection is dynamic
|
|
5346
5361
|
sc(list);
|
|
5347
5362
|
const vmBeingRendered = getVMBeingRendered();
|
|
5348
|
-
if (shared.isUndefined(iterable) || iterable
|
|
5363
|
+
if (shared.isUndefined(iterable) || shared.isNull(iterable)) {
|
|
5349
5364
|
if (process.env.NODE_ENV !== 'production') {
|
|
5350
|
-
logError(`Invalid template iteration for value
|
|
5365
|
+
logError(`Invalid template iteration for value \`${shared.toString(iterable)}\` in ${vmBeingRendered}. It must be an array-like object.`, vmBeingRendered);
|
|
5351
5366
|
}
|
|
5352
5367
|
return list;
|
|
5353
5368
|
}
|
|
5354
5369
|
if (process.env.NODE_ENV !== 'production') {
|
|
5355
|
-
shared.assert.isFalse(shared.isUndefined(iterable[SymbolIterator]), `Invalid template iteration for value \`${shared.toString(iterable)}\` in ${vmBeingRendered}. It must be an array-like object
|
|
5370
|
+
shared.assert.isFalse(shared.isUndefined(iterable[SymbolIterator]), `Invalid template iteration for value \`${shared.toString(iterable)}\` in ${vmBeingRendered}. It must be an array-like object.`);
|
|
5356
5371
|
}
|
|
5357
5372
|
const iterator = iterable[SymbolIterator]();
|
|
5358
5373
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -5489,9 +5504,6 @@ function k(compilerKey, obj) {
|
|
|
5489
5504
|
function gid(id) {
|
|
5490
5505
|
const vmBeingRendered = getVMBeingRendered();
|
|
5491
5506
|
if (shared.isUndefined(id) || id === '') {
|
|
5492
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5493
|
-
logError(`Invalid id value "${id}". The id attribute must contain a non-empty string.`, vmBeingRendered);
|
|
5494
|
-
}
|
|
5495
5507
|
return id;
|
|
5496
5508
|
}
|
|
5497
5509
|
// We remove attributes when they are assigned a value of null
|
|
@@ -5508,11 +5520,6 @@ function gid(id) {
|
|
|
5508
5520
|
function fid(url) {
|
|
5509
5521
|
const vmBeingRendered = getVMBeingRendered();
|
|
5510
5522
|
if (shared.isUndefined(url) || url === '') {
|
|
5511
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
5512
|
-
if (shared.isUndefined(url)) {
|
|
5513
|
-
logError(`Undefined url value for "href" or "xlink:href" attribute. Expected a non-empty string.`, vmBeingRendered);
|
|
5514
|
-
}
|
|
5515
|
-
}
|
|
5516
5523
|
return url;
|
|
5517
5524
|
}
|
|
5518
5525
|
// We remove attributes when they are assigned a value of null
|
|
@@ -5797,6 +5804,44 @@ function logGlobalOperationEnd(opId, vm) {
|
|
|
5797
5804
|
}
|
|
5798
5805
|
}
|
|
5799
5806
|
|
|
5807
|
+
/*
|
|
5808
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
5809
|
+
* All rights reserved.
|
|
5810
|
+
* SPDX-License-Identifier: MIT
|
|
5811
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5812
|
+
*/
|
|
5813
|
+
// HAS_SCOPED_STYLE | SHADOW_MODE_SYNTHETIC = 3
|
|
5814
|
+
const MAX_CACHE_KEY = 3;
|
|
5815
|
+
// Mapping of cacheKeys to `string[]` (assumed to come from a tagged template literal) to an Element.
|
|
5816
|
+
// Note that every unique tagged template literal will have a unique `string[]`. So by using `string[]`
|
|
5817
|
+
// as the WeakMap key, we effectively associate each Element with a unique tagged template literal.
|
|
5818
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
|
|
5819
|
+
// Also note that this array only needs to be large enough to account for the maximum possible cache key
|
|
5820
|
+
const fragmentCache = shared.ArrayFrom({ length: MAX_CACHE_KEY + 1 }, () => new WeakMap());
|
|
5821
|
+
// Only used in LWC's Karma tests
|
|
5822
|
+
if (process.env.NODE_ENV === 'test-karma-lwc') {
|
|
5823
|
+
window.__lwcResetFragmentCache = () => {
|
|
5824
|
+
for (let i = 0; i < fragmentCache.length; i++) {
|
|
5825
|
+
fragmentCache[i] = new WeakMap();
|
|
5826
|
+
}
|
|
5827
|
+
};
|
|
5828
|
+
}
|
|
5829
|
+
function checkIsBrowser() {
|
|
5830
|
+
// The fragment cache only serves prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
5831
|
+
/* istanbul ignore next */
|
|
5832
|
+
if (!process.env.IS_BROWSER) {
|
|
5833
|
+
throw new Error('The fragment cache is intended to only be used in @lwc/engine-dom, not @lwc/engine-server');
|
|
5834
|
+
}
|
|
5835
|
+
}
|
|
5836
|
+
function getFromFragmentCache(cacheKey, strings) {
|
|
5837
|
+
checkIsBrowser();
|
|
5838
|
+
return fragmentCache[cacheKey].get(strings);
|
|
5839
|
+
}
|
|
5840
|
+
function setInFragmentCache(cacheKey, strings, element) {
|
|
5841
|
+
checkIsBrowser();
|
|
5842
|
+
fragmentCache[cacheKey].set(strings, element);
|
|
5843
|
+
}
|
|
5844
|
+
|
|
5800
5845
|
/*
|
|
5801
5846
|
* Copyright (c) 2024, Salesforce, Inc.
|
|
5802
5847
|
* All rights reserved.
|
|
@@ -5940,43 +5985,24 @@ function serializeClassAttribute(part, classToken) {
|
|
|
5940
5985
|
const computedClassName = `${classToken} ${shared.keys(classMap).join(' ')}`.trim();
|
|
5941
5986
|
return computedClassName.length ? ` class="${shared.htmlEscape(computedClassName, true)}"` : '';
|
|
5942
5987
|
}
|
|
5943
|
-
// This should be a no-op outside of LWC's Karma tests, where it's not needed
|
|
5944
|
-
let registerFragmentCache = shared.noop;
|
|
5945
|
-
// Only used in LWC's Karma tests
|
|
5946
|
-
if (process.env.NODE_ENV === 'test-karma-lwc') {
|
|
5947
|
-
// Keep track of fragmentCaches, so we can clear them in LWC's Karma tests
|
|
5948
|
-
const fragmentCaches = [];
|
|
5949
|
-
registerFragmentCache = (fragmentCache) => {
|
|
5950
|
-
fragmentCaches.push(fragmentCache);
|
|
5951
|
-
};
|
|
5952
|
-
window.__lwcResetFragmentCaches = () => {
|
|
5953
|
-
for (const fragmentCache of fragmentCaches) {
|
|
5954
|
-
for (const key of shared.keys(fragmentCache)) {
|
|
5955
|
-
delete fragmentCache[key];
|
|
5956
|
-
}
|
|
5957
|
-
}
|
|
5958
|
-
};
|
|
5959
|
-
}
|
|
5960
5988
|
function buildParseFragmentFn(createFragmentFn) {
|
|
5961
|
-
return (strings, ...keys)
|
|
5962
|
-
|
|
5963
|
-
registerFragmentCache(cache);
|
|
5964
|
-
return function (parts) {
|
|
5989
|
+
return function parseFragment(strings, ...keys) {
|
|
5990
|
+
return function applyFragmentParts(parts) {
|
|
5965
5991
|
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5966
5992
|
const hasStyleToken = !shared.isUndefined(stylesheetToken);
|
|
5967
5993
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5968
5994
|
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
|
|
5969
5995
|
let cacheKey = 0;
|
|
5970
5996
|
if (hasStyleToken && hasScopedStyles) {
|
|
5971
|
-
cacheKey |= 1 /*
|
|
5997
|
+
cacheKey |= 1 /* FragmentCacheKey.HAS_SCOPED_STYLE */;
|
|
5972
5998
|
}
|
|
5973
5999
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5974
|
-
cacheKey |= 2 /*
|
|
6000
|
+
cacheKey |= 2 /* FragmentCacheKey.SHADOW_MODE_SYNTHETIC */;
|
|
5975
6001
|
}
|
|
5976
6002
|
// Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
5977
6003
|
if (process.env.IS_BROWSER) {
|
|
5978
6004
|
// Disable this on the server to prevent cache poisoning when expressions are used.
|
|
5979
|
-
const cached =
|
|
6005
|
+
const cached = getFromFragmentCache(cacheKey, strings);
|
|
5980
6006
|
if (!shared.isUndefined(cached)) {
|
|
5981
6007
|
return cached;
|
|
5982
6008
|
}
|
|
@@ -6016,8 +6042,12 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
6016
6042
|
}
|
|
6017
6043
|
}
|
|
6018
6044
|
htmlFragment += strings[strings.length - 1];
|
|
6019
|
-
|
|
6020
|
-
|
|
6045
|
+
const element = createFragmentFn(htmlFragment, renderer);
|
|
6046
|
+
// Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
6047
|
+
if (process.env.IS_BROWSER) {
|
|
6048
|
+
setInFragmentCache(cacheKey, strings, element);
|
|
6049
|
+
}
|
|
6050
|
+
return element;
|
|
6021
6051
|
};
|
|
6022
6052
|
};
|
|
6023
6053
|
}
|
|
@@ -6552,6 +6582,8 @@ function computeShadowMode(def, owner, renderer, hydrated) {
|
|
|
6552
6582
|
// on, but components running in actual native shadow mode
|
|
6553
6583
|
(process.env.NODE_ENV === 'test-karma-lwc' &&
|
|
6554
6584
|
process.env.FORCE_NATIVE_SHADOW_MODE_FOR_TEST) ||
|
|
6585
|
+
// If synthetic shadow is explicitly disabled, use pure-native
|
|
6586
|
+
lwcRuntimeFlags.DISABLE_SYNTHETIC_SHADOW ||
|
|
6555
6587
|
// hydration only supports native shadow
|
|
6556
6588
|
shared.isTrue(hydrated)) {
|
|
6557
6589
|
return 0 /* ShadowMode.Native */;
|
|
@@ -8091,5 +8123,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
8091
8123
|
exports.track = track;
|
|
8092
8124
|
exports.unwrap = unwrap;
|
|
8093
8125
|
exports.wire = wire;
|
|
8094
|
-
/** version: 7.2.
|
|
8126
|
+
/** version: 7.2.2 */
|
|
8095
8127
|
//# sourceMappingURL=index.cjs.js.map
|