@lwc/engine-core 8.12.3 → 8.12.5
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/LICENSE.md +1 -1
- package/dist/framework/hydration-utils.d.ts +10 -0
- package/dist/framework/sanitized-html-content.d.ts +1 -7
- package/dist/framework/utils.d.ts +1 -0
- package/dist/index.cjs.js +166 -113
- package/dist/index.js +166 -113
- package/package.json +4 -4
package/LICENSE.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MIT LICENSE
|
|
4
4
|
|
|
5
|
-
Copyright (c)
|
|
5
|
+
Copyright (c) 2025, Salesforce, Inc.
|
|
6
6
|
All rights reserved.
|
|
7
7
|
|
|
8
8
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Classes = Omit<Set<string>, 'add'>;
|
|
2
|
+
export declare function prettyPrintAttribute(attribute: string, value: any): string;
|
|
3
|
+
export declare function prettyPrintClasses(classes: Classes): string;
|
|
4
|
+
export declare function queueHydrationError(type: string, serverRendered?: any, clientExpected?: any): void;
|
|
5
|
+
export declare function flushHydrationErrors(source?: Node | null): void;
|
|
6
|
+
export declare function isTypeElement(node?: Node): node is Element;
|
|
7
|
+
export declare function isTypeText(node?: Node): node is Text;
|
|
8
|
+
export declare function isTypeComment(node?: Node): node is Comment;
|
|
9
|
+
export declare function logHydrationWarning(...args: any): void;
|
|
10
|
+
//# sourceMappingURL=hydration-utils.d.ts.map
|
|
@@ -3,6 +3,7 @@ declare const sanitizedHtmlContentSymbol: unique symbol;
|
|
|
3
3
|
export type SanitizedHtmlContent = {
|
|
4
4
|
[sanitizedHtmlContentSymbol]: unknown;
|
|
5
5
|
};
|
|
6
|
+
export declare function unwrapIfNecessary(object: any): any;
|
|
6
7
|
/**
|
|
7
8
|
* Wrap a pre-sanitized string designated for `.innerHTML` via `lwc:inner-html`
|
|
8
9
|
* as an object with a Symbol that only we have access to.
|
|
@@ -19,12 +20,5 @@ export declare function createSanitizedHtmlContent(sanitizedString: unknown): Sa
|
|
|
19
20
|
* @param value - value to set
|
|
20
21
|
*/
|
|
21
22
|
export declare function safelySetProperty(setProperty: RendererAPI['setProperty'], elm: Element, key: string, value: any): void;
|
|
22
|
-
/**
|
|
23
|
-
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
|
|
24
|
-
* string values are equivalent.
|
|
25
|
-
* @param first
|
|
26
|
-
* @param second
|
|
27
|
-
*/
|
|
28
|
-
export declare function isSanitizedHtmlContentEqual(first: any, second: any): boolean;
|
|
29
23
|
export {};
|
|
30
24
|
//# sourceMappingURL=sanitized-html-content.d.ts.map
|
|
@@ -12,5 +12,6 @@ export declare function cloneAndOmitKey(object: {
|
|
|
12
12
|
};
|
|
13
13
|
export declare function assertNotProd(): void;
|
|
14
14
|
export declare function shouldBeFormAssociated(Ctor: LightningElementConstructor): boolean;
|
|
15
|
+
export declare function safeHasProp<K extends PropertyKey>(obj: unknown, prop: K): obj is Record<K, unknown>;
|
|
15
16
|
export {};
|
|
16
17
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/index.cjs.js
CHANGED
|
@@ -251,6 +251,16 @@ function shouldBeFormAssociated(Ctor) {
|
|
|
251
251
|
}
|
|
252
252
|
return ctorFormAssociated && apiFeatureEnabled;
|
|
253
253
|
}
|
|
254
|
+
// check if a property is in an object, and if the object throws an error merely because we are
|
|
255
|
+
// checking if the property exists, return false
|
|
256
|
+
function safeHasProp(obj, prop) {
|
|
257
|
+
try {
|
|
258
|
+
return prop in obj;
|
|
259
|
+
}
|
|
260
|
+
catch (_err) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
254
264
|
|
|
255
265
|
/*
|
|
256
266
|
* Copyright (c) 2024, Salesforce, Inc.
|
|
@@ -591,14 +601,14 @@ function componentValueObserved(vm, key, target = {}) {
|
|
|
591
601
|
valueObserved(component, key);
|
|
592
602
|
}
|
|
593
603
|
// The portion of reactivity that's exposed to signals is to subscribe a callback to re-render the VM (templates).
|
|
594
|
-
// We check
|
|
604
|
+
// We check the following to ensure re-render is subscribed at the correct time.
|
|
595
605
|
// 1. The template is currently being rendered (there is a template reactive observer)
|
|
596
606
|
// 2. There was a call to a getter to access the signal (happens during vnode generation)
|
|
597
607
|
if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS &&
|
|
598
608
|
shared.isObject(target) &&
|
|
599
609
|
!shared.isNull(target) &&
|
|
600
|
-
'value'
|
|
601
|
-
'subscribe'
|
|
610
|
+
safeHasProp(target, 'value') &&
|
|
611
|
+
safeHasProp(target, 'subscribe') &&
|
|
602
612
|
shared.isFunction(target.subscribe) &&
|
|
603
613
|
shared.isTrustedSignal(target) &&
|
|
604
614
|
// Only subscribe if a template is being rendered by the engine
|
|
@@ -3967,15 +3977,6 @@ function safelySetProperty(setProperty, elm, key, value) {
|
|
|
3967
3977
|
setProperty(elm, key, value);
|
|
3968
3978
|
}
|
|
3969
3979
|
}
|
|
3970
|
-
/**
|
|
3971
|
-
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
|
|
3972
|
-
* string values are equivalent.
|
|
3973
|
-
* @param first
|
|
3974
|
-
* @param second
|
|
3975
|
-
*/
|
|
3976
|
-
function isSanitizedHtmlContentEqual(first, second) {
|
|
3977
|
-
return unwrapIfNecessary(first) === unwrapIfNecessary(second);
|
|
3978
|
-
}
|
|
3979
3980
|
|
|
3980
3981
|
/*
|
|
3981
3982
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -7528,6 +7529,78 @@ if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
|
|
|
7528
7529
|
}
|
|
7529
7530
|
}
|
|
7530
7531
|
|
|
7532
|
+
/*
|
|
7533
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
7534
|
+
* All rights reserved.
|
|
7535
|
+
* SPDX-License-Identifier: MIT
|
|
7536
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
7537
|
+
*/
|
|
7538
|
+
// Errors that occured during the hydration process
|
|
7539
|
+
let hydrationErrors = [];
|
|
7540
|
+
/*
|
|
7541
|
+
Prints attributes as null or "value"
|
|
7542
|
+
*/
|
|
7543
|
+
function prettyPrintAttribute(attribute, value) {
|
|
7544
|
+
assertNotProd(); // this method should never leak to prod
|
|
7545
|
+
return `${attribute}=${shared.isNull(value) || shared.isUndefined(value) ? value : `"${value}"`}`;
|
|
7546
|
+
}
|
|
7547
|
+
/*
|
|
7548
|
+
Sorts and stringifies classes
|
|
7549
|
+
*/
|
|
7550
|
+
function prettyPrintClasses(classes) {
|
|
7551
|
+
assertNotProd(); // this method should never leak to prod
|
|
7552
|
+
const value = JSON.stringify(shared.ArrayJoin.call(shared.ArraySort.call(shared.ArrayFrom(classes)), ' '));
|
|
7553
|
+
return `class=${value}`;
|
|
7554
|
+
}
|
|
7555
|
+
/*
|
|
7556
|
+
Hydration errors occur before the source node has been fully hydrated,
|
|
7557
|
+
queue them so they can be logged later against the mounted node.
|
|
7558
|
+
*/
|
|
7559
|
+
function queueHydrationError(type, serverRendered, clientExpected) {
|
|
7560
|
+
assertNotProd(); // this method should never leak to prod
|
|
7561
|
+
shared.ArrayPush.call(hydrationErrors, { type, serverRendered, clientExpected });
|
|
7562
|
+
}
|
|
7563
|
+
/*
|
|
7564
|
+
Flushes (logs) any queued errors after the source node has been mounted.
|
|
7565
|
+
*/
|
|
7566
|
+
function flushHydrationErrors(source) {
|
|
7567
|
+
assertNotProd(); // this method should never leak to prod
|
|
7568
|
+
for (const hydrationError of hydrationErrors) {
|
|
7569
|
+
logHydrationWarning(`Hydration ${hydrationError.type} mismatch on:`, source, `\n- rendered on server:`, hydrationError.serverRendered, `\n- expected on client:`, hydrationError.clientExpected || source);
|
|
7570
|
+
}
|
|
7571
|
+
hydrationErrors = [];
|
|
7572
|
+
}
|
|
7573
|
+
function isTypeElement(node) {
|
|
7574
|
+
const isCorrectType = node?.nodeType === 1 /* EnvNodeTypes.ELEMENT */;
|
|
7575
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7576
|
+
queueHydrationError('node', node);
|
|
7577
|
+
}
|
|
7578
|
+
return isCorrectType;
|
|
7579
|
+
}
|
|
7580
|
+
function isTypeText(node) {
|
|
7581
|
+
const isCorrectType = node?.nodeType === 3 /* EnvNodeTypes.TEXT */;
|
|
7582
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7583
|
+
queueHydrationError('node', node);
|
|
7584
|
+
}
|
|
7585
|
+
return isCorrectType;
|
|
7586
|
+
}
|
|
7587
|
+
function isTypeComment(node) {
|
|
7588
|
+
const isCorrectType = node?.nodeType === 8 /* EnvNodeTypes.COMMENT */;
|
|
7589
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7590
|
+
queueHydrationError('node', node);
|
|
7591
|
+
}
|
|
7592
|
+
return isCorrectType;
|
|
7593
|
+
}
|
|
7594
|
+
/*
|
|
7595
|
+
logger.ts converts all args to a string, losing object referenences and has
|
|
7596
|
+
legacy bloat which would have meant more pathing.
|
|
7597
|
+
*/
|
|
7598
|
+
function logHydrationWarning(...args) {
|
|
7599
|
+
assertNotProd(); // this method should never leak to prod
|
|
7600
|
+
/* eslint-disable-next-line no-console */
|
|
7601
|
+
console.warn('[LWC warn:', ...args);
|
|
7602
|
+
}
|
|
7603
|
+
|
|
7531
7604
|
/*
|
|
7532
7605
|
* Copyright (c) 2022, salesforce.com, inc.
|
|
7533
7606
|
* All rights reserved.
|
|
@@ -7542,8 +7615,15 @@ function hydrateRoot(vm) {
|
|
|
7542
7615
|
hasMismatch = false;
|
|
7543
7616
|
runConnectedCallback(vm);
|
|
7544
7617
|
hydrateVM(vm);
|
|
7545
|
-
if (
|
|
7546
|
-
|
|
7618
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7619
|
+
/*
|
|
7620
|
+
Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
|
|
7621
|
+
Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
|
|
7622
|
+
*/
|
|
7623
|
+
flushHydrationErrors(vm.renderRoot);
|
|
7624
|
+
if (hasMismatch) {
|
|
7625
|
+
logHydrationWarning('Hydration completed with errors.');
|
|
7626
|
+
}
|
|
7547
7627
|
}
|
|
7548
7628
|
}
|
|
7549
7629
|
function hydrateVM(vm) {
|
|
@@ -7581,21 +7661,25 @@ function hydrateNode(node, vnode, renderer) {
|
|
|
7581
7661
|
hydratedNode = hydrateCustomElement(node, vnode, vnode.data.renderer ?? renderer);
|
|
7582
7662
|
break;
|
|
7583
7663
|
}
|
|
7664
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7665
|
+
/*
|
|
7666
|
+
Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
|
|
7667
|
+
Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
|
|
7668
|
+
*/
|
|
7669
|
+
flushHydrationErrors(hydratedNode);
|
|
7670
|
+
}
|
|
7584
7671
|
return renderer.nextSibling(hydratedNode);
|
|
7585
7672
|
}
|
|
7586
7673
|
const NODE_VALUE_PROP = 'nodeValue';
|
|
7587
|
-
function
|
|
7674
|
+
function validateTextNodeEquality(node, vnode, renderer) {
|
|
7588
7675
|
const { getProperty } = renderer;
|
|
7589
7676
|
const nodeValue = getProperty(node, NODE_VALUE_PROP);
|
|
7590
|
-
if (nodeValue
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
if (nodeValue === '\u200D' && vnode.text === '') {
|
|
7596
|
-
return true;
|
|
7677
|
+
if (nodeValue !== vnode.text &&
|
|
7678
|
+
// Special case for empty text nodes – these are serialized differently on the server
|
|
7679
|
+
// See https://github.com/salesforce/lwc/pull/2656
|
|
7680
|
+
(nodeValue !== '\u200D' || vnode.text !== '')) {
|
|
7681
|
+
queueHydrationError('text content', nodeValue, vnode.text);
|
|
7597
7682
|
}
|
|
7598
|
-
return false;
|
|
7599
7683
|
}
|
|
7600
7684
|
// The validationOptOut static property can be an array of attribute names.
|
|
7601
7685
|
// Any attribute names specified in that array will not be validated, and the
|
|
@@ -7618,7 +7702,7 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
|
|
|
7618
7702
|
!shared.isUndefined(optOutStaticProp) &&
|
|
7619
7703
|
!shared.isTrue(optOutStaticProp) &&
|
|
7620
7704
|
!isValidArray) {
|
|
7621
|
-
|
|
7705
|
+
logHydrationWarning('`validationOptOut` must be `true` or an array of attributes that should not be validated.');
|
|
7622
7706
|
}
|
|
7623
7707
|
return (attrName) => {
|
|
7624
7708
|
// Component wants to opt out of all validation
|
|
@@ -7638,16 +7722,14 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
|
|
|
7638
7722
|
};
|
|
7639
7723
|
}
|
|
7640
7724
|
function hydrateText(node, vnode, renderer) {
|
|
7641
|
-
if (!
|
|
7725
|
+
if (!isTypeText(node)) {
|
|
7642
7726
|
return handleMismatch(node, vnode, renderer);
|
|
7643
7727
|
}
|
|
7644
|
-
return updateTextContent(node, vnode,
|
|
7728
|
+
return updateTextContent(node, vnode, renderer);
|
|
7645
7729
|
}
|
|
7646
|
-
function updateTextContent(node, vnode,
|
|
7730
|
+
function updateTextContent(node, vnode, renderer) {
|
|
7647
7731
|
if (process.env.NODE_ENV !== 'production') {
|
|
7648
|
-
|
|
7649
|
-
logWarn('Hydration mismatch: text values do not match, will recover from the difference', owner);
|
|
7650
|
-
}
|
|
7732
|
+
validateTextNodeEquality(node, vnode, renderer);
|
|
7651
7733
|
}
|
|
7652
7734
|
const { setText } = renderer;
|
|
7653
7735
|
setText(node, vnode.text ?? null);
|
|
@@ -7655,14 +7737,14 @@ function updateTextContent(node, vnode, owner, renderer) {
|
|
|
7655
7737
|
return node;
|
|
7656
7738
|
}
|
|
7657
7739
|
function hydrateComment(node, vnode, renderer) {
|
|
7658
|
-
if (!
|
|
7740
|
+
if (!isTypeComment(node)) {
|
|
7659
7741
|
return handleMismatch(node, vnode, renderer);
|
|
7660
7742
|
}
|
|
7661
7743
|
if (process.env.NODE_ENV !== 'production') {
|
|
7662
7744
|
const { getProperty } = renderer;
|
|
7663
7745
|
const nodeValue = getProperty(node, NODE_VALUE_PROP);
|
|
7664
7746
|
if (nodeValue !== vnode.text) {
|
|
7665
|
-
|
|
7747
|
+
queueHydrationError('comment', nodeValue, vnode.text);
|
|
7666
7748
|
}
|
|
7667
7749
|
}
|
|
7668
7750
|
const { setProperty } = renderer;
|
|
@@ -7673,11 +7755,12 @@ function hydrateComment(node, vnode, renderer) {
|
|
|
7673
7755
|
return node;
|
|
7674
7756
|
}
|
|
7675
7757
|
function hydrateStaticElement(elm, vnode, renderer) {
|
|
7676
|
-
if (
|
|
7677
|
-
|
|
7678
|
-
|
|
7758
|
+
if (isTypeElement(elm) &&
|
|
7759
|
+
isTypeElement(vnode.fragment) &&
|
|
7760
|
+
areStaticElementsCompatible(vnode.fragment, elm, vnode, renderer)) {
|
|
7761
|
+
return hydrateStaticElementParts(elm, vnode, renderer);
|
|
7679
7762
|
}
|
|
7680
|
-
return
|
|
7763
|
+
return handleMismatch(elm, vnode, renderer);
|
|
7681
7764
|
}
|
|
7682
7765
|
function hydrateStaticElementParts(elm, vnode, renderer) {
|
|
7683
7766
|
const { parts } = vnode;
|
|
@@ -7700,8 +7783,7 @@ function hydrateFragment(elm, vnode, renderer) {
|
|
|
7700
7783
|
return (vnode.elm = children[children.length - 1].elm);
|
|
7701
7784
|
}
|
|
7702
7785
|
function hydrateElement(elm, vnode, renderer) {
|
|
7703
|
-
if (!
|
|
7704
|
-
!isMatchingElement(vnode, elm, renderer)) {
|
|
7786
|
+
if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer)) {
|
|
7705
7787
|
return handleMismatch(elm, vnode, renderer);
|
|
7706
7788
|
}
|
|
7707
7789
|
vnode.elm = elm;
|
|
@@ -7714,17 +7796,17 @@ function hydrateElement(elm, vnode, renderer) {
|
|
|
7714
7796
|
const { data: { props }, } = vnode;
|
|
7715
7797
|
const { getProperty } = renderer;
|
|
7716
7798
|
if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
|
|
7717
|
-
|
|
7799
|
+
const unwrappedServerInnerHTML = unwrapIfNecessary(getProperty(elm, 'innerHTML'));
|
|
7800
|
+
const unwrappedClientInnerHTML = unwrapIfNecessary(props.innerHTML);
|
|
7801
|
+
if (unwrappedServerInnerHTML === unwrappedClientInnerHTML) {
|
|
7718
7802
|
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
7719
7803
|
vnode.data = {
|
|
7720
7804
|
...vnode.data,
|
|
7721
7805
|
props: cloneAndOmitKey(props, 'innerHTML'),
|
|
7722
7806
|
};
|
|
7723
7807
|
}
|
|
7724
|
-
else {
|
|
7725
|
-
|
|
7726
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, owner);
|
|
7727
|
-
}
|
|
7808
|
+
else if (process.env.NODE_ENV !== 'production') {
|
|
7809
|
+
queueHydrationError('innerHTML', unwrappedServerInnerHTML, unwrappedClientInnerHTML);
|
|
7728
7810
|
}
|
|
7729
7811
|
}
|
|
7730
7812
|
}
|
|
@@ -7747,8 +7829,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
7747
7829
|
//
|
|
7748
7830
|
// Therefore, if validationOptOut is falsey or an array of strings, we need to
|
|
7749
7831
|
// examine some or all of the custom element's attributes.
|
|
7750
|
-
if (!
|
|
7751
|
-
!isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
|
|
7832
|
+
if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
|
|
7752
7833
|
return handleMismatch(elm, vnode, renderer);
|
|
7753
7834
|
}
|
|
7754
7835
|
const { sel, mode, ctor, owner } = vnode;
|
|
@@ -7784,9 +7865,13 @@ function hydrateChildren(node, children, parentNode, owner,
|
|
|
7784
7865
|
// last node of the fragment. Hydration should not fail if a trailing sibling is
|
|
7785
7866
|
// found in this case.
|
|
7786
7867
|
expectAddlSiblings) {
|
|
7787
|
-
let
|
|
7868
|
+
let mismatchedChildren = false;
|
|
7788
7869
|
let nextNode = node;
|
|
7789
7870
|
const { renderer } = owner;
|
|
7871
|
+
const { getChildNodes, cloneNode } = renderer;
|
|
7872
|
+
const serverNodes = process.env.NODE_ENV !== 'production'
|
|
7873
|
+
? Array.from(getChildNodes(parentNode), (node) => cloneNode(node, true))
|
|
7874
|
+
: null;
|
|
7790
7875
|
for (let i = 0; i < children.length; i++) {
|
|
7791
7876
|
const childVnode = children[i];
|
|
7792
7877
|
if (!shared.isNull(childVnode)) {
|
|
@@ -7794,13 +7879,7 @@ expectAddlSiblings) {
|
|
|
7794
7879
|
nextNode = hydrateNode(nextNode, childVnode, renderer);
|
|
7795
7880
|
}
|
|
7796
7881
|
else {
|
|
7797
|
-
|
|
7798
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7799
|
-
if (!hasWarned) {
|
|
7800
|
-
hasWarned = true;
|
|
7801
|
-
logWarn(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
|
|
7802
|
-
}
|
|
7803
|
-
}
|
|
7882
|
+
mismatchedChildren = true;
|
|
7804
7883
|
mount(childVnode, parentNode, renderer, nextNode);
|
|
7805
7884
|
nextNode = renderer.nextSibling(childVnode.type === 5 /* VNodeType.Fragment */ ? childVnode.trailing : childVnode.elm);
|
|
7806
7885
|
}
|
|
@@ -7817,12 +7896,7 @@ expectAddlSiblings) {
|
|
|
7817
7896
|
// rendered more nodes than the client.
|
|
7818
7897
|
(!useCommentsForBookends || !expectAddlSiblings) &&
|
|
7819
7898
|
nextNode) {
|
|
7820
|
-
|
|
7821
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7822
|
-
if (!hasWarned) {
|
|
7823
|
-
logWarn(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
|
|
7824
|
-
}
|
|
7825
|
-
}
|
|
7899
|
+
mismatchedChildren = true;
|
|
7826
7900
|
// nextSibling is mostly harmless, and since we don't have
|
|
7827
7901
|
// a good reference to what element to act upon, we instead
|
|
7828
7902
|
// rely on the vm's associated renderer for navigating to the
|
|
@@ -7834,6 +7908,14 @@ expectAddlSiblings) {
|
|
|
7834
7908
|
removeNode(current, parentNode, renderer);
|
|
7835
7909
|
} while (nextNode);
|
|
7836
7910
|
}
|
|
7911
|
+
if (mismatchedChildren) {
|
|
7912
|
+
hasMismatch = true;
|
|
7913
|
+
// We can't know exactly which node(s) caused the delta, but we can provide context (parent) and the mismatched sets
|
|
7914
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7915
|
+
const clientNodes = shared.ArrayMap.call(children, (c) => c?.elm);
|
|
7916
|
+
queueHydrationError('child node', serverNodes, clientNodes);
|
|
7917
|
+
}
|
|
7918
|
+
}
|
|
7837
7919
|
}
|
|
7838
7920
|
function handleMismatch(node, vnode, renderer) {
|
|
7839
7921
|
hasMismatch = true;
|
|
@@ -7849,31 +7931,21 @@ function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
|
|
|
7849
7931
|
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
7850
7932
|
applyRefs(vnode, vnode.owner);
|
|
7851
7933
|
}
|
|
7852
|
-
function hasCorrectNodeType(vnode, node, nodeType, renderer) {
|
|
7853
|
-
const { getProperty } = renderer;
|
|
7854
|
-
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
7855
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7856
|
-
logWarn('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
7857
|
-
}
|
|
7858
|
-
return false;
|
|
7859
|
-
}
|
|
7860
|
-
return true;
|
|
7861
|
-
}
|
|
7862
7934
|
function isMatchingElement(vnode, elm, renderer, shouldValidateAttr = () => true) {
|
|
7863
7935
|
const { getProperty } = renderer;
|
|
7864
7936
|
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
7865
7937
|
if (process.env.NODE_ENV !== 'production') {
|
|
7866
|
-
|
|
7938
|
+
queueHydrationError('node', elm);
|
|
7867
7939
|
}
|
|
7868
7940
|
return false;
|
|
7869
7941
|
}
|
|
7870
7942
|
const { data } = vnode;
|
|
7871
|
-
const hasCompatibleAttrs = validateAttrs(
|
|
7943
|
+
const hasCompatibleAttrs = validateAttrs(elm, data, renderer, shouldValidateAttr);
|
|
7872
7944
|
const hasCompatibleClass = shouldValidateAttr('class')
|
|
7873
7945
|
? validateClassAttr(vnode, elm, data, renderer)
|
|
7874
7946
|
: true;
|
|
7875
7947
|
const hasCompatibleStyle = shouldValidateAttr('style')
|
|
7876
|
-
? validateStyleAttr(
|
|
7948
|
+
? validateStyleAttr(elm, data, renderer)
|
|
7877
7949
|
: true;
|
|
7878
7950
|
return hasCompatibleAttrs && hasCompatibleClass && hasCompatibleStyle;
|
|
7879
7951
|
}
|
|
@@ -7890,7 +7962,7 @@ function attributeValuesAreEqual(vnodeValue, value) {
|
|
|
7890
7962
|
// In all other cases, the two values are not considered equal
|
|
7891
7963
|
return false;
|
|
7892
7964
|
}
|
|
7893
|
-
function validateAttrs(
|
|
7965
|
+
function validateAttrs(elm, data, renderer, shouldValidateAttr) {
|
|
7894
7966
|
const { attrs = {} } = data;
|
|
7895
7967
|
let nodesAreCompatible = true;
|
|
7896
7968
|
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
@@ -7903,8 +7975,7 @@ function validateAttrs(vnode, elm, data, renderer, shouldValidateAttr) {
|
|
|
7903
7975
|
const elmAttrValue = getAttribute(elm, attrName);
|
|
7904
7976
|
if (!attributeValuesAreEqual(attrValue, elmAttrValue)) {
|
|
7905
7977
|
if (process.env.NODE_ENV !== 'production') {
|
|
7906
|
-
|
|
7907
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found ${shared.isNull(elmAttrValue) ? 'null' : `"${elmAttrValue}"`}`, vnode.owner);
|
|
7978
|
+
queueHydrationError('attribute', prettyPrintAttribute(attrName, elmAttrValue), prettyPrintAttribute(attrName, attrValue));
|
|
7908
7979
|
}
|
|
7909
7980
|
nodesAreCompatible = false;
|
|
7910
7981
|
}
|
|
@@ -7932,7 +8003,6 @@ function validateClassAttr(vnode, elm, data, renderer) {
|
|
|
7932
8003
|
// classMap is never available on VStaticPartData so it can default to undefined
|
|
7933
8004
|
// casting to prevent TS error.
|
|
7934
8005
|
const { className, classMap } = data;
|
|
7935
|
-
const { getProperty } = renderer;
|
|
7936
8006
|
// ---------- Step 1: get the classes from the element and the vnode
|
|
7937
8007
|
// Use a Set because we don't care to validate mismatches for 1) different ordering in SSR vs CSR, or 2)
|
|
7938
8008
|
// duplicated class names. These don't have an effect on rendered styles.
|
|
@@ -7978,12 +8048,11 @@ function validateClassAttr(vnode, elm, data, renderer) {
|
|
|
7978
8048
|
// ---------- Step 3: check for compatibility
|
|
7979
8049
|
const classesAreCompatible = checkClassesCompatibility(vnodeClasses, elmClasses);
|
|
7980
8050
|
if (process.env.NODE_ENV !== 'production' && !classesAreCompatible) {
|
|
7981
|
-
|
|
7982
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected ${prettyPrint(vnodeClasses)} but found ${prettyPrint(elmClasses)}`, vnode.owner);
|
|
8051
|
+
queueHydrationError('attribute', prettyPrintClasses(elmClasses), prettyPrintClasses(vnodeClasses));
|
|
7983
8052
|
}
|
|
7984
8053
|
return classesAreCompatible;
|
|
7985
8054
|
}
|
|
7986
|
-
function validateStyleAttr(
|
|
8055
|
+
function validateStyleAttr(elm, data, renderer) {
|
|
7987
8056
|
// Note styleDecls is always undefined for VStaticPartData, casting here to default it to undefined
|
|
7988
8057
|
const { style, styleDecls } = data;
|
|
7989
8058
|
const { getAttribute } = renderer;
|
|
@@ -8017,49 +8086,33 @@ function validateStyleAttr(vnode, elm, data, renderer) {
|
|
|
8017
8086
|
}
|
|
8018
8087
|
vnodeStyle = shared.ArrayJoin.call(expectedStyle, ' ');
|
|
8019
8088
|
}
|
|
8020
|
-
if (!nodesAreCompatible) {
|
|
8021
|
-
|
|
8022
|
-
const { getProperty } = renderer;
|
|
8023
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
8024
|
-
}
|
|
8089
|
+
if (process.env.NODE_ENV !== 'production' && !nodesAreCompatible) {
|
|
8090
|
+
queueHydrationError('attribute', prettyPrintAttribute('style', elmStyle), prettyPrintAttribute('style', vnodeStyle));
|
|
8025
8091
|
}
|
|
8026
8092
|
return nodesAreCompatible;
|
|
8027
8093
|
}
|
|
8028
|
-
function
|
|
8094
|
+
function areStaticElementsCompatible(clientElement, serverElement, vnode, renderer) {
|
|
8029
8095
|
const { getProperty, getAttribute } = renderer;
|
|
8030
|
-
|
|
8031
|
-
if (!hasCorrectNodeType(vnode, ssr, 3 /* EnvNodeTypes.TEXT */, renderer)) {
|
|
8032
|
-
return false;
|
|
8033
|
-
}
|
|
8034
|
-
return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
|
|
8035
|
-
}
|
|
8036
|
-
if (getProperty(client, 'nodeType') === 8 /* EnvNodeTypes.COMMENT */) {
|
|
8037
|
-
if (!hasCorrectNodeType(vnode, ssr, 8 /* EnvNodeTypes.COMMENT */, renderer)) {
|
|
8038
|
-
return false;
|
|
8039
|
-
}
|
|
8040
|
-
return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
|
|
8041
|
-
}
|
|
8042
|
-
if (!hasCorrectNodeType(vnode, ssr, 1 /* EnvNodeTypes.ELEMENT */, renderer)) {
|
|
8043
|
-
return false;
|
|
8044
|
-
}
|
|
8045
|
-
const { owner, parts } = vnode;
|
|
8096
|
+
const { parts } = vnode;
|
|
8046
8097
|
let isCompatibleElements = true;
|
|
8047
|
-
if (getProperty(
|
|
8098
|
+
if (getProperty(clientElement, 'tagName') !== getProperty(serverElement, 'tagName')) {
|
|
8048
8099
|
if (process.env.NODE_ENV !== 'production') {
|
|
8049
|
-
|
|
8100
|
+
queueHydrationError('node', serverElement);
|
|
8050
8101
|
}
|
|
8051
8102
|
return false;
|
|
8052
8103
|
}
|
|
8053
|
-
const clientAttrsNames = getProperty(
|
|
8104
|
+
const clientAttrsNames = getProperty(clientElement, 'getAttributeNames').call(clientElement);
|
|
8054
8105
|
clientAttrsNames.forEach((attrName) => {
|
|
8055
|
-
|
|
8106
|
+
const clientAttributeValue = getAttribute(clientElement, attrName);
|
|
8107
|
+
const serverAttributeValue = getAttribute(serverElement, attrName);
|
|
8108
|
+
if (clientAttributeValue !== serverAttributeValue) {
|
|
8056
8109
|
// Check if the root element attributes have expressions, if it does then we need to delegate hydration
|
|
8057
8110
|
// validation to haveCompatibleStaticParts.
|
|
8058
8111
|
// Note if there are no parts then it is a fully static fragment.
|
|
8059
8112
|
// partId === 0 will always refer to the root element, this is guaranteed by the compiler.
|
|
8060
8113
|
if (parts?.[0].partId !== 0) {
|
|
8061
8114
|
if (process.env.NODE_ENV !== 'production') {
|
|
8062
|
-
|
|
8115
|
+
queueHydrationError('attribute', prettyPrintAttribute(attrName, serverAttributeValue), prettyPrintAttribute(attrName, clientAttributeValue));
|
|
8063
8116
|
}
|
|
8064
8117
|
isCompatibleElements = false;
|
|
8065
8118
|
}
|
|
@@ -8068,7 +8121,7 @@ function areCompatibleStaticNodes(client, ssr, vnode, renderer) {
|
|
|
8068
8121
|
return isCompatibleElements;
|
|
8069
8122
|
}
|
|
8070
8123
|
function haveCompatibleStaticParts(vnode, renderer) {
|
|
8071
|
-
const { parts
|
|
8124
|
+
const { parts } = vnode;
|
|
8072
8125
|
if (shared.isUndefined(parts)) {
|
|
8073
8126
|
return true;
|
|
8074
8127
|
}
|
|
@@ -8079,11 +8132,11 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8079
8132
|
for (const part of parts) {
|
|
8080
8133
|
const { elm } = part;
|
|
8081
8134
|
if (isVStaticPartElement(part)) {
|
|
8082
|
-
if (!
|
|
8135
|
+
if (!isTypeElement(elm)) {
|
|
8083
8136
|
return false;
|
|
8084
8137
|
}
|
|
8085
8138
|
const { data } = part;
|
|
8086
|
-
const hasMatchingAttrs = validateAttrs(
|
|
8139
|
+
const hasMatchingAttrs = validateAttrs(elm, data, renderer, () => true);
|
|
8087
8140
|
// Explicitly skip hydration validation when static parts don't contain `style` or `className`.
|
|
8088
8141
|
// This means the style/class attributes are either static or don't exist on the element and
|
|
8089
8142
|
// cannot be affected by hydration.
|
|
@@ -8093,7 +8146,7 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8093
8146
|
? validateClassAttr(vnode, elm, data, renderer)
|
|
8094
8147
|
: true;
|
|
8095
8148
|
const hasMatchingStyleAttr = shouldValidateAttr(data, 'style')
|
|
8096
|
-
? validateStyleAttr(
|
|
8149
|
+
? validateStyleAttr(elm, data, renderer)
|
|
8097
8150
|
: true;
|
|
8098
8151
|
if (shared.isFalse(hasMatchingAttrs && hasMatchingClass && hasMatchingStyleAttr)) {
|
|
8099
8152
|
return false;
|
|
@@ -8101,10 +8154,10 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8101
8154
|
}
|
|
8102
8155
|
else {
|
|
8103
8156
|
// VStaticPartText
|
|
8104
|
-
if (!
|
|
8157
|
+
if (!isTypeText(elm)) {
|
|
8105
8158
|
return false;
|
|
8106
8159
|
}
|
|
8107
|
-
updateTextContent(elm, part,
|
|
8160
|
+
updateTextContent(elm, part, renderer);
|
|
8108
8161
|
}
|
|
8109
8162
|
}
|
|
8110
8163
|
return true;
|
|
@@ -8421,5 +8474,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
8421
8474
|
exports.track = track;
|
|
8422
8475
|
exports.unwrap = unwrap;
|
|
8423
8476
|
exports.wire = wire;
|
|
8424
|
-
/** version: 8.12.
|
|
8477
|
+
/** version: 8.12.5 */
|
|
8425
8478
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.js
CHANGED
|
@@ -248,6 +248,16 @@ function shouldBeFormAssociated(Ctor) {
|
|
|
248
248
|
}
|
|
249
249
|
return ctorFormAssociated && apiFeatureEnabled;
|
|
250
250
|
}
|
|
251
|
+
// check if a property is in an object, and if the object throws an error merely because we are
|
|
252
|
+
// checking if the property exists, return false
|
|
253
|
+
function safeHasProp(obj, prop) {
|
|
254
|
+
try {
|
|
255
|
+
return prop in obj;
|
|
256
|
+
}
|
|
257
|
+
catch (_err) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
251
261
|
|
|
252
262
|
/*
|
|
253
263
|
* Copyright (c) 2024, Salesforce, Inc.
|
|
@@ -588,14 +598,14 @@ function componentValueObserved(vm, key, target = {}) {
|
|
|
588
598
|
valueObserved(component, key);
|
|
589
599
|
}
|
|
590
600
|
// The portion of reactivity that's exposed to signals is to subscribe a callback to re-render the VM (templates).
|
|
591
|
-
// We check
|
|
601
|
+
// We check the following to ensure re-render is subscribed at the correct time.
|
|
592
602
|
// 1. The template is currently being rendered (there is a template reactive observer)
|
|
593
603
|
// 2. There was a call to a getter to access the signal (happens during vnode generation)
|
|
594
604
|
if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS &&
|
|
595
605
|
isObject(target) &&
|
|
596
606
|
!isNull(target) &&
|
|
597
|
-
'value'
|
|
598
|
-
'subscribe'
|
|
607
|
+
safeHasProp(target, 'value') &&
|
|
608
|
+
safeHasProp(target, 'subscribe') &&
|
|
599
609
|
isFunction$1(target.subscribe) &&
|
|
600
610
|
isTrustedSignal(target) &&
|
|
601
611
|
// Only subscribe if a template is being rendered by the engine
|
|
@@ -3964,15 +3974,6 @@ function safelySetProperty(setProperty, elm, key, value) {
|
|
|
3964
3974
|
setProperty(elm, key, value);
|
|
3965
3975
|
}
|
|
3966
3976
|
}
|
|
3967
|
-
/**
|
|
3968
|
-
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
|
|
3969
|
-
* string values are equivalent.
|
|
3970
|
-
* @param first
|
|
3971
|
-
* @param second
|
|
3972
|
-
*/
|
|
3973
|
-
function isSanitizedHtmlContentEqual(first, second) {
|
|
3974
|
-
return unwrapIfNecessary(first) === unwrapIfNecessary(second);
|
|
3975
|
-
}
|
|
3976
3977
|
|
|
3977
3978
|
/*
|
|
3978
3979
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -7525,6 +7526,78 @@ if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
|
|
|
7525
7526
|
}
|
|
7526
7527
|
}
|
|
7527
7528
|
|
|
7529
|
+
/*
|
|
7530
|
+
* Copyright (c) 2024, Salesforce, Inc.
|
|
7531
|
+
* All rights reserved.
|
|
7532
|
+
* SPDX-License-Identifier: MIT
|
|
7533
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
7534
|
+
*/
|
|
7535
|
+
// Errors that occured during the hydration process
|
|
7536
|
+
let hydrationErrors = [];
|
|
7537
|
+
/*
|
|
7538
|
+
Prints attributes as null or "value"
|
|
7539
|
+
*/
|
|
7540
|
+
function prettyPrintAttribute(attribute, value) {
|
|
7541
|
+
assertNotProd(); // this method should never leak to prod
|
|
7542
|
+
return `${attribute}=${isNull(value) || isUndefined$1(value) ? value : `"${value}"`}`;
|
|
7543
|
+
}
|
|
7544
|
+
/*
|
|
7545
|
+
Sorts and stringifies classes
|
|
7546
|
+
*/
|
|
7547
|
+
function prettyPrintClasses(classes) {
|
|
7548
|
+
assertNotProd(); // this method should never leak to prod
|
|
7549
|
+
const value = JSON.stringify(ArrayJoin.call(ArraySort.call(ArrayFrom(classes)), ' '));
|
|
7550
|
+
return `class=${value}`;
|
|
7551
|
+
}
|
|
7552
|
+
/*
|
|
7553
|
+
Hydration errors occur before the source node has been fully hydrated,
|
|
7554
|
+
queue them so they can be logged later against the mounted node.
|
|
7555
|
+
*/
|
|
7556
|
+
function queueHydrationError(type, serverRendered, clientExpected) {
|
|
7557
|
+
assertNotProd(); // this method should never leak to prod
|
|
7558
|
+
ArrayPush$1.call(hydrationErrors, { type, serverRendered, clientExpected });
|
|
7559
|
+
}
|
|
7560
|
+
/*
|
|
7561
|
+
Flushes (logs) any queued errors after the source node has been mounted.
|
|
7562
|
+
*/
|
|
7563
|
+
function flushHydrationErrors(source) {
|
|
7564
|
+
assertNotProd(); // this method should never leak to prod
|
|
7565
|
+
for (const hydrationError of hydrationErrors) {
|
|
7566
|
+
logHydrationWarning(`Hydration ${hydrationError.type} mismatch on:`, source, `\n- rendered on server:`, hydrationError.serverRendered, `\n- expected on client:`, hydrationError.clientExpected || source);
|
|
7567
|
+
}
|
|
7568
|
+
hydrationErrors = [];
|
|
7569
|
+
}
|
|
7570
|
+
function isTypeElement(node) {
|
|
7571
|
+
const isCorrectType = node?.nodeType === 1 /* EnvNodeTypes.ELEMENT */;
|
|
7572
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7573
|
+
queueHydrationError('node', node);
|
|
7574
|
+
}
|
|
7575
|
+
return isCorrectType;
|
|
7576
|
+
}
|
|
7577
|
+
function isTypeText(node) {
|
|
7578
|
+
const isCorrectType = node?.nodeType === 3 /* EnvNodeTypes.TEXT */;
|
|
7579
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7580
|
+
queueHydrationError('node', node);
|
|
7581
|
+
}
|
|
7582
|
+
return isCorrectType;
|
|
7583
|
+
}
|
|
7584
|
+
function isTypeComment(node) {
|
|
7585
|
+
const isCorrectType = node?.nodeType === 8 /* EnvNodeTypes.COMMENT */;
|
|
7586
|
+
if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
|
|
7587
|
+
queueHydrationError('node', node);
|
|
7588
|
+
}
|
|
7589
|
+
return isCorrectType;
|
|
7590
|
+
}
|
|
7591
|
+
/*
|
|
7592
|
+
logger.ts converts all args to a string, losing object referenences and has
|
|
7593
|
+
legacy bloat which would have meant more pathing.
|
|
7594
|
+
*/
|
|
7595
|
+
function logHydrationWarning(...args) {
|
|
7596
|
+
assertNotProd(); // this method should never leak to prod
|
|
7597
|
+
/* eslint-disable-next-line no-console */
|
|
7598
|
+
console.warn('[LWC warn:', ...args);
|
|
7599
|
+
}
|
|
7600
|
+
|
|
7528
7601
|
/*
|
|
7529
7602
|
* Copyright (c) 2022, salesforce.com, inc.
|
|
7530
7603
|
* All rights reserved.
|
|
@@ -7539,8 +7612,15 @@ function hydrateRoot(vm) {
|
|
|
7539
7612
|
hasMismatch = false;
|
|
7540
7613
|
runConnectedCallback(vm);
|
|
7541
7614
|
hydrateVM(vm);
|
|
7542
|
-
if (
|
|
7543
|
-
|
|
7615
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7616
|
+
/*
|
|
7617
|
+
Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
|
|
7618
|
+
Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
|
|
7619
|
+
*/
|
|
7620
|
+
flushHydrationErrors(vm.renderRoot);
|
|
7621
|
+
if (hasMismatch) {
|
|
7622
|
+
logHydrationWarning('Hydration completed with errors.');
|
|
7623
|
+
}
|
|
7544
7624
|
}
|
|
7545
7625
|
}
|
|
7546
7626
|
function hydrateVM(vm) {
|
|
@@ -7578,21 +7658,25 @@ function hydrateNode(node, vnode, renderer) {
|
|
|
7578
7658
|
hydratedNode = hydrateCustomElement(node, vnode, vnode.data.renderer ?? renderer);
|
|
7579
7659
|
break;
|
|
7580
7660
|
}
|
|
7661
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7662
|
+
/*
|
|
7663
|
+
Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
|
|
7664
|
+
Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
|
|
7665
|
+
*/
|
|
7666
|
+
flushHydrationErrors(hydratedNode);
|
|
7667
|
+
}
|
|
7581
7668
|
return renderer.nextSibling(hydratedNode);
|
|
7582
7669
|
}
|
|
7583
7670
|
const NODE_VALUE_PROP = 'nodeValue';
|
|
7584
|
-
function
|
|
7671
|
+
function validateTextNodeEquality(node, vnode, renderer) {
|
|
7585
7672
|
const { getProperty } = renderer;
|
|
7586
7673
|
const nodeValue = getProperty(node, NODE_VALUE_PROP);
|
|
7587
|
-
if (nodeValue
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
if (nodeValue === '\u200D' && vnode.text === '') {
|
|
7593
|
-
return true;
|
|
7674
|
+
if (nodeValue !== vnode.text &&
|
|
7675
|
+
// Special case for empty text nodes – these are serialized differently on the server
|
|
7676
|
+
// See https://github.com/salesforce/lwc/pull/2656
|
|
7677
|
+
(nodeValue !== '\u200D' || vnode.text !== '')) {
|
|
7678
|
+
queueHydrationError('text content', nodeValue, vnode.text);
|
|
7594
7679
|
}
|
|
7595
|
-
return false;
|
|
7596
7680
|
}
|
|
7597
7681
|
// The validationOptOut static property can be an array of attribute names.
|
|
7598
7682
|
// Any attribute names specified in that array will not be validated, and the
|
|
@@ -7615,7 +7699,7 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
|
|
|
7615
7699
|
!isUndefined$1(optOutStaticProp) &&
|
|
7616
7700
|
!isTrue(optOutStaticProp) &&
|
|
7617
7701
|
!isValidArray) {
|
|
7618
|
-
|
|
7702
|
+
logHydrationWarning('`validationOptOut` must be `true` or an array of attributes that should not be validated.');
|
|
7619
7703
|
}
|
|
7620
7704
|
return (attrName) => {
|
|
7621
7705
|
// Component wants to opt out of all validation
|
|
@@ -7635,16 +7719,14 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
|
|
|
7635
7719
|
};
|
|
7636
7720
|
}
|
|
7637
7721
|
function hydrateText(node, vnode, renderer) {
|
|
7638
|
-
if (!
|
|
7722
|
+
if (!isTypeText(node)) {
|
|
7639
7723
|
return handleMismatch(node, vnode, renderer);
|
|
7640
7724
|
}
|
|
7641
|
-
return updateTextContent(node, vnode,
|
|
7725
|
+
return updateTextContent(node, vnode, renderer);
|
|
7642
7726
|
}
|
|
7643
|
-
function updateTextContent(node, vnode,
|
|
7727
|
+
function updateTextContent(node, vnode, renderer) {
|
|
7644
7728
|
if (process.env.NODE_ENV !== 'production') {
|
|
7645
|
-
|
|
7646
|
-
logWarn('Hydration mismatch: text values do not match, will recover from the difference', owner);
|
|
7647
|
-
}
|
|
7729
|
+
validateTextNodeEquality(node, vnode, renderer);
|
|
7648
7730
|
}
|
|
7649
7731
|
const { setText } = renderer;
|
|
7650
7732
|
setText(node, vnode.text ?? null);
|
|
@@ -7652,14 +7734,14 @@ function updateTextContent(node, vnode, owner, renderer) {
|
|
|
7652
7734
|
return node;
|
|
7653
7735
|
}
|
|
7654
7736
|
function hydrateComment(node, vnode, renderer) {
|
|
7655
|
-
if (!
|
|
7737
|
+
if (!isTypeComment(node)) {
|
|
7656
7738
|
return handleMismatch(node, vnode, renderer);
|
|
7657
7739
|
}
|
|
7658
7740
|
if (process.env.NODE_ENV !== 'production') {
|
|
7659
7741
|
const { getProperty } = renderer;
|
|
7660
7742
|
const nodeValue = getProperty(node, NODE_VALUE_PROP);
|
|
7661
7743
|
if (nodeValue !== vnode.text) {
|
|
7662
|
-
|
|
7744
|
+
queueHydrationError('comment', nodeValue, vnode.text);
|
|
7663
7745
|
}
|
|
7664
7746
|
}
|
|
7665
7747
|
const { setProperty } = renderer;
|
|
@@ -7670,11 +7752,12 @@ function hydrateComment(node, vnode, renderer) {
|
|
|
7670
7752
|
return node;
|
|
7671
7753
|
}
|
|
7672
7754
|
function hydrateStaticElement(elm, vnode, renderer) {
|
|
7673
|
-
if (
|
|
7674
|
-
|
|
7675
|
-
|
|
7755
|
+
if (isTypeElement(elm) &&
|
|
7756
|
+
isTypeElement(vnode.fragment) &&
|
|
7757
|
+
areStaticElementsCompatible(vnode.fragment, elm, vnode, renderer)) {
|
|
7758
|
+
return hydrateStaticElementParts(elm, vnode, renderer);
|
|
7676
7759
|
}
|
|
7677
|
-
return
|
|
7760
|
+
return handleMismatch(elm, vnode, renderer);
|
|
7678
7761
|
}
|
|
7679
7762
|
function hydrateStaticElementParts(elm, vnode, renderer) {
|
|
7680
7763
|
const { parts } = vnode;
|
|
@@ -7697,8 +7780,7 @@ function hydrateFragment(elm, vnode, renderer) {
|
|
|
7697
7780
|
return (vnode.elm = children[children.length - 1].elm);
|
|
7698
7781
|
}
|
|
7699
7782
|
function hydrateElement(elm, vnode, renderer) {
|
|
7700
|
-
if (!
|
|
7701
|
-
!isMatchingElement(vnode, elm, renderer)) {
|
|
7783
|
+
if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer)) {
|
|
7702
7784
|
return handleMismatch(elm, vnode, renderer);
|
|
7703
7785
|
}
|
|
7704
7786
|
vnode.elm = elm;
|
|
@@ -7711,17 +7793,17 @@ function hydrateElement(elm, vnode, renderer) {
|
|
|
7711
7793
|
const { data: { props }, } = vnode;
|
|
7712
7794
|
const { getProperty } = renderer;
|
|
7713
7795
|
if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
|
|
7714
|
-
|
|
7796
|
+
const unwrappedServerInnerHTML = unwrapIfNecessary(getProperty(elm, 'innerHTML'));
|
|
7797
|
+
const unwrappedClientInnerHTML = unwrapIfNecessary(props.innerHTML);
|
|
7798
|
+
if (unwrappedServerInnerHTML === unwrappedClientInnerHTML) {
|
|
7715
7799
|
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
7716
7800
|
vnode.data = {
|
|
7717
7801
|
...vnode.data,
|
|
7718
7802
|
props: cloneAndOmitKey(props, 'innerHTML'),
|
|
7719
7803
|
};
|
|
7720
7804
|
}
|
|
7721
|
-
else {
|
|
7722
|
-
|
|
7723
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, owner);
|
|
7724
|
-
}
|
|
7805
|
+
else if (process.env.NODE_ENV !== 'production') {
|
|
7806
|
+
queueHydrationError('innerHTML', unwrappedServerInnerHTML, unwrappedClientInnerHTML);
|
|
7725
7807
|
}
|
|
7726
7808
|
}
|
|
7727
7809
|
}
|
|
@@ -7744,8 +7826,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
|
|
|
7744
7826
|
//
|
|
7745
7827
|
// Therefore, if validationOptOut is falsey or an array of strings, we need to
|
|
7746
7828
|
// examine some or all of the custom element's attributes.
|
|
7747
|
-
if (!
|
|
7748
|
-
!isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
|
|
7829
|
+
if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
|
|
7749
7830
|
return handleMismatch(elm, vnode, renderer);
|
|
7750
7831
|
}
|
|
7751
7832
|
const { sel, mode, ctor, owner } = vnode;
|
|
@@ -7781,9 +7862,13 @@ function hydrateChildren(node, children, parentNode, owner,
|
|
|
7781
7862
|
// last node of the fragment. Hydration should not fail if a trailing sibling is
|
|
7782
7863
|
// found in this case.
|
|
7783
7864
|
expectAddlSiblings) {
|
|
7784
|
-
let
|
|
7865
|
+
let mismatchedChildren = false;
|
|
7785
7866
|
let nextNode = node;
|
|
7786
7867
|
const { renderer } = owner;
|
|
7868
|
+
const { getChildNodes, cloneNode } = renderer;
|
|
7869
|
+
const serverNodes = process.env.NODE_ENV !== 'production'
|
|
7870
|
+
? Array.from(getChildNodes(parentNode), (node) => cloneNode(node, true))
|
|
7871
|
+
: null;
|
|
7787
7872
|
for (let i = 0; i < children.length; i++) {
|
|
7788
7873
|
const childVnode = children[i];
|
|
7789
7874
|
if (!isNull(childVnode)) {
|
|
@@ -7791,13 +7876,7 @@ expectAddlSiblings) {
|
|
|
7791
7876
|
nextNode = hydrateNode(nextNode, childVnode, renderer);
|
|
7792
7877
|
}
|
|
7793
7878
|
else {
|
|
7794
|
-
|
|
7795
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7796
|
-
if (!hasWarned) {
|
|
7797
|
-
hasWarned = true;
|
|
7798
|
-
logWarn(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
|
|
7799
|
-
}
|
|
7800
|
-
}
|
|
7879
|
+
mismatchedChildren = true;
|
|
7801
7880
|
mount(childVnode, parentNode, renderer, nextNode);
|
|
7802
7881
|
nextNode = renderer.nextSibling(childVnode.type === 5 /* VNodeType.Fragment */ ? childVnode.trailing : childVnode.elm);
|
|
7803
7882
|
}
|
|
@@ -7814,12 +7893,7 @@ expectAddlSiblings) {
|
|
|
7814
7893
|
// rendered more nodes than the client.
|
|
7815
7894
|
(!useCommentsForBookends || !expectAddlSiblings) &&
|
|
7816
7895
|
nextNode) {
|
|
7817
|
-
|
|
7818
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7819
|
-
if (!hasWarned) {
|
|
7820
|
-
logWarn(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
|
|
7821
|
-
}
|
|
7822
|
-
}
|
|
7896
|
+
mismatchedChildren = true;
|
|
7823
7897
|
// nextSibling is mostly harmless, and since we don't have
|
|
7824
7898
|
// a good reference to what element to act upon, we instead
|
|
7825
7899
|
// rely on the vm's associated renderer for navigating to the
|
|
@@ -7831,6 +7905,14 @@ expectAddlSiblings) {
|
|
|
7831
7905
|
removeNode(current, parentNode, renderer);
|
|
7832
7906
|
} while (nextNode);
|
|
7833
7907
|
}
|
|
7908
|
+
if (mismatchedChildren) {
|
|
7909
|
+
hasMismatch = true;
|
|
7910
|
+
// We can't know exactly which node(s) caused the delta, but we can provide context (parent) and the mismatched sets
|
|
7911
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7912
|
+
const clientNodes = ArrayMap.call(children, (c) => c?.elm);
|
|
7913
|
+
queueHydrationError('child node', serverNodes, clientNodes);
|
|
7914
|
+
}
|
|
7915
|
+
}
|
|
7834
7916
|
}
|
|
7835
7917
|
function handleMismatch(node, vnode, renderer) {
|
|
7836
7918
|
hasMismatch = true;
|
|
@@ -7846,31 +7928,21 @@ function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
|
|
|
7846
7928
|
// The `refs` object is blown away in every re-render, so we always need to re-apply them
|
|
7847
7929
|
applyRefs(vnode, vnode.owner);
|
|
7848
7930
|
}
|
|
7849
|
-
function hasCorrectNodeType(vnode, node, nodeType, renderer) {
|
|
7850
|
-
const { getProperty } = renderer;
|
|
7851
|
-
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
7852
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
7853
|
-
logWarn('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
7854
|
-
}
|
|
7855
|
-
return false;
|
|
7856
|
-
}
|
|
7857
|
-
return true;
|
|
7858
|
-
}
|
|
7859
7931
|
function isMatchingElement(vnode, elm, renderer, shouldValidateAttr = () => true) {
|
|
7860
7932
|
const { getProperty } = renderer;
|
|
7861
7933
|
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
7862
7934
|
if (process.env.NODE_ENV !== 'production') {
|
|
7863
|
-
|
|
7935
|
+
queueHydrationError('node', elm);
|
|
7864
7936
|
}
|
|
7865
7937
|
return false;
|
|
7866
7938
|
}
|
|
7867
7939
|
const { data } = vnode;
|
|
7868
|
-
const hasCompatibleAttrs = validateAttrs(
|
|
7940
|
+
const hasCompatibleAttrs = validateAttrs(elm, data, renderer, shouldValidateAttr);
|
|
7869
7941
|
const hasCompatibleClass = shouldValidateAttr('class')
|
|
7870
7942
|
? validateClassAttr(vnode, elm, data, renderer)
|
|
7871
7943
|
: true;
|
|
7872
7944
|
const hasCompatibleStyle = shouldValidateAttr('style')
|
|
7873
|
-
? validateStyleAttr(
|
|
7945
|
+
? validateStyleAttr(elm, data, renderer)
|
|
7874
7946
|
: true;
|
|
7875
7947
|
return hasCompatibleAttrs && hasCompatibleClass && hasCompatibleStyle;
|
|
7876
7948
|
}
|
|
@@ -7887,7 +7959,7 @@ function attributeValuesAreEqual(vnodeValue, value) {
|
|
|
7887
7959
|
// In all other cases, the two values are not considered equal
|
|
7888
7960
|
return false;
|
|
7889
7961
|
}
|
|
7890
|
-
function validateAttrs(
|
|
7962
|
+
function validateAttrs(elm, data, renderer, shouldValidateAttr) {
|
|
7891
7963
|
const { attrs = {} } = data;
|
|
7892
7964
|
let nodesAreCompatible = true;
|
|
7893
7965
|
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
@@ -7900,8 +7972,7 @@ function validateAttrs(vnode, elm, data, renderer, shouldValidateAttr) {
|
|
|
7900
7972
|
const elmAttrValue = getAttribute(elm, attrName);
|
|
7901
7973
|
if (!attributeValuesAreEqual(attrValue, elmAttrValue)) {
|
|
7902
7974
|
if (process.env.NODE_ENV !== 'production') {
|
|
7903
|
-
|
|
7904
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found ${isNull(elmAttrValue) ? 'null' : `"${elmAttrValue}"`}`, vnode.owner);
|
|
7975
|
+
queueHydrationError('attribute', prettyPrintAttribute(attrName, elmAttrValue), prettyPrintAttribute(attrName, attrValue));
|
|
7905
7976
|
}
|
|
7906
7977
|
nodesAreCompatible = false;
|
|
7907
7978
|
}
|
|
@@ -7929,7 +8000,6 @@ function validateClassAttr(vnode, elm, data, renderer) {
|
|
|
7929
8000
|
// classMap is never available on VStaticPartData so it can default to undefined
|
|
7930
8001
|
// casting to prevent TS error.
|
|
7931
8002
|
const { className, classMap } = data;
|
|
7932
|
-
const { getProperty } = renderer;
|
|
7933
8003
|
// ---------- Step 1: get the classes from the element and the vnode
|
|
7934
8004
|
// Use a Set because we don't care to validate mismatches for 1) different ordering in SSR vs CSR, or 2)
|
|
7935
8005
|
// duplicated class names. These don't have an effect on rendered styles.
|
|
@@ -7975,12 +8045,11 @@ function validateClassAttr(vnode, elm, data, renderer) {
|
|
|
7975
8045
|
// ---------- Step 3: check for compatibility
|
|
7976
8046
|
const classesAreCompatible = checkClassesCompatibility(vnodeClasses, elmClasses);
|
|
7977
8047
|
if (process.env.NODE_ENV !== 'production' && !classesAreCompatible) {
|
|
7978
|
-
|
|
7979
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected ${prettyPrint(vnodeClasses)} but found ${prettyPrint(elmClasses)}`, vnode.owner);
|
|
8048
|
+
queueHydrationError('attribute', prettyPrintClasses(elmClasses), prettyPrintClasses(vnodeClasses));
|
|
7980
8049
|
}
|
|
7981
8050
|
return classesAreCompatible;
|
|
7982
8051
|
}
|
|
7983
|
-
function validateStyleAttr(
|
|
8052
|
+
function validateStyleAttr(elm, data, renderer) {
|
|
7984
8053
|
// Note styleDecls is always undefined for VStaticPartData, casting here to default it to undefined
|
|
7985
8054
|
const { style, styleDecls } = data;
|
|
7986
8055
|
const { getAttribute } = renderer;
|
|
@@ -8014,49 +8083,33 @@ function validateStyleAttr(vnode, elm, data, renderer) {
|
|
|
8014
8083
|
}
|
|
8015
8084
|
vnodeStyle = ArrayJoin.call(expectedStyle, ' ');
|
|
8016
8085
|
}
|
|
8017
|
-
if (!nodesAreCompatible) {
|
|
8018
|
-
|
|
8019
|
-
const { getProperty } = renderer;
|
|
8020
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
8021
|
-
}
|
|
8086
|
+
if (process.env.NODE_ENV !== 'production' && !nodesAreCompatible) {
|
|
8087
|
+
queueHydrationError('attribute', prettyPrintAttribute('style', elmStyle), prettyPrintAttribute('style', vnodeStyle));
|
|
8022
8088
|
}
|
|
8023
8089
|
return nodesAreCompatible;
|
|
8024
8090
|
}
|
|
8025
|
-
function
|
|
8091
|
+
function areStaticElementsCompatible(clientElement, serverElement, vnode, renderer) {
|
|
8026
8092
|
const { getProperty, getAttribute } = renderer;
|
|
8027
|
-
|
|
8028
|
-
if (!hasCorrectNodeType(vnode, ssr, 3 /* EnvNodeTypes.TEXT */, renderer)) {
|
|
8029
|
-
return false;
|
|
8030
|
-
}
|
|
8031
|
-
return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
|
|
8032
|
-
}
|
|
8033
|
-
if (getProperty(client, 'nodeType') === 8 /* EnvNodeTypes.COMMENT */) {
|
|
8034
|
-
if (!hasCorrectNodeType(vnode, ssr, 8 /* EnvNodeTypes.COMMENT */, renderer)) {
|
|
8035
|
-
return false;
|
|
8036
|
-
}
|
|
8037
|
-
return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
|
|
8038
|
-
}
|
|
8039
|
-
if (!hasCorrectNodeType(vnode, ssr, 1 /* EnvNodeTypes.ELEMENT */, renderer)) {
|
|
8040
|
-
return false;
|
|
8041
|
-
}
|
|
8042
|
-
const { owner, parts } = vnode;
|
|
8093
|
+
const { parts } = vnode;
|
|
8043
8094
|
let isCompatibleElements = true;
|
|
8044
|
-
if (getProperty(
|
|
8095
|
+
if (getProperty(clientElement, 'tagName') !== getProperty(serverElement, 'tagName')) {
|
|
8045
8096
|
if (process.env.NODE_ENV !== 'production') {
|
|
8046
|
-
|
|
8097
|
+
queueHydrationError('node', serverElement);
|
|
8047
8098
|
}
|
|
8048
8099
|
return false;
|
|
8049
8100
|
}
|
|
8050
|
-
const clientAttrsNames = getProperty(
|
|
8101
|
+
const clientAttrsNames = getProperty(clientElement, 'getAttributeNames').call(clientElement);
|
|
8051
8102
|
clientAttrsNames.forEach((attrName) => {
|
|
8052
|
-
|
|
8103
|
+
const clientAttributeValue = getAttribute(clientElement, attrName);
|
|
8104
|
+
const serverAttributeValue = getAttribute(serverElement, attrName);
|
|
8105
|
+
if (clientAttributeValue !== serverAttributeValue) {
|
|
8053
8106
|
// Check if the root element attributes have expressions, if it does then we need to delegate hydration
|
|
8054
8107
|
// validation to haveCompatibleStaticParts.
|
|
8055
8108
|
// Note if there are no parts then it is a fully static fragment.
|
|
8056
8109
|
// partId === 0 will always refer to the root element, this is guaranteed by the compiler.
|
|
8057
8110
|
if (parts?.[0].partId !== 0) {
|
|
8058
8111
|
if (process.env.NODE_ENV !== 'production') {
|
|
8059
|
-
|
|
8112
|
+
queueHydrationError('attribute', prettyPrintAttribute(attrName, serverAttributeValue), prettyPrintAttribute(attrName, clientAttributeValue));
|
|
8060
8113
|
}
|
|
8061
8114
|
isCompatibleElements = false;
|
|
8062
8115
|
}
|
|
@@ -8065,7 +8118,7 @@ function areCompatibleStaticNodes(client, ssr, vnode, renderer) {
|
|
|
8065
8118
|
return isCompatibleElements;
|
|
8066
8119
|
}
|
|
8067
8120
|
function haveCompatibleStaticParts(vnode, renderer) {
|
|
8068
|
-
const { parts
|
|
8121
|
+
const { parts } = vnode;
|
|
8069
8122
|
if (isUndefined$1(parts)) {
|
|
8070
8123
|
return true;
|
|
8071
8124
|
}
|
|
@@ -8076,11 +8129,11 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8076
8129
|
for (const part of parts) {
|
|
8077
8130
|
const { elm } = part;
|
|
8078
8131
|
if (isVStaticPartElement(part)) {
|
|
8079
|
-
if (!
|
|
8132
|
+
if (!isTypeElement(elm)) {
|
|
8080
8133
|
return false;
|
|
8081
8134
|
}
|
|
8082
8135
|
const { data } = part;
|
|
8083
|
-
const hasMatchingAttrs = validateAttrs(
|
|
8136
|
+
const hasMatchingAttrs = validateAttrs(elm, data, renderer, () => true);
|
|
8084
8137
|
// Explicitly skip hydration validation when static parts don't contain `style` or `className`.
|
|
8085
8138
|
// This means the style/class attributes are either static or don't exist on the element and
|
|
8086
8139
|
// cannot be affected by hydration.
|
|
@@ -8090,7 +8143,7 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8090
8143
|
? validateClassAttr(vnode, elm, data, renderer)
|
|
8091
8144
|
: true;
|
|
8092
8145
|
const hasMatchingStyleAttr = shouldValidateAttr(data, 'style')
|
|
8093
|
-
? validateStyleAttr(
|
|
8146
|
+
? validateStyleAttr(elm, data, renderer)
|
|
8094
8147
|
: true;
|
|
8095
8148
|
if (isFalse(hasMatchingAttrs && hasMatchingClass && hasMatchingStyleAttr)) {
|
|
8096
8149
|
return false;
|
|
@@ -8098,10 +8151,10 @@ function haveCompatibleStaticParts(vnode, renderer) {
|
|
|
8098
8151
|
}
|
|
8099
8152
|
else {
|
|
8100
8153
|
// VStaticPartText
|
|
8101
|
-
if (!
|
|
8154
|
+
if (!isTypeText(elm)) {
|
|
8102
8155
|
return false;
|
|
8103
8156
|
}
|
|
8104
|
-
updateTextContent(elm, part,
|
|
8157
|
+
updateTextContent(elm, part, renderer);
|
|
8105
8158
|
}
|
|
8106
8159
|
}
|
|
8107
8160
|
return true;
|
|
@@ -8367,5 +8420,5 @@ function readonly(obj) {
|
|
|
8367
8420
|
}
|
|
8368
8421
|
|
|
8369
8422
|
export { BaseBridgeElement, LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, computeShadowAndRenderMode, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, runFormAssociatedCallback, runFormDisabledCallback, runFormResetCallback, runFormStateRestoreCallback, sanitizeAttribute, shouldBeFormAssociated, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
|
|
8370
|
-
/** version: 8.12.
|
|
8423
|
+
/** version: 8.12.5 */
|
|
8371
8424
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten."
|
|
5
5
|
],
|
|
6
6
|
"name": "@lwc/engine-core",
|
|
7
|
-
"version": "8.12.
|
|
7
|
+
"version": "8.12.5",
|
|
8
8
|
"description": "Core LWC engine APIs.",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"lwc"
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lwc/features": "8.12.
|
|
50
|
-
"@lwc/shared": "8.12.
|
|
51
|
-
"@lwc/signals": "8.12.
|
|
49
|
+
"@lwc/features": "8.12.5",
|
|
50
|
+
"@lwc/shared": "8.12.5",
|
|
51
|
+
"@lwc/signals": "8.12.5"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"observable-membrane": "2.0.0"
|