@lwc/engine-core 2.5.6 → 2.5.10-alpha1
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/engine-core.cjs.js +392 -64
- package/dist/engine-core.js +387 -63
- package/package.json +5 -5
- package/types/3rdparty/snabbdom/types.d.ts +1 -0
- package/types/framework/api.d.ts +6 -1
- package/types/framework/hooks.d.ts +5 -0
- package/types/framework/main.d.ts +2 -2
- package/types/framework/overridable-hooks.d.ts +1 -2
- package/types/framework/performance-timing.d.ts +10 -0
- package/types/framework/renderer.d.ts +1 -0
- package/types/framework/utils.d.ts +3 -0
- package/types/framework/vm.d.ts +3 -1
- package/types/shared/logger.d.ts +1 -0
- package/types/framework/api-helpers.d.ts +0 -15
package/dist/engine-core.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* proxy-compat-disable */
|
|
2
|
-
import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, assign, assert, keys, StringCharCodeAt, isString, StringSlice, freeze, defineProperties, forEach, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, getPropertyDescriptor, isObject, AriaPropNameToAttrNameMap, defineProperty, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, noop, isArray as isArray$1, isNumber, StringReplace, KEY__SHADOW_RESOLVER, KEY__SCOPED_CSS, ArrayUnshift, isFrozen } from '@lwc/shared';
|
|
2
|
+
import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, assign, assert, keys, StringCharCodeAt, isString, StringSlice, freeze, defineProperties, forEach, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, getPropertyDescriptor, isObject, AriaPropNameToAttrNameMap, defineProperty, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, ArrayFilter, noop, isArray as isArray$1, isNumber, StringReplace, KEY__SHADOW_RESOLVER, KEY__SCOPED_CSS, ArrayUnshift, isFrozen } from '@lwc/shared';
|
|
3
3
|
import { runtimeFlags } from '@lwc/features';
|
|
4
4
|
export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
|
|
5
5
|
|
|
@@ -48,6 +48,26 @@ function guid() {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
|
51
|
+
} // Borrowed from Vue template compiler.
|
|
52
|
+
// https://github.com/vuejs/vue/blob/531371b818b0e31a989a06df43789728f23dc4e8/src/platforms/web/util/style.js#L5-L16
|
|
53
|
+
|
|
54
|
+
const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
|
|
55
|
+
const PROPERTY_DELIMITER = /:(.+)/;
|
|
56
|
+
function parseStyleText(cssText) {
|
|
57
|
+
const styleMap = {};
|
|
58
|
+
const declarations = cssText.split(DECLARATION_DELIMITER);
|
|
59
|
+
|
|
60
|
+
for (const declaration of declarations) {
|
|
61
|
+
if (declaration) {
|
|
62
|
+
const [prop, value] = declaration.split(PROPERTY_DELIMITER);
|
|
63
|
+
|
|
64
|
+
if (prop !== undefined && value !== undefined) {
|
|
65
|
+
styleMap[prop.trim()] = value.trim();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return styleMap;
|
|
51
71
|
}
|
|
52
72
|
|
|
53
73
|
/*
|
|
@@ -219,8 +239,9 @@ function getErrorComponentStack(vm) {
|
|
|
219
239
|
* SPDX-License-Identifier: MIT
|
|
220
240
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
221
241
|
*/
|
|
222
|
-
|
|
223
|
-
|
|
242
|
+
|
|
243
|
+
function log(method, message, vm) {
|
|
244
|
+
let msg = `[LWC ${method}]: ${message}`;
|
|
224
245
|
|
|
225
246
|
if (!isUndefined$1(vm)) {
|
|
226
247
|
msg = `${msg}\n${getComponentStack(vm)}`;
|
|
@@ -228,7 +249,7 @@ function logError(message, vm) {
|
|
|
228
249
|
|
|
229
250
|
if (process.env.NODE_ENV === 'test') {
|
|
230
251
|
/* eslint-disable-next-line no-console */
|
|
231
|
-
console
|
|
252
|
+
console[method](msg);
|
|
232
253
|
return;
|
|
233
254
|
}
|
|
234
255
|
|
|
@@ -236,10 +257,17 @@ function logError(message, vm) {
|
|
|
236
257
|
throw new Error(msg);
|
|
237
258
|
} catch (e) {
|
|
238
259
|
/* eslint-disable-next-line no-console */
|
|
239
|
-
console
|
|
260
|
+
console[method](e);
|
|
240
261
|
}
|
|
241
262
|
}
|
|
242
263
|
|
|
264
|
+
function logError(message, vm) {
|
|
265
|
+
log('error', message, vm);
|
|
266
|
+
}
|
|
267
|
+
function logWarn(message, vm) {
|
|
268
|
+
log('warn', message, vm);
|
|
269
|
+
}
|
|
270
|
+
|
|
243
271
|
/*
|
|
244
272
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
245
273
|
* All rights reserved.
|
|
@@ -2593,8 +2621,10 @@ for (const [elementProp, rendererMethod] of childGetters) {
|
|
|
2593
2621
|
}
|
|
2594
2622
|
|
|
2595
2623
|
return renderer[rendererMethod](elm);
|
|
2596
|
-
}
|
|
2624
|
+
},
|
|
2597
2625
|
|
|
2626
|
+
configurable: true,
|
|
2627
|
+
enumerable: true
|
|
2598
2628
|
};
|
|
2599
2629
|
}
|
|
2600
2630
|
|
|
@@ -2614,8 +2644,11 @@ for (const queryMethod of queryMethods) {
|
|
|
2614
2644
|
}
|
|
2615
2645
|
|
|
2616
2646
|
return renderer[queryMethod](elm, arg);
|
|
2617
|
-
}
|
|
2647
|
+
},
|
|
2618
2648
|
|
|
2649
|
+
configurable: true,
|
|
2650
|
+
enumerable: true,
|
|
2651
|
+
writable: true
|
|
2619
2652
|
};
|
|
2620
2653
|
}
|
|
2621
2654
|
|
|
@@ -3747,7 +3780,7 @@ function createComponentDef(Ctor) {
|
|
|
3747
3780
|
if (!isUndefined$1(ctorShadowSupportMode)) {
|
|
3748
3781
|
assert.invariant(ctorShadowSupportMode === "any"
|
|
3749
3782
|
/* Any */
|
|
3750
|
-
|| ctorShadowSupportMode === "
|
|
3783
|
+
|| ctorShadowSupportMode === "reset"
|
|
3751
3784
|
/* Default */
|
|
3752
3785
|
, `Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
|
|
3753
3786
|
}
|
|
@@ -3907,7 +3940,7 @@ const lightingElementDef = {
|
|
|
3907
3940
|
renderMode: 1
|
|
3908
3941
|
/* Shadow */
|
|
3909
3942
|
,
|
|
3910
|
-
shadowSupportMode: "
|
|
3943
|
+
shadowSupportMode: "reset"
|
|
3911
3944
|
/* Default */
|
|
3912
3945
|
,
|
|
3913
3946
|
wire: EmptyObject,
|
|
@@ -4052,6 +4085,16 @@ function createElmHook(vnode) {
|
|
|
4052
4085
|
modComputedClassName.create(vnode);
|
|
4053
4086
|
modComputedStyle.create(vnode);
|
|
4054
4087
|
}
|
|
4088
|
+
function hydrateElmHook(vnode) {
|
|
4089
|
+
modEvents.create(vnode); // Attrs are already on the element.
|
|
4090
|
+
// modAttrs.create(vnode);
|
|
4091
|
+
|
|
4092
|
+
modProps.create(vnode); // Already set.
|
|
4093
|
+
// modStaticClassName.create(vnode);
|
|
4094
|
+
// modStaticStyle.create(vnode);
|
|
4095
|
+
// modComputedClassName.create(vnode);
|
|
4096
|
+
// modComputedStyle.create(vnode);
|
|
4097
|
+
}
|
|
4055
4098
|
function fallbackElmHook(elm, vnode) {
|
|
4056
4099
|
const {
|
|
4057
4100
|
owner
|
|
@@ -4216,6 +4259,179 @@ function createChildrenHook(vnode) {
|
|
|
4216
4259
|
}
|
|
4217
4260
|
}
|
|
4218
4261
|
}
|
|
4262
|
+
|
|
4263
|
+
function isElementNode(node) {
|
|
4264
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
4265
|
+
return node.nodeType === Node.ELEMENT_NODE;
|
|
4266
|
+
}
|
|
4267
|
+
|
|
4268
|
+
function vnodesAndElementHaveCompatibleAttrs(vnode, elm) {
|
|
4269
|
+
const {
|
|
4270
|
+
data: {
|
|
4271
|
+
attrs = {}
|
|
4272
|
+
},
|
|
4273
|
+
owner: {
|
|
4274
|
+
renderer
|
|
4275
|
+
}
|
|
4276
|
+
} = vnode;
|
|
4277
|
+
let nodesAreCompatible = true; // Validate attributes, though we could always recovery from those by running the update mods.
|
|
4278
|
+
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
4279
|
+
|
|
4280
|
+
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
4281
|
+
const elmAttrValue = renderer.getAttribute(elm, attrName);
|
|
4282
|
+
|
|
4283
|
+
if (String(attrValue) !== elmAttrValue) {
|
|
4284
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
4285
|
+
nodesAreCompatible = false;
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
|
|
4289
|
+
return nodesAreCompatible;
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
function vnodesAndElementHaveCompatibleClass(vnode, elm) {
|
|
4293
|
+
const {
|
|
4294
|
+
data: {
|
|
4295
|
+
className,
|
|
4296
|
+
classMap
|
|
4297
|
+
},
|
|
4298
|
+
owner: {
|
|
4299
|
+
renderer
|
|
4300
|
+
}
|
|
4301
|
+
} = vnode;
|
|
4302
|
+
let nodesAreCompatible = true;
|
|
4303
|
+
let vnodeClassName;
|
|
4304
|
+
|
|
4305
|
+
if (!isUndefined$1(className) && String(className) !== elm.className) {
|
|
4306
|
+
// className is used when class is bound to an expr.
|
|
4307
|
+
nodesAreCompatible = false;
|
|
4308
|
+
vnodeClassName = className;
|
|
4309
|
+
} else if (!isUndefined$1(classMap)) {
|
|
4310
|
+
// classMap is used when class is set to static value.
|
|
4311
|
+
const classList = renderer.getClassList(elm);
|
|
4312
|
+
let computedClassName = ''; // all classes from the vnode should be in the element.classList
|
|
4313
|
+
|
|
4314
|
+
for (const name in classMap) {
|
|
4315
|
+
computedClassName += ' ' + name;
|
|
4316
|
+
|
|
4317
|
+
if (!classList.contains(name)) {
|
|
4318
|
+
nodesAreCompatible = false;
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
vnodeClassName = computedClassName.trim();
|
|
4323
|
+
|
|
4324
|
+
if (classList.length > keys(classMap).length) {
|
|
4325
|
+
nodesAreCompatible = false;
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
|
|
4329
|
+
if (!nodesAreCompatible) {
|
|
4330
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${elm.className}"`, vnode.owner);
|
|
4331
|
+
}
|
|
4332
|
+
|
|
4333
|
+
return nodesAreCompatible;
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4336
|
+
function vnodesAndElementHaveCompatibleStyle(vnode, elm) {
|
|
4337
|
+
const {
|
|
4338
|
+
data: {
|
|
4339
|
+
style,
|
|
4340
|
+
styleDecls
|
|
4341
|
+
},
|
|
4342
|
+
owner: {
|
|
4343
|
+
renderer
|
|
4344
|
+
}
|
|
4345
|
+
} = vnode;
|
|
4346
|
+
const elmStyle = renderer.getAttribute(elm, 'style') || '';
|
|
4347
|
+
let vnodeStyle;
|
|
4348
|
+
let nodesAreCompatible = true;
|
|
4349
|
+
|
|
4350
|
+
if (!isUndefined$1(style) && style !== elmStyle) {
|
|
4351
|
+
nodesAreCompatible = false;
|
|
4352
|
+
vnodeStyle = style;
|
|
4353
|
+
} else if (!isUndefined$1(styleDecls)) {
|
|
4354
|
+
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
4355
|
+
const expectedStyle = []; // styleMap is used when style is set to static value.
|
|
4356
|
+
|
|
4357
|
+
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
4358
|
+
const [prop, value, important] = styleDecls[i];
|
|
4359
|
+
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
4360
|
+
const parsedPropValue = parsedVnodeStyle[prop];
|
|
4361
|
+
|
|
4362
|
+
if (isUndefined$1(parsedPropValue)) {
|
|
4363
|
+
nodesAreCompatible = false;
|
|
4364
|
+
} else if (!parsedPropValue.startsWith(value)) {
|
|
4365
|
+
nodesAreCompatible = false;
|
|
4366
|
+
} else if (important && !parsedPropValue.endsWith('!important')) {
|
|
4367
|
+
nodesAreCompatible = false;
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
|
|
4371
|
+
if (keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
4372
|
+
nodesAreCompatible = false;
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4375
|
+
vnodeStyle = ArrayJoin.call(expectedStyle, ';');
|
|
4376
|
+
}
|
|
4377
|
+
|
|
4378
|
+
if (!nodesAreCompatible) {
|
|
4379
|
+
// style is used when class is bound to an expr.
|
|
4380
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
4381
|
+
}
|
|
4382
|
+
|
|
4383
|
+
return nodesAreCompatible;
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4386
|
+
function throwHydrationError() {
|
|
4387
|
+
assert.fail('Server rendered elements do not match client side generated elements');
|
|
4388
|
+
}
|
|
4389
|
+
|
|
4390
|
+
function hydrateChildrenHook(elmChildren, children, vm) {
|
|
4391
|
+
var _a, _b;
|
|
4392
|
+
|
|
4393
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4394
|
+
const filteredVNodes = ArrayFilter.call(children, vnode => !!vnode);
|
|
4395
|
+
|
|
4396
|
+
if (elmChildren.length !== filteredVNodes.length) {
|
|
4397
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
|
|
4398
|
+
throwHydrationError();
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
|
|
4402
|
+
let elmCurrentChildIdx = 0;
|
|
4403
|
+
|
|
4404
|
+
for (let j = 0, n = children.length; j < n; j++) {
|
|
4405
|
+
const ch = children[j];
|
|
4406
|
+
|
|
4407
|
+
if (ch != null) {
|
|
4408
|
+
const childNode = elmChildren[elmCurrentChildIdx];
|
|
4409
|
+
|
|
4410
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4411
|
+
// VComments and VTexts validation is handled in their hooks
|
|
4412
|
+
if (isElementNode(childNode)) {
|
|
4413
|
+
if (((_a = ch.sel) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== childNode.tagName.toLowerCase()) {
|
|
4414
|
+
logError(`Hydration mismatch: expecting element with tag "${(_b = ch.sel) === null || _b === void 0 ? void 0 : _b.toLowerCase()}" but found "${childNode.tagName.toLowerCase()}".`, vm);
|
|
4415
|
+
throwHydrationError();
|
|
4416
|
+
} // Note: props are not yet set
|
|
4417
|
+
|
|
4418
|
+
|
|
4419
|
+
const hasIncompatibleAttrs = vnodesAndElementHaveCompatibleAttrs(ch, childNode);
|
|
4420
|
+
const hasIncompatibleClass = vnodesAndElementHaveCompatibleClass(ch, childNode);
|
|
4421
|
+
const hasIncompatibleStyle = vnodesAndElementHaveCompatibleStyle(ch, childNode);
|
|
4422
|
+
const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
4423
|
+
|
|
4424
|
+
if (!isVNodeAndElementCompatible) {
|
|
4425
|
+
throwHydrationError();
|
|
4426
|
+
}
|
|
4427
|
+
}
|
|
4428
|
+
}
|
|
4429
|
+
|
|
4430
|
+
ch.hook.hydrate(ch, childNode);
|
|
4431
|
+
elmCurrentChildIdx++;
|
|
4432
|
+
}
|
|
4433
|
+
}
|
|
4434
|
+
}
|
|
4219
4435
|
function updateCustomElmHook(oldVnode, vnode) {
|
|
4220
4436
|
// Attrs need to be applied to element before props
|
|
4221
4437
|
// IE11 will wipe out value on radio inputs if value
|
|
@@ -4289,36 +4505,6 @@ function getUpgradableConstructor(tagName, renderer) {
|
|
|
4289
4505
|
return CE;
|
|
4290
4506
|
}
|
|
4291
4507
|
|
|
4292
|
-
/*
|
|
4293
|
-
* Copyright (c) 2018, salesforce.com, inc.
|
|
4294
|
-
* All rights reserved.
|
|
4295
|
-
* SPDX-License-Identifier: MIT
|
|
4296
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4297
|
-
*/
|
|
4298
|
-
|
|
4299
|
-
/**
|
|
4300
|
-
* EXPERIMENTAL: This function acts like a hook for Lightning Locker Service and other similar
|
|
4301
|
-
* libraries to sanitize HTML content. This hook process the content passed via the template to
|
|
4302
|
-
* lwc:inner-html directive.
|
|
4303
|
-
* It is meant to be overridden with setSanitizeHtmlContentHook
|
|
4304
|
-
*/
|
|
4305
|
-
let sanitizeHtmlContentHook = () => {
|
|
4306
|
-
// locker-service patches this function during runtime to sanitize HTML content.
|
|
4307
|
-
throw new Error('sanitizeHtmlContent hook must be implemented.');
|
|
4308
|
-
};
|
|
4309
|
-
/**
|
|
4310
|
-
* Sets the sanitizeHtmlContentHook.
|
|
4311
|
-
*
|
|
4312
|
-
* @param newHookImpl
|
|
4313
|
-
* @returns oldHookImplementation.
|
|
4314
|
-
*/
|
|
4315
|
-
|
|
4316
|
-
function setSanitizeHtmlContentHook(newHookImpl) {
|
|
4317
|
-
const currentHook = sanitizeHtmlContentHook;
|
|
4318
|
-
sanitizeHtmlContentHook = newHookImpl;
|
|
4319
|
-
return currentHook;
|
|
4320
|
-
}
|
|
4321
|
-
|
|
4322
4508
|
/*
|
|
4323
4509
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
4324
4510
|
* All rights reserved.
|
|
@@ -4342,7 +4528,26 @@ const TextHook = {
|
|
|
4342
4528
|
update: updateNodeHook,
|
|
4343
4529
|
insert: insertNodeHook,
|
|
4344
4530
|
move: insertNodeHook,
|
|
4345
|
-
remove: removeNodeHook
|
|
4531
|
+
remove: removeNodeHook,
|
|
4532
|
+
hydrate: (vNode, node) => {
|
|
4533
|
+
var _a;
|
|
4534
|
+
|
|
4535
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4536
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
4537
|
+
if (node.nodeType !== Node.TEXT_NODE) {
|
|
4538
|
+
logError('Hydration mismatch: incorrect node type received', vNode.owner);
|
|
4539
|
+
assert.fail('Hydration mismatch: incorrect node type received.');
|
|
4540
|
+
}
|
|
4541
|
+
|
|
4542
|
+
if (node.nodeValue !== vNode.text) {
|
|
4543
|
+
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vNode.owner);
|
|
4544
|
+
}
|
|
4545
|
+
} // always set the text value to the one from the vnode.
|
|
4546
|
+
|
|
4547
|
+
|
|
4548
|
+
node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
|
|
4549
|
+
vNode.elm = node;
|
|
4550
|
+
}
|
|
4346
4551
|
};
|
|
4347
4552
|
const CommentHook = {
|
|
4348
4553
|
create: vnode => {
|
|
@@ -4360,7 +4565,26 @@ const CommentHook = {
|
|
|
4360
4565
|
update: updateNodeHook,
|
|
4361
4566
|
insert: insertNodeHook,
|
|
4362
4567
|
move: insertNodeHook,
|
|
4363
|
-
remove: removeNodeHook
|
|
4568
|
+
remove: removeNodeHook,
|
|
4569
|
+
hydrate: (vNode, node) => {
|
|
4570
|
+
var _a;
|
|
4571
|
+
|
|
4572
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4573
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
4574
|
+
if (node.nodeType !== Node.COMMENT_NODE) {
|
|
4575
|
+
logError('Hydration mismatch: incorrect node type received', vNode.owner);
|
|
4576
|
+
assert.fail('Hydration mismatch: incorrect node type received.');
|
|
4577
|
+
}
|
|
4578
|
+
|
|
4579
|
+
if (node.nodeValue !== vNode.text) {
|
|
4580
|
+
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vNode.owner);
|
|
4581
|
+
}
|
|
4582
|
+
} // always set the text value to the one from the vnode.
|
|
4583
|
+
|
|
4584
|
+
|
|
4585
|
+
node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
|
|
4586
|
+
vNode.elm = node;
|
|
4587
|
+
}
|
|
4364
4588
|
}; // insert is called after update, which is used somewhere else (via a module)
|
|
4365
4589
|
// to mark the vm as inserted, that means we cannot use update as the main channel
|
|
4366
4590
|
// to rehydrate when dirty, because sometimes the element is not inserted just yet,
|
|
@@ -4400,6 +4624,38 @@ const ElementHook = {
|
|
|
4400
4624
|
remove: (vnode, parentNode) => {
|
|
4401
4625
|
removeNodeHook(vnode, parentNode);
|
|
4402
4626
|
removeElmHook(vnode);
|
|
4627
|
+
},
|
|
4628
|
+
hydrate: (vnode, node) => {
|
|
4629
|
+
const elm = node;
|
|
4630
|
+
vnode.elm = elm;
|
|
4631
|
+
const {
|
|
4632
|
+
context
|
|
4633
|
+
} = vnode.data;
|
|
4634
|
+
const isDomManual = Boolean(!isUndefined$1(context) && !isUndefined$1(context.lwc) && context.lwc.dom === "manual"
|
|
4635
|
+
/* manual */
|
|
4636
|
+
);
|
|
4637
|
+
|
|
4638
|
+
if (isDomManual) {
|
|
4639
|
+
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
4640
|
+
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
4641
|
+
const {
|
|
4642
|
+
props
|
|
4643
|
+
} = vnode.data;
|
|
4644
|
+
|
|
4645
|
+
if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
|
|
4646
|
+
if (elm.innerHTML === props.innerHTML) {
|
|
4647
|
+
delete props.innerHTML;
|
|
4648
|
+
} else {
|
|
4649
|
+
logWarn(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4654
|
+
hydrateElmHook(vnode);
|
|
4655
|
+
|
|
4656
|
+
if (!isDomManual) {
|
|
4657
|
+
hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vnode.owner);
|
|
4658
|
+
}
|
|
4403
4659
|
}
|
|
4404
4660
|
};
|
|
4405
4661
|
const CustomElementHook = {
|
|
@@ -4491,6 +4747,44 @@ const CustomElementHook = {
|
|
|
4491
4747
|
// will take care of disconnecting any child VM attached to its shadow as well.
|
|
4492
4748
|
removeVM(vm);
|
|
4493
4749
|
}
|
|
4750
|
+
},
|
|
4751
|
+
hydrate: (vnode, elm) => {
|
|
4752
|
+
// the element is created, but the vm is not
|
|
4753
|
+
const {
|
|
4754
|
+
sel,
|
|
4755
|
+
mode,
|
|
4756
|
+
ctor,
|
|
4757
|
+
owner
|
|
4758
|
+
} = vnode;
|
|
4759
|
+
const def = getComponentInternalDef(ctor);
|
|
4760
|
+
createVM(elm, def, {
|
|
4761
|
+
mode,
|
|
4762
|
+
owner,
|
|
4763
|
+
tagName: sel,
|
|
4764
|
+
renderer: owner.renderer
|
|
4765
|
+
});
|
|
4766
|
+
vnode.elm = elm;
|
|
4767
|
+
const vm = getAssociatedVM(elm);
|
|
4768
|
+
allocateChildrenHook(vnode, vm);
|
|
4769
|
+
hydrateElmHook(vnode); // Insert hook section:
|
|
4770
|
+
|
|
4771
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4772
|
+
assert.isTrue(vm.state === 0
|
|
4773
|
+
/* created */
|
|
4774
|
+
, `${vm} cannot be recycled.`);
|
|
4775
|
+
}
|
|
4776
|
+
|
|
4777
|
+
runConnectedCallback(vm);
|
|
4778
|
+
|
|
4779
|
+
if (vm.renderMode !== 0
|
|
4780
|
+
/* Light */
|
|
4781
|
+
) {
|
|
4782
|
+
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
4783
|
+
// Note: for Light DOM, this is handled while hydrating the VM
|
|
4784
|
+
hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vm);
|
|
4785
|
+
}
|
|
4786
|
+
|
|
4787
|
+
hydrateVM(vm);
|
|
4494
4788
|
}
|
|
4495
4789
|
};
|
|
4496
4790
|
|
|
@@ -4803,7 +5097,7 @@ function co(text) {
|
|
|
4803
5097
|
|
|
4804
5098
|
|
|
4805
5099
|
function d(value) {
|
|
4806
|
-
return value == null ? '' : value;
|
|
5100
|
+
return value == null ? '' : String(value);
|
|
4807
5101
|
} // [b]ind function
|
|
4808
5102
|
|
|
4809
5103
|
|
|
@@ -4965,9 +5259,28 @@ function sc(vnodes) {
|
|
|
4965
5259
|
|
|
4966
5260
|
markAsDynamicChildren(vnodes);
|
|
4967
5261
|
return vnodes;
|
|
4968
|
-
}
|
|
5262
|
+
}
|
|
5263
|
+
/**
|
|
5264
|
+
* EXPERIMENTAL: This function acts like a hook for Lightning Locker Service and other similar
|
|
5265
|
+
* libraries to sanitize HTML content. This hook process the content passed via the template to
|
|
5266
|
+
* lwc:inner-html directive.
|
|
5267
|
+
* It is meant to be overridden with setSanitizeHtmlContentHook, it throws an error by default.
|
|
5268
|
+
*/
|
|
4969
5269
|
|
|
4970
5270
|
|
|
5271
|
+
let sanitizeHtmlContentHook = () => {
|
|
5272
|
+
// locker-service patches this function during runtime to sanitize HTML content.
|
|
5273
|
+
throw new Error('sanitizeHtmlContent hook must be implemented.');
|
|
5274
|
+
};
|
|
5275
|
+
/**
|
|
5276
|
+
* Sets the sanitizeHtmlContentHook.
|
|
5277
|
+
*/
|
|
5278
|
+
|
|
5279
|
+
|
|
5280
|
+
function setSanitizeHtmlContentHook(newHookImpl) {
|
|
5281
|
+
sanitizeHtmlContentHook = newHookImpl;
|
|
5282
|
+
} // [s]anitize [h]tml [c]ontent
|
|
5283
|
+
|
|
4971
5284
|
function shc(content) {
|
|
4972
5285
|
return sanitizeHtmlContentHook(content);
|
|
4973
5286
|
}
|
|
@@ -5159,7 +5472,10 @@ function createStylesheet(vm, stylesheets) {
|
|
|
5159
5472
|
for (let i = 0; i < stylesheets.length; i++) {
|
|
5160
5473
|
renderer.insertGlobalStylesheet(stylesheets[i]);
|
|
5161
5474
|
}
|
|
5162
|
-
} else if (renderer.ssr) {
|
|
5475
|
+
} else if (renderer.ssr || renderer.isHydrating()) {
|
|
5476
|
+
// Note: We need to ensure that during hydration, the stylesheets method is the same as those in ssr.
|
|
5477
|
+
// This works in the client, because the stylesheets are created, and cached in the VM
|
|
5478
|
+
// the first time the VM renders.
|
|
5163
5479
|
// native shadow or light DOM, SSR
|
|
5164
5480
|
const combinedStylesheetContent = ArrayJoin.call(stylesheets, '\n');
|
|
5165
5481
|
return createInlineStyleVNode(combinedStylesheetContent);
|
|
@@ -5756,12 +6072,20 @@ function connectRootElement(elm) {
|
|
|
5756
6072
|
/* GlobalHydrate */
|
|
5757
6073
|
, vm);
|
|
5758
6074
|
}
|
|
6075
|
+
function hydrateRootElement(elm) {
|
|
6076
|
+
const vm = getAssociatedVM(elm);
|
|
6077
|
+
runConnectedCallback(vm);
|
|
6078
|
+
hydrateVM(vm);
|
|
6079
|
+
}
|
|
5759
6080
|
function disconnectRootElement(elm) {
|
|
5760
6081
|
const vm = getAssociatedVM(elm);
|
|
5761
6082
|
resetComponentStateWhenRemoved(vm);
|
|
5762
6083
|
}
|
|
5763
6084
|
function appendVM(vm) {
|
|
5764
6085
|
rehydrate(vm);
|
|
6086
|
+
}
|
|
6087
|
+
function hydrateVM(vm) {
|
|
6088
|
+
hydrate(vm);
|
|
5765
6089
|
} // just in case the component comes back, with this we guarantee re-rendering it
|
|
5766
6090
|
// while preventing any attempt to rehydration until after reinsertion.
|
|
5767
6091
|
|
|
@@ -5992,6 +6316,22 @@ function rehydrate(vm) {
|
|
|
5992
6316
|
}
|
|
5993
6317
|
}
|
|
5994
6318
|
|
|
6319
|
+
function hydrate(vm) {
|
|
6320
|
+
if (isTrue(vm.isDirty)) {
|
|
6321
|
+
// manually diffing/patching here.
|
|
6322
|
+
// This routine is:
|
|
6323
|
+
// patchShadowRoot(vm, children);
|
|
6324
|
+
// -> addVnodes.
|
|
6325
|
+
const children = renderComponent(vm);
|
|
6326
|
+
vm.children = children;
|
|
6327
|
+
const vmChildren = vm.renderMode === 0
|
|
6328
|
+
/* Light */
|
|
6329
|
+
? vm.elm.childNodes : vm.elm.shadowRoot.childNodes;
|
|
6330
|
+
hydrateChildrenHook(vmChildren, children, vm);
|
|
6331
|
+
runRenderedCallback(vm);
|
|
6332
|
+
}
|
|
6333
|
+
}
|
|
6334
|
+
|
|
5995
6335
|
function patchShadowRoot(vm, newCh) {
|
|
5996
6336
|
const {
|
|
5997
6337
|
children: oldCh
|
|
@@ -6802,27 +7142,11 @@ function readonly(obj) {
|
|
|
6802
7142
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
6803
7143
|
*/
|
|
6804
7144
|
let hooksAreSet = false;
|
|
6805
|
-
|
|
6806
|
-
function overrideHooks(hooks) {
|
|
6807
|
-
const oldHooks = {};
|
|
6808
|
-
|
|
6809
|
-
if (!isUndefined$1(hooks.sanitizeHtmlContent)) {
|
|
6810
|
-
oldHooks.sanitizeHtmlContent = setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
|
|
6811
|
-
}
|
|
6812
|
-
|
|
6813
|
-
return oldHooks;
|
|
6814
|
-
}
|
|
6815
|
-
|
|
6816
7145
|
function setHooks(hooks) {
|
|
6817
7146
|
assert.isFalse(hooksAreSet, 'Hooks are already overridden, only one definition is allowed.');
|
|
6818
|
-
overrideHooks(hooks);
|
|
6819
7147
|
hooksAreSet = true;
|
|
6820
|
-
|
|
6821
|
-
function setHooksForTest(hooks) {
|
|
6822
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
6823
|
-
return overrideHooks(hooks);
|
|
6824
|
-
}
|
|
7148
|
+
setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
|
|
6825
7149
|
}
|
|
6826
7150
|
|
|
6827
|
-
export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentInternalDef, getUpgradableConstructor, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks,
|
|
6828
|
-
/* version: 2.5.
|
|
7151
|
+
export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentInternalDef, getUpgradableConstructor, hydrateRootElement, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
|
|
7152
|
+
/* version: 2.5.10-alpha1 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lwc/engine-core",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.10-alpha1",
|
|
4
4
|
"description": "Core LWC engine APIs.",
|
|
5
5
|
"homepage": "https://lwc.dev/",
|
|
6
6
|
"repository": {
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"types/"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@lwc/features": "2.5.
|
|
28
|
-
"@lwc/shared": "2.5.
|
|
27
|
+
"@lwc/features": "2.5.10-alpha1",
|
|
28
|
+
"@lwc/shared": "2.5.10-alpha1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"observable-membrane": "1.
|
|
31
|
+
"observable-membrane": "1.1.5"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "b96b2d24f545c14a5c8984ab01081290afd5dc39"
|
|
37
37
|
}
|
|
@@ -74,6 +74,7 @@ export interface Hooks<N extends VNode> {
|
|
|
74
74
|
move: (vNode: N, parentNode: Node, referenceNode: Node | null) => void;
|
|
75
75
|
update: (oldVNode: N, vNode: N) => void;
|
|
76
76
|
remove: (vNode: N, parentNode: Node) => void;
|
|
77
|
+
hydrate: (vNode: N, node: Node) => void;
|
|
77
78
|
}
|
|
78
79
|
export interface Module<N extends VNode> {
|
|
79
80
|
create?: (vNode: N) => void;
|
package/types/framework/api.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare function i(iterable: Iterable<any>, factory: (value: any, index: number,
|
|
|
12
12
|
declare function f(items: any[]): any[];
|
|
13
13
|
declare function t(text: string): VText;
|
|
14
14
|
declare function co(text: string): VComment;
|
|
15
|
-
declare function d(value: any): string
|
|
15
|
+
declare function d(value: any): string;
|
|
16
16
|
declare function b(fn: EventListener): EventListener;
|
|
17
17
|
declare function k(compilerKey: number, obj: any): string | void;
|
|
18
18
|
declare function gid(id: string | undefined | null): string | null | undefined;
|
|
@@ -21,6 +21,11 @@ declare function fid(url: string | undefined | null): string | null | undefined;
|
|
|
21
21
|
* create a dynamic component via `<x-foo lwc:dynamic={Ctor}>`
|
|
22
22
|
*/
|
|
23
23
|
declare function dc(sel: string, Ctor: LightningElementConstructor | null | undefined, data: VElementData, children?: VNodes): VCustomElement | null;
|
|
24
|
+
export declare type SanitizeHtmlContentHook = (content: unknown) => string;
|
|
25
|
+
/**
|
|
26
|
+
* Sets the sanitizeHtmlContentHook.
|
|
27
|
+
*/
|
|
28
|
+
export declare function setSanitizeHtmlContentHook(newHookImpl: SanitizeHtmlContentHook): void;
|
|
24
29
|
declare function shc(content: unknown): string;
|
|
25
30
|
declare const api: Readonly<{
|
|
26
31
|
s: typeof s;
|
|
@@ -4,6 +4,10 @@ export declare function updateNodeHook(oldVnode: VNode, vnode: VNode): void;
|
|
|
4
4
|
export declare function insertNodeHook(vnode: VNode, parentNode: Node, referenceNode: Node | null): void;
|
|
5
5
|
export declare function removeNodeHook(vnode: VNode, parentNode: Node): void;
|
|
6
6
|
export declare function createElmHook(vnode: VElement): void;
|
|
7
|
+
export declare const enum LWCDOMMode {
|
|
8
|
+
manual = "manual"
|
|
9
|
+
}
|
|
10
|
+
export declare function hydrateElmHook(vnode: VElement): void;
|
|
7
11
|
export declare function fallbackElmHook(elm: Element, vnode: VElement): void;
|
|
8
12
|
export declare function updateElmHook(oldVnode: VElement, vnode: VElement): void;
|
|
9
13
|
export declare function updateChildrenHook(oldVnode: VElement, vnode: VElement): void;
|
|
@@ -11,6 +15,7 @@ export declare function allocateChildrenHook(vnode: VCustomElement, vm: VM): voi
|
|
|
11
15
|
export declare function createViewModelHook(elm: HTMLElement, vnode: VCustomElement): void;
|
|
12
16
|
export declare function createCustomElmHook(vnode: VCustomElement): void;
|
|
13
17
|
export declare function createChildrenHook(vnode: VElement): void;
|
|
18
|
+
export declare function hydrateChildrenHook(elmChildren: NodeListOf<ChildNode>, children: VNodes, vm?: VM): void;
|
|
14
19
|
export declare function updateCustomElmHook(oldVnode: VCustomElement, vnode: VCustomElement): void;
|
|
15
20
|
export declare function removeElmHook(vnode: VElement): void;
|
|
16
21
|
export declare function markAsDynamicChildren(children: VNodes): void;
|