@lwc/engine-core 2.11.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine-core.cjs.js +302 -257
- package/dist/engine-core.js +303 -258
- package/package.json +6 -6
- package/types/framework/component.d.ts +2 -2
- package/types/framework/hydration.d.ts +1 -2
- package/types/framework/main.d.ts +2 -1
- package/types/framework/rendering.d.ts +3 -1
- package/types/framework/vm.d.ts +1 -2
package/dist/engine-core.cjs.js
CHANGED
|
@@ -4705,11 +4705,15 @@ const signedTemplateMap = new Map();
|
|
|
4705
4705
|
* INTERNAL: This function can only be invoked by compiled code. The compiler
|
|
4706
4706
|
* will prevent this function from being imported by userland code.
|
|
4707
4707
|
*/
|
|
4708
|
-
function registerComponent(
|
|
4709
|
-
|
|
4710
|
-
|
|
4708
|
+
function registerComponent(
|
|
4709
|
+
// We typically expect a LightningElementConstructor, but technically you can call this with anything
|
|
4710
|
+
Ctor, { tmpl }) {
|
|
4711
|
+
if (shared.isFunction(Ctor)) {
|
|
4712
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4713
|
+
checkVersionMismatch(Ctor, 'component');
|
|
4714
|
+
}
|
|
4715
|
+
signedTemplateMap.set(Ctor, tmpl);
|
|
4711
4716
|
}
|
|
4712
|
-
signedTemplateMap.set(Ctor, tmpl);
|
|
4713
4717
|
// chaining this method as a way to wrap existing assignment of component constructor easily,
|
|
4714
4718
|
// without too much transformation
|
|
4715
4719
|
return Ctor;
|
|
@@ -4798,236 +4802,6 @@ function invokeServiceHook(vm, cbs) {
|
|
|
4798
4802
|
}
|
|
4799
4803
|
}
|
|
4800
4804
|
|
|
4801
|
-
/*
|
|
4802
|
-
* Copyright (c) 2022, salesforce.com, inc.
|
|
4803
|
-
* All rights reserved.
|
|
4804
|
-
* SPDX-License-Identifier: MIT
|
|
4805
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4806
|
-
*/
|
|
4807
|
-
function hydrate(vnode, node) {
|
|
4808
|
-
switch (vnode.type) {
|
|
4809
|
-
case 0 /* Text */:
|
|
4810
|
-
hydrateText(vnode, node);
|
|
4811
|
-
break;
|
|
4812
|
-
case 1 /* Comment */:
|
|
4813
|
-
hydrateComment(vnode, node);
|
|
4814
|
-
break;
|
|
4815
|
-
case 2 /* Element */:
|
|
4816
|
-
hydrateElement(vnode, node);
|
|
4817
|
-
break;
|
|
4818
|
-
case 3 /* CustomElement */:
|
|
4819
|
-
hydrateCustomElement(vnode, node);
|
|
4820
|
-
break;
|
|
4821
|
-
}
|
|
4822
|
-
}
|
|
4823
|
-
function hydrateText(vnode, node) {
|
|
4824
|
-
var _a;
|
|
4825
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4826
|
-
validateNodeType(vnode, node, 3 /* TEXT */);
|
|
4827
|
-
const nodeValue = getProperty(node, 'nodeValue');
|
|
4828
|
-
if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
|
|
4829
|
-
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
|
|
4830
|
-
}
|
|
4831
|
-
}
|
|
4832
|
-
// always set the text value to the one from the vnode.
|
|
4833
|
-
setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
4834
|
-
vnode.elm = node;
|
|
4835
|
-
}
|
|
4836
|
-
function hydrateComment(vnode, node) {
|
|
4837
|
-
var _a;
|
|
4838
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4839
|
-
validateNodeType(vnode, node, 8 /* COMMENT */);
|
|
4840
|
-
if (getProperty(node, 'nodeValue') !== vnode.text) {
|
|
4841
|
-
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
|
|
4842
|
-
}
|
|
4843
|
-
}
|
|
4844
|
-
// always set the text value to the one from the vnode.
|
|
4845
|
-
setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
4846
|
-
vnode.elm = node;
|
|
4847
|
-
}
|
|
4848
|
-
function hydrateElement(vnode, node) {
|
|
4849
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4850
|
-
validateNodeType(vnode, node, 1 /* ELEMENT */);
|
|
4851
|
-
validateElement(vnode, node);
|
|
4852
|
-
}
|
|
4853
|
-
const elm = node;
|
|
4854
|
-
vnode.elm = elm;
|
|
4855
|
-
const { context } = vnode.data;
|
|
4856
|
-
const isDomManual = Boolean(!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual" /* Manual */);
|
|
4857
|
-
if (isDomManual) {
|
|
4858
|
-
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
4859
|
-
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
4860
|
-
const { props } = vnode.data;
|
|
4861
|
-
if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
|
|
4862
|
-
if (getProperty(elm, 'innerHTML') === props.innerHTML) {
|
|
4863
|
-
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
4864
|
-
vnode.data = Object.assign(Object.assign({}, vnode.data), { props: cloneAndOmitKey(props, 'innerHTML') });
|
|
4865
|
-
}
|
|
4866
|
-
else {
|
|
4867
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
4868
|
-
}
|
|
4869
|
-
}
|
|
4870
|
-
}
|
|
4871
|
-
patchElementPropsAndAttrs(vnode);
|
|
4872
|
-
if (!isDomManual) {
|
|
4873
|
-
hydrateChildren(getChildNodes(vnode.elm), vnode.children, vnode.owner);
|
|
4874
|
-
}
|
|
4875
|
-
}
|
|
4876
|
-
function hydrateCustomElement(vnode, node) {
|
|
4877
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4878
|
-
validateNodeType(vnode, node, 1 /* ELEMENT */);
|
|
4879
|
-
validateElement(vnode, node);
|
|
4880
|
-
}
|
|
4881
|
-
const elm = node;
|
|
4882
|
-
const { sel, mode, ctor, owner } = vnode;
|
|
4883
|
-
const vm = createVM(elm, ctor, {
|
|
4884
|
-
mode,
|
|
4885
|
-
owner,
|
|
4886
|
-
tagName: sel,
|
|
4887
|
-
});
|
|
4888
|
-
vnode.elm = elm;
|
|
4889
|
-
vnode.vm = vm;
|
|
4890
|
-
allocateChildren(vnode, vm);
|
|
4891
|
-
patchElementPropsAndAttrs(vnode);
|
|
4892
|
-
// Insert hook section:
|
|
4893
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4894
|
-
shared.assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
|
|
4895
|
-
}
|
|
4896
|
-
runConnectedCallback(vm);
|
|
4897
|
-
if (vm.renderMode !== 0 /* Light */) {
|
|
4898
|
-
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
4899
|
-
// Note: for Light DOM, this is handled while hydrating the VM
|
|
4900
|
-
hydrateChildren(getChildNodes(vnode.elm), vnode.children, vm);
|
|
4901
|
-
}
|
|
4902
|
-
hydrateVM(vm);
|
|
4903
|
-
}
|
|
4904
|
-
function hydrateChildren(elmChildren, children, vm) {
|
|
4905
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4906
|
-
const filteredVNodes = shared.ArrayFilter.call(children, (vnode) => !!vnode);
|
|
4907
|
-
if (elmChildren.length !== filteredVNodes.length) {
|
|
4908
|
-
logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
|
|
4909
|
-
throwHydrationError();
|
|
4910
|
-
}
|
|
4911
|
-
}
|
|
4912
|
-
let childNodeIndex = 0;
|
|
4913
|
-
for (let i = 0; i < children.length; i++) {
|
|
4914
|
-
const childVnode = children[i];
|
|
4915
|
-
if (!shared.isNull(childVnode)) {
|
|
4916
|
-
const childNode = elmChildren[childNodeIndex];
|
|
4917
|
-
hydrate(childVnode, childNode);
|
|
4918
|
-
childNodeIndex++;
|
|
4919
|
-
}
|
|
4920
|
-
}
|
|
4921
|
-
}
|
|
4922
|
-
function patchElementPropsAndAttrs(vnode) {
|
|
4923
|
-
applyEventListeners(vnode);
|
|
4924
|
-
patchProps(null, vnode);
|
|
4925
|
-
}
|
|
4926
|
-
function throwHydrationError() {
|
|
4927
|
-
shared.assert.fail('Server rendered elements do not match client side generated elements');
|
|
4928
|
-
}
|
|
4929
|
-
function validateNodeType(vnode, node, nodeType) {
|
|
4930
|
-
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
4931
|
-
logError('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
4932
|
-
shared.assert.fail('Hydration mismatch: incorrect node type received.');
|
|
4933
|
-
}
|
|
4934
|
-
}
|
|
4935
|
-
function validateElement(vnode, elm) {
|
|
4936
|
-
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
4937
|
-
logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
|
|
4938
|
-
throwHydrationError();
|
|
4939
|
-
}
|
|
4940
|
-
const hasIncompatibleAttrs = validateAttrs(vnode, elm);
|
|
4941
|
-
const hasIncompatibleClass = validateClassAttr(vnode, elm);
|
|
4942
|
-
const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
|
|
4943
|
-
const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
4944
|
-
if (!isVNodeAndElementCompatible) {
|
|
4945
|
-
throwHydrationError();
|
|
4946
|
-
}
|
|
4947
|
-
}
|
|
4948
|
-
function validateAttrs(vnode, elm) {
|
|
4949
|
-
const { data: { attrs = {} }, } = vnode;
|
|
4950
|
-
let nodesAreCompatible = true;
|
|
4951
|
-
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
4952
|
-
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
4953
|
-
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
4954
|
-
const elmAttrValue = getAttribute(elm, attrName);
|
|
4955
|
-
if (String(attrValue) !== elmAttrValue) {
|
|
4956
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
4957
|
-
nodesAreCompatible = false;
|
|
4958
|
-
}
|
|
4959
|
-
}
|
|
4960
|
-
return nodesAreCompatible;
|
|
4961
|
-
}
|
|
4962
|
-
function validateClassAttr(vnode, elm) {
|
|
4963
|
-
const { data: { className, classMap }, } = vnode;
|
|
4964
|
-
let nodesAreCompatible = true;
|
|
4965
|
-
let vnodeClassName;
|
|
4966
|
-
if (!shared.isUndefined(className) && String(className) !== getProperty(elm, 'className')) {
|
|
4967
|
-
// className is used when class is bound to an expr.
|
|
4968
|
-
nodesAreCompatible = false;
|
|
4969
|
-
vnodeClassName = className;
|
|
4970
|
-
}
|
|
4971
|
-
else if (!shared.isUndefined(classMap)) {
|
|
4972
|
-
// classMap is used when class is set to static value.
|
|
4973
|
-
const classList = getClassList(elm);
|
|
4974
|
-
let computedClassName = '';
|
|
4975
|
-
// all classes from the vnode should be in the element.classList
|
|
4976
|
-
for (const name in classMap) {
|
|
4977
|
-
computedClassName += ' ' + name;
|
|
4978
|
-
if (!classList.contains(name)) {
|
|
4979
|
-
nodesAreCompatible = false;
|
|
4980
|
-
}
|
|
4981
|
-
}
|
|
4982
|
-
vnodeClassName = computedClassName.trim();
|
|
4983
|
-
if (classList.length > shared.keys(classMap).length) {
|
|
4984
|
-
nodesAreCompatible = false;
|
|
4985
|
-
}
|
|
4986
|
-
}
|
|
4987
|
-
if (!nodesAreCompatible) {
|
|
4988
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${getProperty(elm, 'className')}"`, vnode.owner);
|
|
4989
|
-
}
|
|
4990
|
-
return nodesAreCompatible;
|
|
4991
|
-
}
|
|
4992
|
-
function validateStyleAttr(vnode, elm) {
|
|
4993
|
-
const { data: { style, styleDecls }, } = vnode;
|
|
4994
|
-
const elmStyle = getAttribute(elm, 'style') || '';
|
|
4995
|
-
let vnodeStyle;
|
|
4996
|
-
let nodesAreCompatible = true;
|
|
4997
|
-
if (!shared.isUndefined(style) && style !== elmStyle) {
|
|
4998
|
-
nodesAreCompatible = false;
|
|
4999
|
-
vnodeStyle = style;
|
|
5000
|
-
}
|
|
5001
|
-
else if (!shared.isUndefined(styleDecls)) {
|
|
5002
|
-
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
5003
|
-
const expectedStyle = [];
|
|
5004
|
-
// styleMap is used when style is set to static value.
|
|
5005
|
-
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
5006
|
-
const [prop, value, important] = styleDecls[i];
|
|
5007
|
-
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
5008
|
-
const parsedPropValue = parsedVnodeStyle[prop];
|
|
5009
|
-
if (shared.isUndefined(parsedPropValue)) {
|
|
5010
|
-
nodesAreCompatible = false;
|
|
5011
|
-
}
|
|
5012
|
-
else if (!parsedPropValue.startsWith(value)) {
|
|
5013
|
-
nodesAreCompatible = false;
|
|
5014
|
-
}
|
|
5015
|
-
else if (important && !parsedPropValue.endsWith('!important')) {
|
|
5016
|
-
nodesAreCompatible = false;
|
|
5017
|
-
}
|
|
5018
|
-
}
|
|
5019
|
-
if (shared.keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
5020
|
-
nodesAreCompatible = false;
|
|
5021
|
-
}
|
|
5022
|
-
vnodeStyle = shared.ArrayJoin.call(expectedStyle, ';');
|
|
5023
|
-
}
|
|
5024
|
-
if (!nodesAreCompatible) {
|
|
5025
|
-
// style is used when class is bound to an expr.
|
|
5026
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
5027
|
-
}
|
|
5028
|
-
return nodesAreCompatible;
|
|
5029
|
-
}
|
|
5030
|
-
|
|
5031
4805
|
/*
|
|
5032
4806
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
5033
4807
|
* All rights reserved.
|
|
@@ -5073,32 +4847,12 @@ function connectRootElement(elm) {
|
|
|
5073
4847
|
/* GlobalHydrate */
|
|
5074
4848
|
, vm);
|
|
5075
4849
|
}
|
|
5076
|
-
function hydrateRootElement(elm) {
|
|
5077
|
-
const vm = getAssociatedVM(elm);
|
|
5078
|
-
runConnectedCallback(vm);
|
|
5079
|
-
hydrateVM(vm);
|
|
5080
|
-
}
|
|
5081
4850
|
function disconnectRootElement(elm) {
|
|
5082
4851
|
const vm = getAssociatedVM(elm);
|
|
5083
4852
|
resetComponentStateWhenRemoved(vm);
|
|
5084
4853
|
}
|
|
5085
4854
|
function appendVM(vm) {
|
|
5086
4855
|
rehydrate(vm);
|
|
5087
|
-
}
|
|
5088
|
-
function hydrateVM(vm) {
|
|
5089
|
-
if (shared.isTrue(vm.isDirty)) {
|
|
5090
|
-
// manually diffing/patching here.
|
|
5091
|
-
// This routine is:
|
|
5092
|
-
// patchShadowRoot(vm, children);
|
|
5093
|
-
// -> addVnodes.
|
|
5094
|
-
const children = renderComponent(vm);
|
|
5095
|
-
vm.children = children;
|
|
5096
|
-
const vmChildren = vm.renderMode === 0
|
|
5097
|
-
/* Light */
|
|
5098
|
-
? getChildNodes(vm.elm) : getChildNodes(vm.elm.shadowRoot);
|
|
5099
|
-
hydrateChildren(vmChildren, children, vm);
|
|
5100
|
-
runRenderedCallback(vm);
|
|
5101
|
-
}
|
|
5102
4856
|
} // just in case the component comes back, with this we guarantee re-rendering it
|
|
5103
4857
|
// while preventing any attempt to rehydration until after reinsertion.
|
|
5104
4858
|
|
|
@@ -5403,7 +5157,6 @@ function runRenderedCallback(vm) {
|
|
|
5403
5157
|
, vm);
|
|
5404
5158
|
}
|
|
5405
5159
|
}
|
|
5406
|
-
|
|
5407
5160
|
let rehydrateQueue = [];
|
|
5408
5161
|
|
|
5409
5162
|
function flushRehydrationQueue() {
|
|
@@ -6060,6 +5813,298 @@ function readonly(obj) {
|
|
|
6060
5813
|
return reactiveMembrane.getReadOnlyProxy(obj);
|
|
6061
5814
|
}
|
|
6062
5815
|
|
|
5816
|
+
/*
|
|
5817
|
+
* Copyright (c) 2022, salesforce.com, inc.
|
|
5818
|
+
* All rights reserved.
|
|
5819
|
+
* SPDX-License-Identifier: MIT
|
|
5820
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5821
|
+
*/
|
|
5822
|
+
// flag indicating if the hydration recovered from the DOM mismatch
|
|
5823
|
+
let hasMismatch = false;
|
|
5824
|
+
function hydrateRoot(vm) {
|
|
5825
|
+
hasMismatch = false;
|
|
5826
|
+
runConnectedCallback(vm);
|
|
5827
|
+
hydrateVM(vm);
|
|
5828
|
+
if (hasMismatch) {
|
|
5829
|
+
logError('Hydration completed with errors.', vm);
|
|
5830
|
+
}
|
|
5831
|
+
}
|
|
5832
|
+
function hydrateVM(vm) {
|
|
5833
|
+
const children = renderComponent(vm);
|
|
5834
|
+
vm.children = children;
|
|
5835
|
+
const parentNode = vm.renderRoot;
|
|
5836
|
+
hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
|
|
5837
|
+
runRenderedCallback(vm);
|
|
5838
|
+
}
|
|
5839
|
+
function hydrateNode(node, vnode) {
|
|
5840
|
+
let hydratedNode;
|
|
5841
|
+
switch (vnode.type) {
|
|
5842
|
+
case 0 /* Text */:
|
|
5843
|
+
hydratedNode = hydrateText(node, vnode);
|
|
5844
|
+
break;
|
|
5845
|
+
case 1 /* Comment */:
|
|
5846
|
+
hydratedNode = hydrateComment(node, vnode);
|
|
5847
|
+
break;
|
|
5848
|
+
case 2 /* Element */:
|
|
5849
|
+
hydratedNode = hydrateElement(node, vnode);
|
|
5850
|
+
break;
|
|
5851
|
+
case 3 /* CustomElement */:
|
|
5852
|
+
hydratedNode = hydrateCustomElement(node, vnode);
|
|
5853
|
+
break;
|
|
5854
|
+
}
|
|
5855
|
+
return nextSibling(hydratedNode);
|
|
5856
|
+
}
|
|
5857
|
+
function hydrateText(node, vnode) {
|
|
5858
|
+
var _a;
|
|
5859
|
+
if (!hasCorrectNodeType(vnode, node, 3 /* TEXT */)) {
|
|
5860
|
+
return handleMismatch(node, vnode);
|
|
5861
|
+
}
|
|
5862
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5863
|
+
const nodeValue = getProperty(node, 'nodeValue');
|
|
5864
|
+
if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
|
|
5865
|
+
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
5869
|
+
vnode.elm = node;
|
|
5870
|
+
return node;
|
|
5871
|
+
}
|
|
5872
|
+
function hydrateComment(node, vnode) {
|
|
5873
|
+
var _a;
|
|
5874
|
+
if (!hasCorrectNodeType(vnode, node, 8 /* COMMENT */)) {
|
|
5875
|
+
return handleMismatch(node, vnode);
|
|
5876
|
+
}
|
|
5877
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5878
|
+
const nodeValue = getProperty(node, 'nodeValue');
|
|
5879
|
+
if (nodeValue !== vnode.text) {
|
|
5880
|
+
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
5884
|
+
vnode.elm = node;
|
|
5885
|
+
return node;
|
|
5886
|
+
}
|
|
5887
|
+
function hydrateElement(elm, vnode) {
|
|
5888
|
+
if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
|
|
5889
|
+
!isMatchingElement(vnode, elm)) {
|
|
5890
|
+
return handleMismatch(elm, vnode);
|
|
5891
|
+
}
|
|
5892
|
+
vnode.elm = elm;
|
|
5893
|
+
const { context } = vnode.data;
|
|
5894
|
+
const isDomManual = Boolean(!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual" /* Manual */);
|
|
5895
|
+
if (isDomManual) {
|
|
5896
|
+
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
5897
|
+
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
5898
|
+
const { props } = vnode.data;
|
|
5899
|
+
if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
|
|
5900
|
+
if (getProperty(elm, 'innerHTML') === props.innerHTML) {
|
|
5901
|
+
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
5902
|
+
vnode.data = Object.assign(Object.assign({}, vnode.data), { props: cloneAndOmitKey(props, 'innerHTML') });
|
|
5903
|
+
}
|
|
5904
|
+
else {
|
|
5905
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5906
|
+
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
patchElementPropsAndAttrs(vnode);
|
|
5912
|
+
if (!isDomManual) {
|
|
5913
|
+
hydrateChildren(getFirstChild(elm), vnode.children, elm, vnode.owner);
|
|
5914
|
+
}
|
|
5915
|
+
return elm;
|
|
5916
|
+
}
|
|
5917
|
+
function hydrateCustomElement(elm, vnode) {
|
|
5918
|
+
if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
|
|
5919
|
+
!isMatchingElement(vnode, elm)) {
|
|
5920
|
+
return handleMismatch(elm, vnode);
|
|
5921
|
+
}
|
|
5922
|
+
const { sel, mode, ctor, owner } = vnode;
|
|
5923
|
+
const vm = createVM(elm, ctor, {
|
|
5924
|
+
mode,
|
|
5925
|
+
owner,
|
|
5926
|
+
tagName: sel,
|
|
5927
|
+
});
|
|
5928
|
+
vnode.elm = elm;
|
|
5929
|
+
vnode.vm = vm;
|
|
5930
|
+
allocateChildren(vnode, vm);
|
|
5931
|
+
patchElementPropsAndAttrs(vnode);
|
|
5932
|
+
// Insert hook section:
|
|
5933
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5934
|
+
shared.assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
|
|
5935
|
+
}
|
|
5936
|
+
runConnectedCallback(vm);
|
|
5937
|
+
if (vm.renderMode !== 0 /* Light */) {
|
|
5938
|
+
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
5939
|
+
// Note: for Light DOM, this is handled while hydrating the VM
|
|
5940
|
+
hydrateChildren(getFirstChild(elm), vnode.children, elm, vm);
|
|
5941
|
+
}
|
|
5942
|
+
hydrateVM(vm);
|
|
5943
|
+
return elm;
|
|
5944
|
+
}
|
|
5945
|
+
function hydrateChildren(node, children, parentNode, owner) {
|
|
5946
|
+
let hasWarned = false;
|
|
5947
|
+
let nextNode = node;
|
|
5948
|
+
let anchor = null;
|
|
5949
|
+
for (let i = 0; i < children.length; i++) {
|
|
5950
|
+
const childVnode = children[i];
|
|
5951
|
+
if (!shared.isNull(childVnode)) {
|
|
5952
|
+
if (nextNode) {
|
|
5953
|
+
nextNode = hydrateNode(nextNode, childVnode);
|
|
5954
|
+
anchor = childVnode.elm;
|
|
5955
|
+
}
|
|
5956
|
+
else {
|
|
5957
|
+
hasMismatch = true;
|
|
5958
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5959
|
+
if (!hasWarned) {
|
|
5960
|
+
hasWarned = true;
|
|
5961
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
|
|
5962
|
+
}
|
|
5963
|
+
}
|
|
5964
|
+
mount(childVnode, parentNode, anchor);
|
|
5965
|
+
anchor = childVnode.elm;
|
|
5966
|
+
}
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5969
|
+
if (nextNode) {
|
|
5970
|
+
hasMismatch = true;
|
|
5971
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5972
|
+
if (!hasWarned) {
|
|
5973
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
do {
|
|
5977
|
+
const current = nextNode;
|
|
5978
|
+
nextNode = nextSibling(nextNode);
|
|
5979
|
+
removeNode(current, parentNode);
|
|
5980
|
+
} while (nextNode);
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
function handleMismatch(node, vnode, msg) {
|
|
5984
|
+
hasMismatch = true;
|
|
5985
|
+
if (!shared.isUndefined(msg)) {
|
|
5986
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5987
|
+
logError(msg, vnode.owner);
|
|
5988
|
+
}
|
|
5989
|
+
}
|
|
5990
|
+
const parentNode = getProperty(node, 'parentNode');
|
|
5991
|
+
mount(vnode, parentNode, node);
|
|
5992
|
+
removeNode(node, parentNode);
|
|
5993
|
+
return vnode.elm;
|
|
5994
|
+
}
|
|
5995
|
+
function patchElementPropsAndAttrs(vnode) {
|
|
5996
|
+
applyEventListeners(vnode);
|
|
5997
|
+
patchProps(null, vnode);
|
|
5998
|
+
}
|
|
5999
|
+
function hasCorrectNodeType(vnode, node, nodeType) {
|
|
6000
|
+
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
6001
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6002
|
+
logError('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
6003
|
+
}
|
|
6004
|
+
return false;
|
|
6005
|
+
}
|
|
6006
|
+
return true;
|
|
6007
|
+
}
|
|
6008
|
+
function isMatchingElement(vnode, elm) {
|
|
6009
|
+
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
6010
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6011
|
+
logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
|
|
6012
|
+
}
|
|
6013
|
+
return false;
|
|
6014
|
+
}
|
|
6015
|
+
const hasIncompatibleAttrs = validateAttrs(vnode, elm);
|
|
6016
|
+
const hasIncompatibleClass = validateClassAttr(vnode, elm);
|
|
6017
|
+
const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
|
|
6018
|
+
return hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
6019
|
+
}
|
|
6020
|
+
function validateAttrs(vnode, elm) {
|
|
6021
|
+
const { data: { attrs = {} }, } = vnode;
|
|
6022
|
+
let nodesAreCompatible = true;
|
|
6023
|
+
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
6024
|
+
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
6025
|
+
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
6026
|
+
const elmAttrValue = getAttribute(elm, attrName);
|
|
6027
|
+
if (String(attrValue) !== elmAttrValue) {
|
|
6028
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6029
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
6030
|
+
}
|
|
6031
|
+
nodesAreCompatible = false;
|
|
6032
|
+
}
|
|
6033
|
+
}
|
|
6034
|
+
return nodesAreCompatible;
|
|
6035
|
+
}
|
|
6036
|
+
function validateClassAttr(vnode, elm) {
|
|
6037
|
+
const { data: { className, classMap }, } = vnode;
|
|
6038
|
+
let nodesAreCompatible = true;
|
|
6039
|
+
let vnodeClassName;
|
|
6040
|
+
if (!shared.isUndefined(className) && String(className) !== getProperty(elm, 'className')) {
|
|
6041
|
+
// className is used when class is bound to an expr.
|
|
6042
|
+
nodesAreCompatible = false;
|
|
6043
|
+
vnodeClassName = className;
|
|
6044
|
+
}
|
|
6045
|
+
else if (!shared.isUndefined(classMap)) {
|
|
6046
|
+
// classMap is used when class is set to static value.
|
|
6047
|
+
const classList = getClassList(elm);
|
|
6048
|
+
let computedClassName = '';
|
|
6049
|
+
// all classes from the vnode should be in the element.classList
|
|
6050
|
+
for (const name in classMap) {
|
|
6051
|
+
computedClassName += ' ' + name;
|
|
6052
|
+
if (!classList.contains(name)) {
|
|
6053
|
+
nodesAreCompatible = false;
|
|
6054
|
+
}
|
|
6055
|
+
}
|
|
6056
|
+
vnodeClassName = computedClassName.trim();
|
|
6057
|
+
if (classList.length > shared.keys(classMap).length) {
|
|
6058
|
+
nodesAreCompatible = false;
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6061
|
+
if (!nodesAreCompatible) {
|
|
6062
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6063
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${getProperty(elm, 'className')}"`, vnode.owner);
|
|
6064
|
+
}
|
|
6065
|
+
}
|
|
6066
|
+
return nodesAreCompatible;
|
|
6067
|
+
}
|
|
6068
|
+
function validateStyleAttr(vnode, elm) {
|
|
6069
|
+
const { data: { style, styleDecls }, } = vnode;
|
|
6070
|
+
const elmStyle = getAttribute(elm, 'style') || '';
|
|
6071
|
+
let vnodeStyle;
|
|
6072
|
+
let nodesAreCompatible = true;
|
|
6073
|
+
if (!shared.isUndefined(style) && style !== elmStyle) {
|
|
6074
|
+
nodesAreCompatible = false;
|
|
6075
|
+
vnodeStyle = style;
|
|
6076
|
+
}
|
|
6077
|
+
else if (!shared.isUndefined(styleDecls)) {
|
|
6078
|
+
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
6079
|
+
const expectedStyle = [];
|
|
6080
|
+
// styleMap is used when style is set to static value.
|
|
6081
|
+
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
6082
|
+
const [prop, value, important] = styleDecls[i];
|
|
6083
|
+
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
6084
|
+
const parsedPropValue = parsedVnodeStyle[prop];
|
|
6085
|
+
if (shared.isUndefined(parsedPropValue)) {
|
|
6086
|
+
nodesAreCompatible = false;
|
|
6087
|
+
}
|
|
6088
|
+
else if (!parsedPropValue.startsWith(value)) {
|
|
6089
|
+
nodesAreCompatible = false;
|
|
6090
|
+
}
|
|
6091
|
+
else if (important && !parsedPropValue.endsWith('!important')) {
|
|
6092
|
+
nodesAreCompatible = false;
|
|
6093
|
+
}
|
|
6094
|
+
}
|
|
6095
|
+
if (shared.keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
6096
|
+
nodesAreCompatible = false;
|
|
6097
|
+
}
|
|
6098
|
+
vnodeStyle = shared.ArrayJoin.call(expectedStyle, ';');
|
|
6099
|
+
}
|
|
6100
|
+
if (!nodesAreCompatible) {
|
|
6101
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6102
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
6103
|
+
}
|
|
6104
|
+
}
|
|
6105
|
+
return nodesAreCompatible;
|
|
6106
|
+
}
|
|
6107
|
+
|
|
6063
6108
|
/*
|
|
6064
6109
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
6065
6110
|
* All rights reserved.
|
|
@@ -6092,7 +6137,7 @@ exports.getAssociatedVMIfPresent = getAssociatedVMIfPresent;
|
|
|
6092
6137
|
exports.getComponentDef = getComponentDef;
|
|
6093
6138
|
exports.getComponentHtmlPrototype = getComponentHtmlPrototype;
|
|
6094
6139
|
exports.getUpgradableConstructor = getUpgradableConstructor;
|
|
6095
|
-
exports.
|
|
6140
|
+
exports.hydrateRoot = hydrateRoot;
|
|
6096
6141
|
exports.isComponentConstructor = isComponentConstructor;
|
|
6097
6142
|
exports.readonly = readonly;
|
|
6098
6143
|
exports.register = register;
|
|
@@ -6147,4 +6192,4 @@ exports.swapTemplate = swapTemplate;
|
|
|
6147
6192
|
exports.track = track;
|
|
6148
6193
|
exports.unwrap = unwrap;
|
|
6149
6194
|
exports.wire = wire;
|
|
6150
|
-
/* version: 2.
|
|
6195
|
+
/* version: 2.12.0 */
|
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, isFrozen, defineProperty, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_RESOLVER, isArray as isArray$1, isNumber, StringReplace, KEY__SCOPED_CSS, noop, ArrayUnshift
|
|
2
|
+
import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, isFrozen, defineProperty, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_RESOLVER, isArray as isArray$1, isNumber, StringReplace, KEY__SCOPED_CSS, noop, ArrayUnshift } from '@lwc/shared';
|
|
3
3
|
import { runtimeFlags } from '@lwc/features';
|
|
4
4
|
export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
|
|
5
5
|
|
|
@@ -4702,11 +4702,15 @@ const signedTemplateMap = new Map();
|
|
|
4702
4702
|
* INTERNAL: This function can only be invoked by compiled code. The compiler
|
|
4703
4703
|
* will prevent this function from being imported by userland code.
|
|
4704
4704
|
*/
|
|
4705
|
-
function registerComponent(
|
|
4706
|
-
|
|
4707
|
-
|
|
4705
|
+
function registerComponent(
|
|
4706
|
+
// We typically expect a LightningElementConstructor, but technically you can call this with anything
|
|
4707
|
+
Ctor, { tmpl }) {
|
|
4708
|
+
if (isFunction$1(Ctor)) {
|
|
4709
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4710
|
+
checkVersionMismatch(Ctor, 'component');
|
|
4711
|
+
}
|
|
4712
|
+
signedTemplateMap.set(Ctor, tmpl);
|
|
4708
4713
|
}
|
|
4709
|
-
signedTemplateMap.set(Ctor, tmpl);
|
|
4710
4714
|
// chaining this method as a way to wrap existing assignment of component constructor easily,
|
|
4711
4715
|
// without too much transformation
|
|
4712
4716
|
return Ctor;
|
|
@@ -4795,236 +4799,6 @@ function invokeServiceHook(vm, cbs) {
|
|
|
4795
4799
|
}
|
|
4796
4800
|
}
|
|
4797
4801
|
|
|
4798
|
-
/*
|
|
4799
|
-
* Copyright (c) 2022, salesforce.com, inc.
|
|
4800
|
-
* All rights reserved.
|
|
4801
|
-
* SPDX-License-Identifier: MIT
|
|
4802
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4803
|
-
*/
|
|
4804
|
-
function hydrate(vnode, node) {
|
|
4805
|
-
switch (vnode.type) {
|
|
4806
|
-
case 0 /* Text */:
|
|
4807
|
-
hydrateText(vnode, node);
|
|
4808
|
-
break;
|
|
4809
|
-
case 1 /* Comment */:
|
|
4810
|
-
hydrateComment(vnode, node);
|
|
4811
|
-
break;
|
|
4812
|
-
case 2 /* Element */:
|
|
4813
|
-
hydrateElement(vnode, node);
|
|
4814
|
-
break;
|
|
4815
|
-
case 3 /* CustomElement */:
|
|
4816
|
-
hydrateCustomElement(vnode, node);
|
|
4817
|
-
break;
|
|
4818
|
-
}
|
|
4819
|
-
}
|
|
4820
|
-
function hydrateText(vnode, node) {
|
|
4821
|
-
var _a;
|
|
4822
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4823
|
-
validateNodeType(vnode, node, 3 /* TEXT */);
|
|
4824
|
-
const nodeValue = getProperty(node, 'nodeValue');
|
|
4825
|
-
if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
|
|
4826
|
-
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
|
|
4827
|
-
}
|
|
4828
|
-
}
|
|
4829
|
-
// always set the text value to the one from the vnode.
|
|
4830
|
-
setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
4831
|
-
vnode.elm = node;
|
|
4832
|
-
}
|
|
4833
|
-
function hydrateComment(vnode, node) {
|
|
4834
|
-
var _a;
|
|
4835
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4836
|
-
validateNodeType(vnode, node, 8 /* COMMENT */);
|
|
4837
|
-
if (getProperty(node, 'nodeValue') !== vnode.text) {
|
|
4838
|
-
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
|
|
4839
|
-
}
|
|
4840
|
-
}
|
|
4841
|
-
// always set the text value to the one from the vnode.
|
|
4842
|
-
setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
4843
|
-
vnode.elm = node;
|
|
4844
|
-
}
|
|
4845
|
-
function hydrateElement(vnode, node) {
|
|
4846
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4847
|
-
validateNodeType(vnode, node, 1 /* ELEMENT */);
|
|
4848
|
-
validateElement(vnode, node);
|
|
4849
|
-
}
|
|
4850
|
-
const elm = node;
|
|
4851
|
-
vnode.elm = elm;
|
|
4852
|
-
const { context } = vnode.data;
|
|
4853
|
-
const isDomManual = Boolean(!isUndefined$1(context) && !isUndefined$1(context.lwc) && context.lwc.dom === "manual" /* Manual */);
|
|
4854
|
-
if (isDomManual) {
|
|
4855
|
-
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
4856
|
-
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
4857
|
-
const { props } = vnode.data;
|
|
4858
|
-
if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
|
|
4859
|
-
if (getProperty(elm, 'innerHTML') === props.innerHTML) {
|
|
4860
|
-
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
4861
|
-
vnode.data = Object.assign(Object.assign({}, vnode.data), { props: cloneAndOmitKey(props, 'innerHTML') });
|
|
4862
|
-
}
|
|
4863
|
-
else {
|
|
4864
|
-
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
4865
|
-
}
|
|
4866
|
-
}
|
|
4867
|
-
}
|
|
4868
|
-
patchElementPropsAndAttrs(vnode);
|
|
4869
|
-
if (!isDomManual) {
|
|
4870
|
-
hydrateChildren(getChildNodes(vnode.elm), vnode.children, vnode.owner);
|
|
4871
|
-
}
|
|
4872
|
-
}
|
|
4873
|
-
function hydrateCustomElement(vnode, node) {
|
|
4874
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4875
|
-
validateNodeType(vnode, node, 1 /* ELEMENT */);
|
|
4876
|
-
validateElement(vnode, node);
|
|
4877
|
-
}
|
|
4878
|
-
const elm = node;
|
|
4879
|
-
const { sel, mode, ctor, owner } = vnode;
|
|
4880
|
-
const vm = createVM(elm, ctor, {
|
|
4881
|
-
mode,
|
|
4882
|
-
owner,
|
|
4883
|
-
tagName: sel,
|
|
4884
|
-
});
|
|
4885
|
-
vnode.elm = elm;
|
|
4886
|
-
vnode.vm = vm;
|
|
4887
|
-
allocateChildren(vnode, vm);
|
|
4888
|
-
patchElementPropsAndAttrs(vnode);
|
|
4889
|
-
// Insert hook section:
|
|
4890
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4891
|
-
assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
|
|
4892
|
-
}
|
|
4893
|
-
runConnectedCallback(vm);
|
|
4894
|
-
if (vm.renderMode !== 0 /* Light */) {
|
|
4895
|
-
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
4896
|
-
// Note: for Light DOM, this is handled while hydrating the VM
|
|
4897
|
-
hydrateChildren(getChildNodes(vnode.elm), vnode.children, vm);
|
|
4898
|
-
}
|
|
4899
|
-
hydrateVM(vm);
|
|
4900
|
-
}
|
|
4901
|
-
function hydrateChildren(elmChildren, children, vm) {
|
|
4902
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4903
|
-
const filteredVNodes = ArrayFilter.call(children, (vnode) => !!vnode);
|
|
4904
|
-
if (elmChildren.length !== filteredVNodes.length) {
|
|
4905
|
-
logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
|
|
4906
|
-
throwHydrationError();
|
|
4907
|
-
}
|
|
4908
|
-
}
|
|
4909
|
-
let childNodeIndex = 0;
|
|
4910
|
-
for (let i = 0; i < children.length; i++) {
|
|
4911
|
-
const childVnode = children[i];
|
|
4912
|
-
if (!isNull(childVnode)) {
|
|
4913
|
-
const childNode = elmChildren[childNodeIndex];
|
|
4914
|
-
hydrate(childVnode, childNode);
|
|
4915
|
-
childNodeIndex++;
|
|
4916
|
-
}
|
|
4917
|
-
}
|
|
4918
|
-
}
|
|
4919
|
-
function patchElementPropsAndAttrs(vnode) {
|
|
4920
|
-
applyEventListeners(vnode);
|
|
4921
|
-
patchProps(null, vnode);
|
|
4922
|
-
}
|
|
4923
|
-
function throwHydrationError() {
|
|
4924
|
-
assert.fail('Server rendered elements do not match client side generated elements');
|
|
4925
|
-
}
|
|
4926
|
-
function validateNodeType(vnode, node, nodeType) {
|
|
4927
|
-
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
4928
|
-
logError('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
4929
|
-
assert.fail('Hydration mismatch: incorrect node type received.');
|
|
4930
|
-
}
|
|
4931
|
-
}
|
|
4932
|
-
function validateElement(vnode, elm) {
|
|
4933
|
-
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
4934
|
-
logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
|
|
4935
|
-
throwHydrationError();
|
|
4936
|
-
}
|
|
4937
|
-
const hasIncompatibleAttrs = validateAttrs(vnode, elm);
|
|
4938
|
-
const hasIncompatibleClass = validateClassAttr(vnode, elm);
|
|
4939
|
-
const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
|
|
4940
|
-
const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
4941
|
-
if (!isVNodeAndElementCompatible) {
|
|
4942
|
-
throwHydrationError();
|
|
4943
|
-
}
|
|
4944
|
-
}
|
|
4945
|
-
function validateAttrs(vnode, elm) {
|
|
4946
|
-
const { data: { attrs = {} }, } = vnode;
|
|
4947
|
-
let nodesAreCompatible = true;
|
|
4948
|
-
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
4949
|
-
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
4950
|
-
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
4951
|
-
const elmAttrValue = getAttribute(elm, attrName);
|
|
4952
|
-
if (String(attrValue) !== elmAttrValue) {
|
|
4953
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
4954
|
-
nodesAreCompatible = false;
|
|
4955
|
-
}
|
|
4956
|
-
}
|
|
4957
|
-
return nodesAreCompatible;
|
|
4958
|
-
}
|
|
4959
|
-
function validateClassAttr(vnode, elm) {
|
|
4960
|
-
const { data: { className, classMap }, } = vnode;
|
|
4961
|
-
let nodesAreCompatible = true;
|
|
4962
|
-
let vnodeClassName;
|
|
4963
|
-
if (!isUndefined$1(className) && String(className) !== getProperty(elm, 'className')) {
|
|
4964
|
-
// className is used when class is bound to an expr.
|
|
4965
|
-
nodesAreCompatible = false;
|
|
4966
|
-
vnodeClassName = className;
|
|
4967
|
-
}
|
|
4968
|
-
else if (!isUndefined$1(classMap)) {
|
|
4969
|
-
// classMap is used when class is set to static value.
|
|
4970
|
-
const classList = getClassList(elm);
|
|
4971
|
-
let computedClassName = '';
|
|
4972
|
-
// all classes from the vnode should be in the element.classList
|
|
4973
|
-
for (const name in classMap) {
|
|
4974
|
-
computedClassName += ' ' + name;
|
|
4975
|
-
if (!classList.contains(name)) {
|
|
4976
|
-
nodesAreCompatible = false;
|
|
4977
|
-
}
|
|
4978
|
-
}
|
|
4979
|
-
vnodeClassName = computedClassName.trim();
|
|
4980
|
-
if (classList.length > keys(classMap).length) {
|
|
4981
|
-
nodesAreCompatible = false;
|
|
4982
|
-
}
|
|
4983
|
-
}
|
|
4984
|
-
if (!nodesAreCompatible) {
|
|
4985
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${getProperty(elm, 'className')}"`, vnode.owner);
|
|
4986
|
-
}
|
|
4987
|
-
return nodesAreCompatible;
|
|
4988
|
-
}
|
|
4989
|
-
function validateStyleAttr(vnode, elm) {
|
|
4990
|
-
const { data: { style, styleDecls }, } = vnode;
|
|
4991
|
-
const elmStyle = getAttribute(elm, 'style') || '';
|
|
4992
|
-
let vnodeStyle;
|
|
4993
|
-
let nodesAreCompatible = true;
|
|
4994
|
-
if (!isUndefined$1(style) && style !== elmStyle) {
|
|
4995
|
-
nodesAreCompatible = false;
|
|
4996
|
-
vnodeStyle = style;
|
|
4997
|
-
}
|
|
4998
|
-
else if (!isUndefined$1(styleDecls)) {
|
|
4999
|
-
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
5000
|
-
const expectedStyle = [];
|
|
5001
|
-
// styleMap is used when style is set to static value.
|
|
5002
|
-
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
5003
|
-
const [prop, value, important] = styleDecls[i];
|
|
5004
|
-
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
5005
|
-
const parsedPropValue = parsedVnodeStyle[prop];
|
|
5006
|
-
if (isUndefined$1(parsedPropValue)) {
|
|
5007
|
-
nodesAreCompatible = false;
|
|
5008
|
-
}
|
|
5009
|
-
else if (!parsedPropValue.startsWith(value)) {
|
|
5010
|
-
nodesAreCompatible = false;
|
|
5011
|
-
}
|
|
5012
|
-
else if (important && !parsedPropValue.endsWith('!important')) {
|
|
5013
|
-
nodesAreCompatible = false;
|
|
5014
|
-
}
|
|
5015
|
-
}
|
|
5016
|
-
if (keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
5017
|
-
nodesAreCompatible = false;
|
|
5018
|
-
}
|
|
5019
|
-
vnodeStyle = ArrayJoin.call(expectedStyle, ';');
|
|
5020
|
-
}
|
|
5021
|
-
if (!nodesAreCompatible) {
|
|
5022
|
-
// style is used when class is bound to an expr.
|
|
5023
|
-
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
5024
|
-
}
|
|
5025
|
-
return nodesAreCompatible;
|
|
5026
|
-
}
|
|
5027
|
-
|
|
5028
4802
|
/*
|
|
5029
4803
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
5030
4804
|
* All rights reserved.
|
|
@@ -5070,32 +4844,12 @@ function connectRootElement(elm) {
|
|
|
5070
4844
|
/* GlobalHydrate */
|
|
5071
4845
|
, vm);
|
|
5072
4846
|
}
|
|
5073
|
-
function hydrateRootElement(elm) {
|
|
5074
|
-
const vm = getAssociatedVM(elm);
|
|
5075
|
-
runConnectedCallback(vm);
|
|
5076
|
-
hydrateVM(vm);
|
|
5077
|
-
}
|
|
5078
4847
|
function disconnectRootElement(elm) {
|
|
5079
4848
|
const vm = getAssociatedVM(elm);
|
|
5080
4849
|
resetComponentStateWhenRemoved(vm);
|
|
5081
4850
|
}
|
|
5082
4851
|
function appendVM(vm) {
|
|
5083
4852
|
rehydrate(vm);
|
|
5084
|
-
}
|
|
5085
|
-
function hydrateVM(vm) {
|
|
5086
|
-
if (isTrue(vm.isDirty)) {
|
|
5087
|
-
// manually diffing/patching here.
|
|
5088
|
-
// This routine is:
|
|
5089
|
-
// patchShadowRoot(vm, children);
|
|
5090
|
-
// -> addVnodes.
|
|
5091
|
-
const children = renderComponent(vm);
|
|
5092
|
-
vm.children = children;
|
|
5093
|
-
const vmChildren = vm.renderMode === 0
|
|
5094
|
-
/* Light */
|
|
5095
|
-
? getChildNodes(vm.elm) : getChildNodes(vm.elm.shadowRoot);
|
|
5096
|
-
hydrateChildren(vmChildren, children, vm);
|
|
5097
|
-
runRenderedCallback(vm);
|
|
5098
|
-
}
|
|
5099
4853
|
} // just in case the component comes back, with this we guarantee re-rendering it
|
|
5100
4854
|
// while preventing any attempt to rehydration until after reinsertion.
|
|
5101
4855
|
|
|
@@ -5400,7 +5154,6 @@ function runRenderedCallback(vm) {
|
|
|
5400
5154
|
, vm);
|
|
5401
5155
|
}
|
|
5402
5156
|
}
|
|
5403
|
-
|
|
5404
5157
|
let rehydrateQueue = [];
|
|
5405
5158
|
|
|
5406
5159
|
function flushRehydrationQueue() {
|
|
@@ -6057,6 +5810,298 @@ function readonly(obj) {
|
|
|
6057
5810
|
return reactiveMembrane.getReadOnlyProxy(obj);
|
|
6058
5811
|
}
|
|
6059
5812
|
|
|
5813
|
+
/*
|
|
5814
|
+
* Copyright (c) 2022, salesforce.com, inc.
|
|
5815
|
+
* All rights reserved.
|
|
5816
|
+
* SPDX-License-Identifier: MIT
|
|
5817
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5818
|
+
*/
|
|
5819
|
+
// flag indicating if the hydration recovered from the DOM mismatch
|
|
5820
|
+
let hasMismatch = false;
|
|
5821
|
+
function hydrateRoot(vm) {
|
|
5822
|
+
hasMismatch = false;
|
|
5823
|
+
runConnectedCallback(vm);
|
|
5824
|
+
hydrateVM(vm);
|
|
5825
|
+
if (hasMismatch) {
|
|
5826
|
+
logError('Hydration completed with errors.', vm);
|
|
5827
|
+
}
|
|
5828
|
+
}
|
|
5829
|
+
function hydrateVM(vm) {
|
|
5830
|
+
const children = renderComponent(vm);
|
|
5831
|
+
vm.children = children;
|
|
5832
|
+
const parentNode = vm.renderRoot;
|
|
5833
|
+
hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
|
|
5834
|
+
runRenderedCallback(vm);
|
|
5835
|
+
}
|
|
5836
|
+
function hydrateNode(node, vnode) {
|
|
5837
|
+
let hydratedNode;
|
|
5838
|
+
switch (vnode.type) {
|
|
5839
|
+
case 0 /* Text */:
|
|
5840
|
+
hydratedNode = hydrateText(node, vnode);
|
|
5841
|
+
break;
|
|
5842
|
+
case 1 /* Comment */:
|
|
5843
|
+
hydratedNode = hydrateComment(node, vnode);
|
|
5844
|
+
break;
|
|
5845
|
+
case 2 /* Element */:
|
|
5846
|
+
hydratedNode = hydrateElement(node, vnode);
|
|
5847
|
+
break;
|
|
5848
|
+
case 3 /* CustomElement */:
|
|
5849
|
+
hydratedNode = hydrateCustomElement(node, vnode);
|
|
5850
|
+
break;
|
|
5851
|
+
}
|
|
5852
|
+
return nextSibling(hydratedNode);
|
|
5853
|
+
}
|
|
5854
|
+
function hydrateText(node, vnode) {
|
|
5855
|
+
var _a;
|
|
5856
|
+
if (!hasCorrectNodeType(vnode, node, 3 /* TEXT */)) {
|
|
5857
|
+
return handleMismatch(node, vnode);
|
|
5858
|
+
}
|
|
5859
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5860
|
+
const nodeValue = getProperty(node, 'nodeValue');
|
|
5861
|
+
if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
|
|
5862
|
+
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
5866
|
+
vnode.elm = node;
|
|
5867
|
+
return node;
|
|
5868
|
+
}
|
|
5869
|
+
function hydrateComment(node, vnode) {
|
|
5870
|
+
var _a;
|
|
5871
|
+
if (!hasCorrectNodeType(vnode, node, 8 /* COMMENT */)) {
|
|
5872
|
+
return handleMismatch(node, vnode);
|
|
5873
|
+
}
|
|
5874
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5875
|
+
const nodeValue = getProperty(node, 'nodeValue');
|
|
5876
|
+
if (nodeValue !== vnode.text) {
|
|
5877
|
+
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
|
|
5878
|
+
}
|
|
5879
|
+
}
|
|
5880
|
+
setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
|
|
5881
|
+
vnode.elm = node;
|
|
5882
|
+
return node;
|
|
5883
|
+
}
|
|
5884
|
+
function hydrateElement(elm, vnode) {
|
|
5885
|
+
if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
|
|
5886
|
+
!isMatchingElement(vnode, elm)) {
|
|
5887
|
+
return handleMismatch(elm, vnode);
|
|
5888
|
+
}
|
|
5889
|
+
vnode.elm = elm;
|
|
5890
|
+
const { context } = vnode.data;
|
|
5891
|
+
const isDomManual = Boolean(!isUndefined$1(context) && !isUndefined$1(context.lwc) && context.lwc.dom === "manual" /* Manual */);
|
|
5892
|
+
if (isDomManual) {
|
|
5893
|
+
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
5894
|
+
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
5895
|
+
const { props } = vnode.data;
|
|
5896
|
+
if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
|
|
5897
|
+
if (getProperty(elm, 'innerHTML') === props.innerHTML) {
|
|
5898
|
+
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
5899
|
+
vnode.data = Object.assign(Object.assign({}, vnode.data), { props: cloneAndOmitKey(props, 'innerHTML') });
|
|
5900
|
+
}
|
|
5901
|
+
else {
|
|
5902
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5903
|
+
logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
}
|
|
5907
|
+
}
|
|
5908
|
+
patchElementPropsAndAttrs(vnode);
|
|
5909
|
+
if (!isDomManual) {
|
|
5910
|
+
hydrateChildren(getFirstChild(elm), vnode.children, elm, vnode.owner);
|
|
5911
|
+
}
|
|
5912
|
+
return elm;
|
|
5913
|
+
}
|
|
5914
|
+
function hydrateCustomElement(elm, vnode) {
|
|
5915
|
+
if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
|
|
5916
|
+
!isMatchingElement(vnode, elm)) {
|
|
5917
|
+
return handleMismatch(elm, vnode);
|
|
5918
|
+
}
|
|
5919
|
+
const { sel, mode, ctor, owner } = vnode;
|
|
5920
|
+
const vm = createVM(elm, ctor, {
|
|
5921
|
+
mode,
|
|
5922
|
+
owner,
|
|
5923
|
+
tagName: sel,
|
|
5924
|
+
});
|
|
5925
|
+
vnode.elm = elm;
|
|
5926
|
+
vnode.vm = vm;
|
|
5927
|
+
allocateChildren(vnode, vm);
|
|
5928
|
+
patchElementPropsAndAttrs(vnode);
|
|
5929
|
+
// Insert hook section:
|
|
5930
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5931
|
+
assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
|
|
5932
|
+
}
|
|
5933
|
+
runConnectedCallback(vm);
|
|
5934
|
+
if (vm.renderMode !== 0 /* Light */) {
|
|
5935
|
+
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
5936
|
+
// Note: for Light DOM, this is handled while hydrating the VM
|
|
5937
|
+
hydrateChildren(getFirstChild(elm), vnode.children, elm, vm);
|
|
5938
|
+
}
|
|
5939
|
+
hydrateVM(vm);
|
|
5940
|
+
return elm;
|
|
5941
|
+
}
|
|
5942
|
+
function hydrateChildren(node, children, parentNode, owner) {
|
|
5943
|
+
let hasWarned = false;
|
|
5944
|
+
let nextNode = node;
|
|
5945
|
+
let anchor = null;
|
|
5946
|
+
for (let i = 0; i < children.length; i++) {
|
|
5947
|
+
const childVnode = children[i];
|
|
5948
|
+
if (!isNull(childVnode)) {
|
|
5949
|
+
if (nextNode) {
|
|
5950
|
+
nextNode = hydrateNode(nextNode, childVnode);
|
|
5951
|
+
anchor = childVnode.elm;
|
|
5952
|
+
}
|
|
5953
|
+
else {
|
|
5954
|
+
hasMismatch = true;
|
|
5955
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5956
|
+
if (!hasWarned) {
|
|
5957
|
+
hasWarned = true;
|
|
5958
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
|
|
5959
|
+
}
|
|
5960
|
+
}
|
|
5961
|
+
mount(childVnode, parentNode, anchor);
|
|
5962
|
+
anchor = childVnode.elm;
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
if (nextNode) {
|
|
5967
|
+
hasMismatch = true;
|
|
5968
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5969
|
+
if (!hasWarned) {
|
|
5970
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
do {
|
|
5974
|
+
const current = nextNode;
|
|
5975
|
+
nextNode = nextSibling(nextNode);
|
|
5976
|
+
removeNode(current, parentNode);
|
|
5977
|
+
} while (nextNode);
|
|
5978
|
+
}
|
|
5979
|
+
}
|
|
5980
|
+
function handleMismatch(node, vnode, msg) {
|
|
5981
|
+
hasMismatch = true;
|
|
5982
|
+
if (!isUndefined$1(msg)) {
|
|
5983
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5984
|
+
logError(msg, vnode.owner);
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
const parentNode = getProperty(node, 'parentNode');
|
|
5988
|
+
mount(vnode, parentNode, node);
|
|
5989
|
+
removeNode(node, parentNode);
|
|
5990
|
+
return vnode.elm;
|
|
5991
|
+
}
|
|
5992
|
+
function patchElementPropsAndAttrs(vnode) {
|
|
5993
|
+
applyEventListeners(vnode);
|
|
5994
|
+
patchProps(null, vnode);
|
|
5995
|
+
}
|
|
5996
|
+
function hasCorrectNodeType(vnode, node, nodeType) {
|
|
5997
|
+
if (getProperty(node, 'nodeType') !== nodeType) {
|
|
5998
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5999
|
+
logError('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
6000
|
+
}
|
|
6001
|
+
return false;
|
|
6002
|
+
}
|
|
6003
|
+
return true;
|
|
6004
|
+
}
|
|
6005
|
+
function isMatchingElement(vnode, elm) {
|
|
6006
|
+
if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
|
|
6007
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6008
|
+
logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
|
|
6009
|
+
}
|
|
6010
|
+
return false;
|
|
6011
|
+
}
|
|
6012
|
+
const hasIncompatibleAttrs = validateAttrs(vnode, elm);
|
|
6013
|
+
const hasIncompatibleClass = validateClassAttr(vnode, elm);
|
|
6014
|
+
const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
|
|
6015
|
+
return hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
6016
|
+
}
|
|
6017
|
+
function validateAttrs(vnode, elm) {
|
|
6018
|
+
const { data: { attrs = {} }, } = vnode;
|
|
6019
|
+
let nodesAreCompatible = true;
|
|
6020
|
+
// Validate attributes, though we could always recovery from those by running the update mods.
|
|
6021
|
+
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
6022
|
+
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
6023
|
+
const elmAttrValue = getAttribute(elm, attrName);
|
|
6024
|
+
if (String(attrValue) !== elmAttrValue) {
|
|
6025
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6026
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
6027
|
+
}
|
|
6028
|
+
nodesAreCompatible = false;
|
|
6029
|
+
}
|
|
6030
|
+
}
|
|
6031
|
+
return nodesAreCompatible;
|
|
6032
|
+
}
|
|
6033
|
+
function validateClassAttr(vnode, elm) {
|
|
6034
|
+
const { data: { className, classMap }, } = vnode;
|
|
6035
|
+
let nodesAreCompatible = true;
|
|
6036
|
+
let vnodeClassName;
|
|
6037
|
+
if (!isUndefined$1(className) && String(className) !== getProperty(elm, 'className')) {
|
|
6038
|
+
// className is used when class is bound to an expr.
|
|
6039
|
+
nodesAreCompatible = false;
|
|
6040
|
+
vnodeClassName = className;
|
|
6041
|
+
}
|
|
6042
|
+
else if (!isUndefined$1(classMap)) {
|
|
6043
|
+
// classMap is used when class is set to static value.
|
|
6044
|
+
const classList = getClassList(elm);
|
|
6045
|
+
let computedClassName = '';
|
|
6046
|
+
// all classes from the vnode should be in the element.classList
|
|
6047
|
+
for (const name in classMap) {
|
|
6048
|
+
computedClassName += ' ' + name;
|
|
6049
|
+
if (!classList.contains(name)) {
|
|
6050
|
+
nodesAreCompatible = false;
|
|
6051
|
+
}
|
|
6052
|
+
}
|
|
6053
|
+
vnodeClassName = computedClassName.trim();
|
|
6054
|
+
if (classList.length > keys(classMap).length) {
|
|
6055
|
+
nodesAreCompatible = false;
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
if (!nodesAreCompatible) {
|
|
6059
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6060
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${getProperty(elm, 'className')}"`, vnode.owner);
|
|
6061
|
+
}
|
|
6062
|
+
}
|
|
6063
|
+
return nodesAreCompatible;
|
|
6064
|
+
}
|
|
6065
|
+
function validateStyleAttr(vnode, elm) {
|
|
6066
|
+
const { data: { style, styleDecls }, } = vnode;
|
|
6067
|
+
const elmStyle = getAttribute(elm, 'style') || '';
|
|
6068
|
+
let vnodeStyle;
|
|
6069
|
+
let nodesAreCompatible = true;
|
|
6070
|
+
if (!isUndefined$1(style) && style !== elmStyle) {
|
|
6071
|
+
nodesAreCompatible = false;
|
|
6072
|
+
vnodeStyle = style;
|
|
6073
|
+
}
|
|
6074
|
+
else if (!isUndefined$1(styleDecls)) {
|
|
6075
|
+
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
6076
|
+
const expectedStyle = [];
|
|
6077
|
+
// styleMap is used when style is set to static value.
|
|
6078
|
+
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
6079
|
+
const [prop, value, important] = styleDecls[i];
|
|
6080
|
+
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
6081
|
+
const parsedPropValue = parsedVnodeStyle[prop];
|
|
6082
|
+
if (isUndefined$1(parsedPropValue)) {
|
|
6083
|
+
nodesAreCompatible = false;
|
|
6084
|
+
}
|
|
6085
|
+
else if (!parsedPropValue.startsWith(value)) {
|
|
6086
|
+
nodesAreCompatible = false;
|
|
6087
|
+
}
|
|
6088
|
+
else if (important && !parsedPropValue.endsWith('!important')) {
|
|
6089
|
+
nodesAreCompatible = false;
|
|
6090
|
+
}
|
|
6091
|
+
}
|
|
6092
|
+
if (keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
6093
|
+
nodesAreCompatible = false;
|
|
6094
|
+
}
|
|
6095
|
+
vnodeStyle = ArrayJoin.call(expectedStyle, ';');
|
|
6096
|
+
}
|
|
6097
|
+
if (!nodesAreCompatible) {
|
|
6098
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
6099
|
+
logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
return nodesAreCompatible;
|
|
6103
|
+
}
|
|
6104
|
+
|
|
6060
6105
|
/*
|
|
6061
6106
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
6062
6107
|
* All rights reserved.
|
|
@@ -6070,5 +6115,5 @@ function setHooks(hooks) {
|
|
|
6070
6115
|
setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
|
|
6071
6116
|
}
|
|
6072
6117
|
|
|
6073
|
-
export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentHtmlPrototype, getUpgradableConstructor,
|
|
6074
|
-
/* version: 2.
|
|
6118
|
+
export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentHtmlPrototype, getUpgradableConstructor, hydrateRoot, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setAddEventListener, setAssertInstanceOfHTMLElement, setAttachShadow, setCreateComment, setCreateElement, setCreateText, setDefineCustomElement, setDispatchEvent, setGetAttribute, setGetBoundingClientRect, setGetChildNodes, setGetChildren, setGetClassList, setGetCustomElement, setGetElementsByClassName, setGetElementsByTagName, setGetFirstChild, setGetFirstElementChild, setGetLastChild, setGetLastElementChild, setGetProperty, setHTMLElement, setHooks, setInsert, setInsertGlobalStylesheet, setInsertStylesheet, setIsConnected, setIsHydrating, setIsNativeShadowDefined, setIsSyntheticShadowDefined, setNextSibling, setQuerySelector, setQuerySelectorAll, setRemove, setRemoveAttribute, setRemoveEventListener, setSetAttribute, setSetCSSStyleProperty, setSetProperty, setSetText, setSsr, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
|
|
6119
|
+
/* version: 2.12.0 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lwc/engine-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Core LWC engine APIs.",
|
|
5
5
|
"homepage": "https://lwc.dev/",
|
|
6
6
|
"repository": {
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"clean": "rm -rf dist/ types/",
|
|
20
|
-
"build": "rollup --config scripts/rollup.config.js"
|
|
20
|
+
"build": "rollup --config scripts/rollup.config.js",
|
|
21
|
+
"dev": "rollup --config scripts/rollup.config.js --watch --no-watch.clearScreen"
|
|
21
22
|
},
|
|
22
23
|
"files": [
|
|
23
24
|
"dist/",
|
|
24
25
|
"types/"
|
|
25
26
|
],
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@lwc/features": "2.
|
|
28
|
-
"@lwc/shared": "2.
|
|
28
|
+
"@lwc/features": "2.12.0",
|
|
29
|
+
"@lwc/shared": "2.12.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"observable-membrane": "2.0.0"
|
|
32
33
|
},
|
|
33
34
|
"publishConfig": {
|
|
34
35
|
"access": "public"
|
|
35
|
-
}
|
|
36
|
-
"gitHead": "94040389ab8fc717b8753e503f659489480a327d"
|
|
36
|
+
}
|
|
37
37
|
}
|
|
@@ -7,9 +7,9 @@ import { VNodes } from './vnodes';
|
|
|
7
7
|
* INTERNAL: This function can only be invoked by compiled code. The compiler
|
|
8
8
|
* will prevent this function from being imported by userland code.
|
|
9
9
|
*/
|
|
10
|
-
export declare function registerComponent(Ctor:
|
|
10
|
+
export declare function registerComponent(Ctor: any, { tmpl }: {
|
|
11
11
|
tmpl: Template;
|
|
12
|
-
}):
|
|
12
|
+
}): any;
|
|
13
13
|
export declare function getComponentRegisteredTemplate(Ctor: LightningElementConstructor): Template | undefined;
|
|
14
14
|
export declare function getTemplateReactiveObserver(vm: VM): ReactiveObserver;
|
|
15
15
|
export declare function renderComponent(vm: VM): VNodes;
|
|
@@ -7,7 +7,8 @@ export { default as wire } from './decorators/wire';
|
|
|
7
7
|
export { readonly } from './readonly';
|
|
8
8
|
export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
|
|
9
9
|
export { getComponentHtmlPrototype } from './def';
|
|
10
|
-
export { createVM, connectRootElement, disconnectRootElement, getAssociatedVMIfPresent,
|
|
10
|
+
export { createVM, connectRootElement, disconnectRootElement, getAssociatedVMIfPresent, } from './vm';
|
|
11
|
+
export { hydrateRoot } from './hydration';
|
|
11
12
|
export { registerComponent } from './component';
|
|
12
13
|
export { registerTemplate } from './secure-template';
|
|
13
14
|
export { registerDecorators } from './decorators/register';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { VM } from './vm';
|
|
2
|
-
import { VNodes, VCustomElement } from './vnodes';
|
|
2
|
+
import { VNode, VNodes, VCustomElement } from './vnodes';
|
|
3
3
|
export declare function patchChildren(c1: VNodes, c2: VNodes, parent: ParentNode): void;
|
|
4
|
+
export declare function mount(node: VNode, parent: ParentNode, anchor: Node | null): void;
|
|
5
|
+
export declare function removeNode(node: Node, parent: ParentNode): void;
|
|
4
6
|
export declare function allocateChildren(vnode: VCustomElement, vm: VM): void;
|
|
5
7
|
export declare function markAsDynamicChildren(children: VNodes): void;
|
package/types/framework/vm.d.ts
CHANGED
|
@@ -123,10 +123,8 @@ export interface VM<N = HostNode, E = HostElement> {
|
|
|
123
123
|
declare type VMAssociable = HostNode | LightningElement;
|
|
124
124
|
export declare function rerenderVM(vm: VM): void;
|
|
125
125
|
export declare function connectRootElement(elm: any): void;
|
|
126
|
-
export declare function hydrateRootElement(elm: any): void;
|
|
127
126
|
export declare function disconnectRootElement(elm: any): void;
|
|
128
127
|
export declare function appendVM(vm: VM): void;
|
|
129
|
-
export declare function hydrateVM(vm: VM): void;
|
|
130
128
|
export declare function removeVM(vm: VM): void;
|
|
131
129
|
export declare function createVM<HostNode, HostElement>(elm: HostElement, ctor: LightningElementConstructor, options: {
|
|
132
130
|
mode: ShadowRootMode;
|
|
@@ -136,6 +134,7 @@ export declare function createVM<HostNode, HostElement>(elm: HostElement, ctor:
|
|
|
136
134
|
export declare function associateVM(obj: VMAssociable, vm: VM): void;
|
|
137
135
|
export declare function getAssociatedVM(obj: VMAssociable): VM;
|
|
138
136
|
export declare function getAssociatedVMIfPresent(obj: VMAssociable): VM | undefined;
|
|
137
|
+
export declare function runRenderedCallback(vm: VM): void;
|
|
139
138
|
export declare function runConnectedCallback(vm: VM): void;
|
|
140
139
|
export declare function resetComponentRoot(vm: VM): void;
|
|
141
140
|
export declare function scheduleRehydration(vm: VM): void;
|