@lwc/engine-core 7.3.0-alpha.3 → 8.0.0-alpha.1
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/index.cjs.js +87 -45
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +88 -46
- 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;
|
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);
|
|
@@ -1456,7 +1456,7 @@ async function fetchStylesheet(elm) {
|
|
|
1456
1456
|
try {
|
|
1457
1457
|
return await (await fetch(href)).text();
|
|
1458
1458
|
}
|
|
1459
|
-
catch (
|
|
1459
|
+
catch (_err) {
|
|
1460
1460
|
logWarnOnce(`Ignoring cross-origin stylesheet in migrate mode: ${href}`);
|
|
1461
1461
|
// ignore errors with cross-origin stylesheets - nothing we can do for those
|
|
1462
1462
|
return '';
|
|
@@ -5261,22 +5261,30 @@ function s(slotName, data, children, slotset) {
|
|
|
5261
5261
|
if (renderMode === 0 /* RenderMode.Light */ &&
|
|
5262
5262
|
shared.isAPIFeatureEnabled(6 /* APIFeature.USE_LIGHT_DOM_SLOT_FORWARDING */, apiVersion) &&
|
|
5263
5263
|
(isVBaseElement(vnode) || isVStatic(vnode)) &&
|
|
5264
|
-
// We only need to copy the vnodes when the slot assignment changes, copying every time causes issues with
|
|
5265
|
-
// disconnected/connected callback firing.
|
|
5266
5264
|
vnode.slotAssignment !== data.slotAssignment) {
|
|
5267
|
-
// When the light DOM slot assignment (slot attribute) changes we can't use the same reference
|
|
5268
|
-
// to the vnode because the current way the diffing algo works, it will replace the original
|
|
5269
|
-
// to the host element with a new one. This means the new element will be mounted and
|
|
5270
|
-
// Creating a copy of the vnode
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5265
|
+
// When the light DOM slot assignment (slot attribute) changes, we can't use the same reference
|
|
5266
|
+
// to the vnode because the current way the diffing algo works, it will replace the original
|
|
5267
|
+
// reference to the host element with a new one. This means the new element will be mounted and
|
|
5268
|
+
// immediately unmounted. Creating a copy of the vnode preserves a reference to the previous
|
|
5269
|
+
// host element.
|
|
5270
|
+
clonedVNode = { ...vnode, slotAssignment: data.slotAssignment };
|
|
5271
|
+
// For disconnectedCallback to work correctly in synthetic lifecycle mode, we need to link the
|
|
5272
|
+
// current VM's velements to the clone, so that when the VM unmounts, the clone also unmounts.
|
|
5273
|
+
// Note this only applies to VCustomElements, since those are the elements that we manually need
|
|
5274
|
+
// to call disconnectedCallback for, when running in synthetic lifecycle mode.
|
|
5275
|
+
//
|
|
5276
|
+
// You might think it would make more sense to add the clonedVNode to the same velements array
|
|
5277
|
+
// as the original vnode's VM (i.e. `vnode.owner.velements`) rather than the current VM (i.e.
|
|
5278
|
+
// `vmBeingRendered.velements`), but this actually might not trigger disconnectedCallback
|
|
5279
|
+
// in synthetic lifecycle mode. The reason for this is that a reactivity change may cause
|
|
5280
|
+
// the slottable component to unmount, but _not_ the slotter component (see issue #4446).
|
|
5281
|
+
//
|
|
5282
|
+
// If this occurs, then the slottable component (i.e .this component we are rendering right
|
|
5283
|
+
// now) is the one that needs to own the clone. Whereas if a reactivity change higher in the
|
|
5284
|
+
// tree causes the slotter to unmount, then the slottable will also unmount. So using the
|
|
5285
|
+
// current VM works either way.
|
|
5286
|
+
if (isVCustomElement(vnode)) {
|
|
5287
|
+
addVNodeToChildLWC(clonedVNode);
|
|
5280
5288
|
}
|
|
5281
5289
|
}
|
|
5282
5290
|
// If the slot content is standard type, the content is static, no additional
|
|
@@ -5798,6 +5806,44 @@ function logGlobalOperationEnd(opId, vm) {
|
|
|
5798
5806
|
}
|
|
5799
5807
|
}
|
|
5800
5808
|
|
|
5809
|
+
/*
|
|
5810
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
5811
|
+
* All rights reserved.
|
|
5812
|
+
* SPDX-License-Identifier: MIT
|
|
5813
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5814
|
+
*/
|
|
5815
|
+
// HAS_SCOPED_STYLE | SHADOW_MODE_SYNTHETIC = 3
|
|
5816
|
+
const MAX_CACHE_KEY = 3;
|
|
5817
|
+
// Mapping of cacheKeys to `string[]` (assumed to come from a tagged template literal) to an Element.
|
|
5818
|
+
// Note that every unique tagged template literal will have a unique `string[]`. So by using `string[]`
|
|
5819
|
+
// as the WeakMap key, we effectively associate each Element with a unique tagged template literal.
|
|
5820
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
|
|
5821
|
+
// Also note that this array only needs to be large enough to account for the maximum possible cache key
|
|
5822
|
+
const fragmentCache = shared.ArrayFrom({ length: MAX_CACHE_KEY + 1 }, () => new WeakMap());
|
|
5823
|
+
// Only used in LWC's Karma tests
|
|
5824
|
+
if (process.env.NODE_ENV === 'test-karma-lwc') {
|
|
5825
|
+
window.__lwcResetFragmentCache = () => {
|
|
5826
|
+
for (let i = 0; i < fragmentCache.length; i++) {
|
|
5827
|
+
fragmentCache[i] = new WeakMap();
|
|
5828
|
+
}
|
|
5829
|
+
};
|
|
5830
|
+
}
|
|
5831
|
+
function checkIsBrowser() {
|
|
5832
|
+
// The fragment cache only serves prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
5833
|
+
/* istanbul ignore next */
|
|
5834
|
+
if (!process.env.IS_BROWSER) {
|
|
5835
|
+
throw new Error('The fragment cache is intended to only be used in @lwc/engine-dom, not @lwc/engine-server');
|
|
5836
|
+
}
|
|
5837
|
+
}
|
|
5838
|
+
function getFromFragmentCache(cacheKey, strings) {
|
|
5839
|
+
checkIsBrowser();
|
|
5840
|
+
return fragmentCache[cacheKey].get(strings);
|
|
5841
|
+
}
|
|
5842
|
+
function setInFragmentCache(cacheKey, strings, element) {
|
|
5843
|
+
checkIsBrowser();
|
|
5844
|
+
fragmentCache[cacheKey].set(strings, element);
|
|
5845
|
+
}
|
|
5846
|
+
|
|
5801
5847
|
/*
|
|
5802
5848
|
* Copyright (c) 2024, Salesforce, Inc.
|
|
5803
5849
|
* All rights reserved.
|
|
@@ -5941,47 +5987,33 @@ function serializeClassAttribute(part, classToken) {
|
|
|
5941
5987
|
const computedClassName = `${classToken} ${shared.keys(classMap).join(' ')}`.trim();
|
|
5942
5988
|
return computedClassName.length ? ` class="${shared.htmlEscape(computedClassName, true)}"` : '';
|
|
5943
5989
|
}
|
|
5944
|
-
// This should be a no-op outside of LWC's Karma tests, where it's not needed
|
|
5945
|
-
let registerFragmentCache = shared.noop;
|
|
5946
|
-
// Only used in LWC's Karma tests
|
|
5947
|
-
if (process.env.NODE_ENV === 'test-karma-lwc') {
|
|
5948
|
-
// Keep track of fragmentCaches, so we can clear them in LWC's Karma tests
|
|
5949
|
-
const fragmentCaches = [];
|
|
5950
|
-
registerFragmentCache = (fragmentCache) => {
|
|
5951
|
-
fragmentCaches.push(fragmentCache);
|
|
5952
|
-
};
|
|
5953
|
-
window.__lwcResetFragmentCaches = () => {
|
|
5954
|
-
for (const fragmentCache of fragmentCaches) {
|
|
5955
|
-
for (const key of shared.keys(fragmentCache)) {
|
|
5956
|
-
delete fragmentCache[key];
|
|
5957
|
-
}
|
|
5958
|
-
}
|
|
5959
|
-
};
|
|
5960
|
-
}
|
|
5961
5990
|
function buildParseFragmentFn(createFragmentFn) {
|
|
5962
|
-
return (strings, ...keys)
|
|
5963
|
-
|
|
5964
|
-
registerFragmentCache(cache);
|
|
5965
|
-
return function (parts) {
|
|
5991
|
+
return function parseFragment(strings, ...keys) {
|
|
5992
|
+
return function applyFragmentParts(parts) {
|
|
5966
5993
|
const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
|
|
5967
5994
|
const hasStyleToken = !shared.isUndefined(stylesheetToken);
|
|
5968
5995
|
const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
|
|
5969
5996
|
const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
|
|
5970
5997
|
let cacheKey = 0;
|
|
5971
5998
|
if (hasStyleToken && hasScopedStyles) {
|
|
5972
|
-
cacheKey |= 1 /*
|
|
5999
|
+
cacheKey |= 1 /* FragmentCacheKey.HAS_SCOPED_STYLE */;
|
|
5973
6000
|
}
|
|
5974
6001
|
if (hasStyleToken && isSyntheticShadow) {
|
|
5975
|
-
cacheKey |= 2 /*
|
|
6002
|
+
cacheKey |= 2 /* FragmentCacheKey.SHADOW_MODE_SYNTHETIC */;
|
|
5976
6003
|
}
|
|
5977
6004
|
// Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
5978
6005
|
if (process.env.IS_BROWSER) {
|
|
5979
6006
|
// Disable this on the server to prevent cache poisoning when expressions are used.
|
|
5980
|
-
const cached =
|
|
6007
|
+
const cached = getFromFragmentCache(cacheKey, strings);
|
|
5981
6008
|
if (!shared.isUndefined(cached)) {
|
|
5982
6009
|
return cached;
|
|
5983
6010
|
}
|
|
5984
6011
|
}
|
|
6012
|
+
// See W-16614556
|
|
6013
|
+
if ((hasStyleToken && !shared.isString(stylesheetToken)) ||
|
|
6014
|
+
(hasLegacyToken && !shared.isString(legacyStylesheetToken))) {
|
|
6015
|
+
throw new Error('stylesheet token must be a string');
|
|
6016
|
+
}
|
|
5985
6017
|
// If legacy stylesheet tokens are required, then add them to the rendered string
|
|
5986
6018
|
const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
|
|
5987
6019
|
const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
|
|
@@ -6017,8 +6049,12 @@ function buildParseFragmentFn(createFragmentFn) {
|
|
|
6017
6049
|
}
|
|
6018
6050
|
}
|
|
6019
6051
|
htmlFragment += strings[strings.length - 1];
|
|
6020
|
-
|
|
6021
|
-
|
|
6052
|
+
const element = createFragmentFn(htmlFragment, renderer);
|
|
6053
|
+
// Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
|
|
6054
|
+
if (process.env.IS_BROWSER) {
|
|
6055
|
+
setInFragmentCache(cacheKey, strings, element);
|
|
6056
|
+
}
|
|
6057
|
+
return element;
|
|
6022
6058
|
};
|
|
6023
6059
|
};
|
|
6024
6060
|
}
|
|
@@ -7801,7 +7837,13 @@ function setHooks(hooks) {
|
|
|
7801
7837
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
7802
7838
|
*/
|
|
7803
7839
|
// See @lwc/engine-core/src/framework/template.ts
|
|
7804
|
-
const TEMPLATE_PROPS = [
|
|
7840
|
+
const TEMPLATE_PROPS = [
|
|
7841
|
+
'slots',
|
|
7842
|
+
'stylesheetToken',
|
|
7843
|
+
'stylesheets',
|
|
7844
|
+
'renderMode',
|
|
7845
|
+
'legacyStylesheetToken',
|
|
7846
|
+
];
|
|
7805
7847
|
// Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
|
|
7806
7848
|
const STYLESHEET_PROPS = [
|
|
7807
7849
|
// SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
|
|
@@ -8094,5 +8136,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
8094
8136
|
exports.track = track;
|
|
8095
8137
|
exports.unwrap = unwrap;
|
|
8096
8138
|
exports.wire = wire;
|
|
8097
|
-
/** version:
|
|
8139
|
+
/** version: 8.0.0-alpha.1 */
|
|
8098
8140
|
//# sourceMappingURL=index.cjs.js.map
|