@lwc/engine-core 2.7.3 → 2.7.4
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 +857 -784
- package/dist/engine-core.js +855 -782
- package/package.json +4 -4
- package/types/framework/api.d.ts +1 -1
- package/types/framework/component.d.ts +1 -1
- package/types/framework/def.d.ts +1 -0
- package/types/framework/hydration.d.ts +3 -0
- package/types/framework/invoker.d.ts +1 -1
- package/types/framework/main.d.ts +1 -1
- package/types/framework/modules/attrs.d.ts +2 -2
- package/types/framework/modules/computed-class-attr.d.ts +2 -2
- package/types/framework/modules/computed-style-attr.d.ts +2 -2
- package/types/framework/modules/events.d.ts +2 -2
- package/types/framework/modules/props.d.ts +2 -2
- package/types/framework/modules/static-class-attr.d.ts +2 -2
- package/types/framework/modules/static-style-attr.d.ts +2 -2
- package/types/framework/rendering.d.ts +9 -0
- package/types/framework/services.d.ts +1 -1
- package/types/framework/stylesheet.d.ts +1 -1
- package/types/framework/template.d.ts +1 -1
- package/types/framework/vm.d.ts +10 -5
- package/types/{3rdparty/snabbdom/types.d.ts → framework/vnodes.d.ts} +32 -32
- package/types/3rdparty/snabbdom/snabbdom.d.ts +0 -11
- package/types/framework/hooks.d.ts +0 -18
package/dist/engine-core.cjs.js
CHANGED
|
@@ -400,6 +400,24 @@ function getErrorComponentStack(vm) {
|
|
|
400
400
|
return wcStack.reverse().join('\n\t');
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
/*
|
|
404
|
+
* Copyright (c) 2018, salesforce.com, inc.
|
|
405
|
+
* All rights reserved.
|
|
406
|
+
* SPDX-License-Identifier: MIT
|
|
407
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
408
|
+
*/
|
|
409
|
+
function addErrorComponentStack(vm, error) {
|
|
410
|
+
if (!shared.isFrozen(error) && shared.isUndefined(error.wcStack)) {
|
|
411
|
+
const wcStack = getErrorComponentStack(vm);
|
|
412
|
+
shared.defineProperty(error, 'wcStack', {
|
|
413
|
+
get() {
|
|
414
|
+
return wcStack;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
403
421
|
/*
|
|
404
422
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
405
423
|
* All rights reserved.
|
|
@@ -441,205 +459,10 @@ function logWarn(message, vm) {
|
|
|
441
459
|
* SPDX-License-Identifier: MIT
|
|
442
460
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
443
461
|
*/
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
function sameVnode(vnode1, vnode2) {
|
|
450
|
-
return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function isVNode(vnode) {
|
|
454
|
-
return vnode != null;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
function createKeyToOldIdx(children, beginIdx, endIdx) {
|
|
458
|
-
const map = {};
|
|
459
|
-
let j, key, ch; // TODO [#1637]: simplify this by assuming that all vnodes has keys
|
|
460
|
-
|
|
461
|
-
for (j = beginIdx; j <= endIdx; ++j) {
|
|
462
|
-
ch = children[j];
|
|
463
|
-
|
|
464
|
-
if (isVNode(ch)) {
|
|
465
|
-
key = ch.key;
|
|
466
|
-
|
|
467
|
-
if (key !== undefined) {
|
|
468
|
-
map[key] = j;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
return map;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
|
|
477
|
-
for (; startIdx <= endIdx; ++startIdx) {
|
|
478
|
-
const ch = vnodes[startIdx];
|
|
479
|
-
|
|
480
|
-
if (isVNode(ch)) {
|
|
481
|
-
ch.hook.create(ch);
|
|
482
|
-
ch.hook.insert(ch, parentElm, before);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
|
|
488
|
-
for (; startIdx <= endIdx; ++startIdx) {
|
|
489
|
-
const ch = vnodes[startIdx]; // text nodes do not have logic associated to them
|
|
490
|
-
|
|
491
|
-
if (isVNode(ch)) {
|
|
492
|
-
ch.hook.remove(ch, parentElm);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
function updateDynamicChildren(parentElm, oldCh, newCh) {
|
|
498
|
-
let oldStartIdx = 0;
|
|
499
|
-
let newStartIdx = 0;
|
|
500
|
-
let oldEndIdx = oldCh.length - 1;
|
|
501
|
-
let oldStartVnode = oldCh[0];
|
|
502
|
-
let oldEndVnode = oldCh[oldEndIdx];
|
|
503
|
-
const newChEnd = newCh.length - 1;
|
|
504
|
-
let newEndIdx = newChEnd;
|
|
505
|
-
let newStartVnode = newCh[0];
|
|
506
|
-
let newEndVnode = newCh[newEndIdx];
|
|
507
|
-
let oldKeyToIdx;
|
|
508
|
-
let idxInOld;
|
|
509
|
-
let elmToMove;
|
|
510
|
-
let before;
|
|
511
|
-
|
|
512
|
-
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|
513
|
-
if (!isVNode(oldStartVnode)) {
|
|
514
|
-
oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
|
|
515
|
-
} else if (!isVNode(oldEndVnode)) {
|
|
516
|
-
oldEndVnode = oldCh[--oldEndIdx];
|
|
517
|
-
} else if (!isVNode(newStartVnode)) {
|
|
518
|
-
newStartVnode = newCh[++newStartIdx];
|
|
519
|
-
} else if (!isVNode(newEndVnode)) {
|
|
520
|
-
newEndVnode = newCh[--newEndIdx];
|
|
521
|
-
} else if (sameVnode(oldStartVnode, newStartVnode)) {
|
|
522
|
-
patchVnode(oldStartVnode, newStartVnode);
|
|
523
|
-
oldStartVnode = oldCh[++oldStartIdx];
|
|
524
|
-
newStartVnode = newCh[++newStartIdx];
|
|
525
|
-
} else if (sameVnode(oldEndVnode, newEndVnode)) {
|
|
526
|
-
patchVnode(oldEndVnode, newEndVnode);
|
|
527
|
-
oldEndVnode = oldCh[--oldEndIdx];
|
|
528
|
-
newEndVnode = newCh[--newEndIdx];
|
|
529
|
-
} else if (sameVnode(oldStartVnode, newEndVnode)) {
|
|
530
|
-
// Vnode moved right
|
|
531
|
-
patchVnode(oldStartVnode, newEndVnode);
|
|
532
|
-
newEndVnode.hook.move(oldStartVnode, parentElm, nextSibling(oldEndVnode.elm));
|
|
533
|
-
oldStartVnode = oldCh[++oldStartIdx];
|
|
534
|
-
newEndVnode = newCh[--newEndIdx];
|
|
535
|
-
} else if (sameVnode(oldEndVnode, newStartVnode)) {
|
|
536
|
-
// Vnode moved left
|
|
537
|
-
patchVnode(oldEndVnode, newStartVnode);
|
|
538
|
-
newStartVnode.hook.move(oldEndVnode, parentElm, oldStartVnode.elm);
|
|
539
|
-
oldEndVnode = oldCh[--oldEndIdx];
|
|
540
|
-
newStartVnode = newCh[++newStartIdx];
|
|
541
|
-
} else {
|
|
542
|
-
if (oldKeyToIdx === undefined) {
|
|
543
|
-
oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
idxInOld = oldKeyToIdx[newStartVnode.key];
|
|
547
|
-
|
|
548
|
-
if (isUndef(idxInOld)) {
|
|
549
|
-
// New element
|
|
550
|
-
newStartVnode.hook.create(newStartVnode);
|
|
551
|
-
newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
|
|
552
|
-
newStartVnode = newCh[++newStartIdx];
|
|
553
|
-
} else {
|
|
554
|
-
elmToMove = oldCh[idxInOld];
|
|
555
|
-
|
|
556
|
-
if (isVNode(elmToMove)) {
|
|
557
|
-
if (elmToMove.sel !== newStartVnode.sel) {
|
|
558
|
-
// New element
|
|
559
|
-
newStartVnode.hook.create(newStartVnode);
|
|
560
|
-
newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
|
|
561
|
-
} else {
|
|
562
|
-
patchVnode(elmToMove, newStartVnode);
|
|
563
|
-
oldCh[idxInOld] = undefined;
|
|
564
|
-
newStartVnode.hook.move(elmToMove, parentElm, oldStartVnode.elm);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
newStartVnode = newCh[++newStartIdx];
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
|
|
574
|
-
if (oldStartIdx > oldEndIdx) {
|
|
575
|
-
// There's some cases in which the sub array of vnodes to be inserted is followed by null(s) and an
|
|
576
|
-
// already processed vnode, in such cases the vnodes to be inserted should be before that processed vnode.
|
|
577
|
-
let i = newEndIdx;
|
|
578
|
-
let n;
|
|
579
|
-
|
|
580
|
-
do {
|
|
581
|
-
n = newCh[++i];
|
|
582
|
-
} while (!isVNode(n) && i < newChEnd);
|
|
583
|
-
|
|
584
|
-
before = isVNode(n) ? n.elm : null;
|
|
585
|
-
addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx);
|
|
586
|
-
} else {
|
|
587
|
-
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
function updateStaticChildren(parentElm, oldCh, newCh) {
|
|
592
|
-
const oldChLength = oldCh.length;
|
|
593
|
-
const newChLength = newCh.length;
|
|
594
|
-
|
|
595
|
-
if (oldChLength === 0) {
|
|
596
|
-
// the old list is empty, we can directly insert anything new
|
|
597
|
-
addVnodes(parentElm, null, newCh, 0, newChLength);
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
if (newChLength === 0) {
|
|
602
|
-
// the old list is nonempty and the new list is empty so we can directly remove all old nodes
|
|
603
|
-
// this is the case in which the dynamic children of an if-directive should be removed
|
|
604
|
-
removeVnodes(parentElm, oldCh, 0, oldChLength);
|
|
605
|
-
return;
|
|
606
|
-
} // if the old list is not empty, the new list MUST have the same
|
|
607
|
-
// amount of nodes, that's why we call this static children
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
let referenceElm = null;
|
|
611
|
-
|
|
612
|
-
for (let i = newChLength - 1; i >= 0; i -= 1) {
|
|
613
|
-
const vnode = newCh[i];
|
|
614
|
-
const oldVNode = oldCh[i];
|
|
615
|
-
|
|
616
|
-
if (vnode !== oldVNode) {
|
|
617
|
-
if (isVNode(oldVNode)) {
|
|
618
|
-
if (isVNode(vnode)) {
|
|
619
|
-
// both vnodes must be equivalent, and se just need to patch them
|
|
620
|
-
patchVnode(oldVNode, vnode);
|
|
621
|
-
referenceElm = vnode.elm;
|
|
622
|
-
} else {
|
|
623
|
-
// removing the old vnode since the new one is null
|
|
624
|
-
oldVNode.hook.remove(oldVNode, parentElm);
|
|
625
|
-
}
|
|
626
|
-
} else if (isVNode(vnode)) {
|
|
627
|
-
// this condition is unnecessary
|
|
628
|
-
vnode.hook.create(vnode); // insert the new node one since the old one is null
|
|
629
|
-
|
|
630
|
-
vnode.hook.insert(vnode, parentElm, referenceElm);
|
|
631
|
-
referenceElm = vnode.elm;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function patchVnode(oldVnode, vnode) {
|
|
638
|
-
if (oldVnode !== vnode) {
|
|
639
|
-
vnode.elm = oldVnode.elm;
|
|
640
|
-
vnode.hook.update(oldVnode, vnode);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
462
|
+
// This is a temporary workaround to get the @lwc/engine-server to evaluate in node without having
|
|
463
|
+
// to inject at runtime.
|
|
464
|
+
const HTMLElementConstructor = typeof HTMLElement !== 'undefined' ? HTMLElement : function () {};
|
|
465
|
+
const HTMLElementPrototype = HTMLElementConstructor.prototype;
|
|
643
466
|
|
|
644
467
|
/*
|
|
645
468
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -757,6 +580,40 @@ function unlockAttribute(elm, key) {
|
|
|
757
580
|
controlledAttributeName = key;
|
|
758
581
|
}
|
|
759
582
|
|
|
583
|
+
/*
|
|
584
|
+
* Copyright (c) 2018, salesforce.com, inc.
|
|
585
|
+
* All rights reserved.
|
|
586
|
+
* SPDX-License-Identifier: MIT
|
|
587
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
588
|
+
*/
|
|
589
|
+
/**
|
|
590
|
+
* This is a descriptor map that contains
|
|
591
|
+
* all standard properties that a Custom Element can support (including AOM properties), which
|
|
592
|
+
* determines what kind of capabilities the Base HTML Element and
|
|
593
|
+
* Base Lightning Element should support.
|
|
594
|
+
*/
|
|
595
|
+
|
|
596
|
+
const HTMLElementOriginalDescriptors = shared.create(null);
|
|
597
|
+
shared.forEach.call(shared.keys(shared.AriaPropNameToAttrNameMap), propName => {
|
|
598
|
+
// Note: intentionally using our in-house getPropertyDescriptor instead of getOwnPropertyDescriptor here because
|
|
599
|
+
// in IE11, some properties are on Element.prototype instead of HTMLElement, just to be sure.
|
|
600
|
+
const descriptor = shared.getPropertyDescriptor(HTMLElementPrototype, propName);
|
|
601
|
+
|
|
602
|
+
if (!shared.isUndefined(descriptor)) {
|
|
603
|
+
HTMLElementOriginalDescriptors[propName] = descriptor;
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
shared.forEach.call(defaultDefHTMLPropertyNames, propName => {
|
|
607
|
+
// Note: intentionally using our in-house getPropertyDescriptor instead of getOwnPropertyDescriptor here because
|
|
608
|
+
// in IE11, id property is on Element.prototype instead of HTMLElement, and we suspect that more will fall into
|
|
609
|
+
// this category, so, better to be sure.
|
|
610
|
+
const descriptor = shared.getPropertyDescriptor(HTMLElementPrototype, propName);
|
|
611
|
+
|
|
612
|
+
if (!shared.isUndefined(descriptor)) {
|
|
613
|
+
HTMLElementOriginalDescriptors[propName] = descriptor;
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
|
|
760
617
|
/*
|
|
761
618
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
762
619
|
* All rights reserved.
|
|
@@ -1121,53 +978,8 @@ function patchLightningElementPrototypeWithRestrictions(proto) {
|
|
|
1121
978
|
shared.defineProperties(proto, getLightningElementPrototypeRestrictionsDescriptors(proto));
|
|
1122
979
|
}
|
|
1123
980
|
|
|
1124
|
-
|
|
1125
|
-
* Copyright (
|
|
1126
|
-
* All rights reserved.
|
|
1127
|
-
* SPDX-License-Identifier: MIT
|
|
1128
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
1129
|
-
*/
|
|
1130
|
-
// This is a temporary workaround to get the @lwc/engine-server to evaluate in node without having
|
|
1131
|
-
// to inject at runtime.
|
|
1132
|
-
const HTMLElementConstructor = typeof HTMLElement !== 'undefined' ? HTMLElement : function () {};
|
|
1133
|
-
const HTMLElementPrototype = HTMLElementConstructor.prototype;
|
|
1134
|
-
|
|
1135
|
-
/*
|
|
1136
|
-
* Copyright (c) 2018, salesforce.com, inc.
|
|
1137
|
-
* All rights reserved.
|
|
1138
|
-
* SPDX-License-Identifier: MIT
|
|
1139
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
1140
|
-
*/
|
|
1141
|
-
/**
|
|
1142
|
-
* This is a descriptor map that contains
|
|
1143
|
-
* all standard properties that a Custom Element can support (including AOM properties), which
|
|
1144
|
-
* determines what kind of capabilities the Base HTML Element and
|
|
1145
|
-
* Base Lightning Element should support.
|
|
1146
|
-
*/
|
|
1147
|
-
|
|
1148
|
-
const HTMLElementOriginalDescriptors = shared.create(null);
|
|
1149
|
-
shared.forEach.call(shared.keys(shared.AriaPropNameToAttrNameMap), propName => {
|
|
1150
|
-
// Note: intentionally using our in-house getPropertyDescriptor instead of getOwnPropertyDescriptor here because
|
|
1151
|
-
// in IE11, some properties are on Element.prototype instead of HTMLElement, just to be sure.
|
|
1152
|
-
const descriptor = shared.getPropertyDescriptor(HTMLElementPrototype, propName);
|
|
1153
|
-
|
|
1154
|
-
if (!shared.isUndefined(descriptor)) {
|
|
1155
|
-
HTMLElementOriginalDescriptors[propName] = descriptor;
|
|
1156
|
-
}
|
|
1157
|
-
});
|
|
1158
|
-
shared.forEach.call(defaultDefHTMLPropertyNames, propName => {
|
|
1159
|
-
// Note: intentionally using our in-house getPropertyDescriptor instead of getOwnPropertyDescriptor here because
|
|
1160
|
-
// in IE11, id property is on Element.prototype instead of HTMLElement, and we suspect that more will fall into
|
|
1161
|
-
// this category, so, better to be sure.
|
|
1162
|
-
const descriptor = shared.getPropertyDescriptor(HTMLElementPrototype, propName);
|
|
1163
|
-
|
|
1164
|
-
if (!shared.isUndefined(descriptor)) {
|
|
1165
|
-
HTMLElementOriginalDescriptors[propName] = descriptor;
|
|
1166
|
-
}
|
|
1167
|
-
});
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
* Copyright (C) 2017 salesforce.com, inc.
|
|
981
|
+
/**
|
|
982
|
+
* Copyright (C) 2017 salesforce.com, inc.
|
|
1171
983
|
*/
|
|
1172
984
|
const {
|
|
1173
985
|
isArray
|
|
@@ -2082,7 +1894,9 @@ const LightningElement = function () {
|
|
|
2082
1894
|
if (vm.renderMode === 1
|
|
2083
1895
|
/* Shadow */
|
|
2084
1896
|
) {
|
|
2085
|
-
doAttachShadow(vm);
|
|
1897
|
+
vm.renderRoot = doAttachShadow(vm);
|
|
1898
|
+
} else {
|
|
1899
|
+
vm.renderRoot = elm;
|
|
2086
1900
|
} // Adding extra guard rails in DEV mode.
|
|
2087
1901
|
|
|
2088
1902
|
|
|
@@ -2103,19 +1917,21 @@ function doAttachShadow(vm) {
|
|
|
2103
1917
|
ctor
|
|
2104
1918
|
}
|
|
2105
1919
|
} = vm;
|
|
2106
|
-
const
|
|
1920
|
+
const shadowRoot = attachShadow(elm, {
|
|
2107
1921
|
[shared.KEY__SYNTHETIC_MODE]: shadowMode === 1
|
|
2108
1922
|
/* Synthetic */
|
|
2109
1923
|
,
|
|
2110
1924
|
delegatesFocus: Boolean(ctor.delegatesFocus),
|
|
2111
1925
|
mode
|
|
2112
1926
|
});
|
|
2113
|
-
vm.
|
|
2114
|
-
associateVM(
|
|
1927
|
+
vm.shadowRoot = shadowRoot;
|
|
1928
|
+
associateVM(shadowRoot, vm);
|
|
2115
1929
|
|
|
2116
1930
|
if (process.env.NODE_ENV !== 'production') {
|
|
2117
|
-
patchShadowRootWithRestrictions(
|
|
1931
|
+
patchShadowRootWithRestrictions(shadowRoot);
|
|
2118
1932
|
}
|
|
1933
|
+
|
|
1934
|
+
return shadowRoot;
|
|
2119
1935
|
}
|
|
2120
1936
|
|
|
2121
1937
|
function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
|
|
@@ -2283,7 +2099,7 @@ LightningElement.prototype = {
|
|
|
2283
2099
|
}
|
|
2284
2100
|
}
|
|
2285
2101
|
|
|
2286
|
-
return vm.
|
|
2102
|
+
return vm.shadowRoot;
|
|
2287
2103
|
},
|
|
2288
2104
|
|
|
2289
2105
|
get shadowRoot() {
|
|
@@ -3667,6 +3483,10 @@ function getComponentInternalDef(Ctor) {
|
|
|
3667
3483
|
|
|
3668
3484
|
return def;
|
|
3669
3485
|
}
|
|
3486
|
+
function getComponentHtmlPrototype(Ctor) {
|
|
3487
|
+
const def = getComponentInternalDef(Ctor);
|
|
3488
|
+
return def.bridge;
|
|
3489
|
+
}
|
|
3670
3490
|
const lightingElementDef = {
|
|
3671
3491
|
ctor: LightningElement,
|
|
3672
3492
|
name: LightningElement.name,
|
|
@@ -3730,14 +3550,68 @@ function getComponentDef(Ctor) {
|
|
|
3730
3550
|
};
|
|
3731
3551
|
}
|
|
3732
3552
|
|
|
3553
|
+
/*
|
|
3554
|
+
* Copyright (c) 2020, salesforce.com, inc.
|
|
3555
|
+
* All rights reserved.
|
|
3556
|
+
* SPDX-License-Identifier: MIT
|
|
3557
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3558
|
+
*/
|
|
3559
|
+
function getUpgradableConstructor(tagName) {
|
|
3560
|
+
// Should never get a tag with upper case letter at this point, the compiler should
|
|
3561
|
+
// produce only tags with lowercase letters
|
|
3562
|
+
// But, for backwards compatibility, we will lower case the tagName
|
|
3563
|
+
tagName = tagName.toLowerCase();
|
|
3564
|
+
let CE = getCustomElement(tagName);
|
|
3565
|
+
|
|
3566
|
+
if (!shared.isUndefined(CE)) {
|
|
3567
|
+
return CE;
|
|
3568
|
+
}
|
|
3569
|
+
/**
|
|
3570
|
+
* LWC Upgradable Element reference to an element that was created
|
|
3571
|
+
* via the scoped registry mechanism, and that is ready to be upgraded.
|
|
3572
|
+
*/
|
|
3573
|
+
|
|
3574
|
+
|
|
3575
|
+
CE = class LWCUpgradableElement extends HTMLElementExported {
|
|
3576
|
+
constructor(upgradeCallback) {
|
|
3577
|
+
super();
|
|
3578
|
+
|
|
3579
|
+
if (shared.isFunction(upgradeCallback)) {
|
|
3580
|
+
upgradeCallback(this); // nothing to do with the result for now
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
};
|
|
3585
|
+
defineCustomElement(tagName, CE);
|
|
3586
|
+
return CE;
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3589
|
+
/*
|
|
3590
|
+
* Copyright (c) 2018, salesforce.com, inc.
|
|
3591
|
+
* All rights reserved.
|
|
3592
|
+
* SPDX-License-Identifier: MIT
|
|
3593
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3594
|
+
*/
|
|
3595
|
+
function isVBaseElement(vnode) {
|
|
3596
|
+
const {
|
|
3597
|
+
type
|
|
3598
|
+
} = vnode;
|
|
3599
|
+
return type === 2
|
|
3600
|
+
/* Element */
|
|
3601
|
+
|| type === 3
|
|
3602
|
+
/* CustomElement */
|
|
3603
|
+
;
|
|
3604
|
+
}
|
|
3605
|
+
function isSameVnode(vnode1, vnode2) {
|
|
3606
|
+
return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
|
|
3607
|
+
}
|
|
3608
|
+
|
|
3733
3609
|
/*
|
|
3734
3610
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
3735
3611
|
* All rights reserved.
|
|
3736
3612
|
* SPDX-License-Identifier: MIT
|
|
3737
3613
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
3738
3614
|
*/
|
|
3739
|
-
const xlinkNS = 'http://www.w3.org/1999/xlink';
|
|
3740
|
-
const xmlNS = 'http://www.w3.org/XML/1998/namespace';
|
|
3741
3615
|
const ColonCharCode = 58;
|
|
3742
3616
|
function patchAttributes(oldVnode, vnode) {
|
|
3743
3617
|
const {
|
|
@@ -3767,10 +3641,10 @@ function patchAttributes(oldVnode, vnode) {
|
|
|
3767
3641
|
|
|
3768
3642
|
if (shared.StringCharCodeAt.call(key, 3) === ColonCharCode) {
|
|
3769
3643
|
// Assume xml namespace
|
|
3770
|
-
setAttribute(elm, key, cur,
|
|
3644
|
+
setAttribute(elm, key, cur, shared.XML_NAMESPACE);
|
|
3771
3645
|
} else if (shared.StringCharCodeAt.call(key, 5) === ColonCharCode) {
|
|
3772
3646
|
// Assume xlink namespace
|
|
3773
|
-
setAttribute(elm, key, cur,
|
|
3647
|
+
setAttribute(elm, key, cur, shared.XLINK_NAMESPACE);
|
|
3774
3648
|
} else if (shared.isNull(cur) || shared.isUndefined(cur)) {
|
|
3775
3649
|
removeAttribute(elm, key);
|
|
3776
3650
|
} else {
|
|
@@ -4021,6 +3895,160 @@ function applyStaticStyleAttribute(vnode) {
|
|
|
4021
3895
|
* SPDX-License-Identifier: MIT
|
|
4022
3896
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4023
3897
|
*/
|
|
3898
|
+
const TextHook = {
|
|
3899
|
+
create: vnode => {
|
|
3900
|
+
const {
|
|
3901
|
+
owner
|
|
3902
|
+
} = vnode;
|
|
3903
|
+
const elm = createText(vnode.text);
|
|
3904
|
+
linkNodeToShadow(elm, owner);
|
|
3905
|
+
vnode.elm = elm;
|
|
3906
|
+
},
|
|
3907
|
+
update: updateNodeHook,
|
|
3908
|
+
insert: insertNode,
|
|
3909
|
+
move: insertNode,
|
|
3910
|
+
remove: removeNode
|
|
3911
|
+
};
|
|
3912
|
+
const CommentHook = {
|
|
3913
|
+
create: vnode => {
|
|
3914
|
+
const {
|
|
3915
|
+
owner,
|
|
3916
|
+
text
|
|
3917
|
+
} = vnode;
|
|
3918
|
+
const elm = createComment(text);
|
|
3919
|
+
linkNodeToShadow(elm, owner);
|
|
3920
|
+
vnode.elm = elm;
|
|
3921
|
+
},
|
|
3922
|
+
update: updateNodeHook,
|
|
3923
|
+
insert: insertNode,
|
|
3924
|
+
move: insertNode,
|
|
3925
|
+
remove: removeNode
|
|
3926
|
+
}; // insert is called after update, which is used somewhere else (via a module)
|
|
3927
|
+
// to mark the vm as inserted, that means we cannot use update as the main channel
|
|
3928
|
+
// to rehydrate when dirty, because sometimes the element is not inserted just yet,
|
|
3929
|
+
// which breaks some invariants. For that reason, we have the following for any
|
|
3930
|
+
// Custom Element that is inserted via a template.
|
|
3931
|
+
|
|
3932
|
+
const ElementHook = {
|
|
3933
|
+
create: vnode => {
|
|
3934
|
+
const {
|
|
3935
|
+
sel,
|
|
3936
|
+
owner,
|
|
3937
|
+
data: {
|
|
3938
|
+
svg
|
|
3939
|
+
}
|
|
3940
|
+
} = vnode;
|
|
3941
|
+
const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
|
|
3942
|
+
const elm = createElement(sel, namespace);
|
|
3943
|
+
linkNodeToShadow(elm, owner);
|
|
3944
|
+
fallbackElmHook(elm, vnode);
|
|
3945
|
+
vnode.elm = elm;
|
|
3946
|
+
patchElementPropsAndAttrs$1(null, vnode);
|
|
3947
|
+
},
|
|
3948
|
+
update: (oldVnode, vnode) => {
|
|
3949
|
+
patchElementPropsAndAttrs$1(oldVnode, vnode);
|
|
3950
|
+
patchChildren(vnode.elm, oldVnode.children, vnode.children);
|
|
3951
|
+
},
|
|
3952
|
+
insert: (vnode, parentNode, referenceNode) => {
|
|
3953
|
+
insertNode(vnode, parentNode, referenceNode);
|
|
3954
|
+
createChildrenHook(vnode);
|
|
3955
|
+
},
|
|
3956
|
+
move: insertNode,
|
|
3957
|
+
remove: (vnode, parentNode) => {
|
|
3958
|
+
removeNode(vnode, parentNode);
|
|
3959
|
+
removeChildren(vnode);
|
|
3960
|
+
}
|
|
3961
|
+
};
|
|
3962
|
+
const CustomElementHook = {
|
|
3963
|
+
create: vnode => {
|
|
3964
|
+
const {
|
|
3965
|
+
sel,
|
|
3966
|
+
owner
|
|
3967
|
+
} = vnode;
|
|
3968
|
+
const UpgradableConstructor = getUpgradableConstructor(sel);
|
|
3969
|
+
/**
|
|
3970
|
+
* Note: if the upgradable constructor does not expect, or throw when we new it
|
|
3971
|
+
* with a callback as the first argument, we could implement a more advanced
|
|
3972
|
+
* mechanism that only passes that argument if the constructor is known to be
|
|
3973
|
+
* an upgradable custom element.
|
|
3974
|
+
*/
|
|
3975
|
+
|
|
3976
|
+
let vm;
|
|
3977
|
+
const elm = new UpgradableConstructor(elm => {
|
|
3978
|
+
// the custom element from the registry is expecting an upgrade callback
|
|
3979
|
+
vm = createViewModelHook(elm, vnode);
|
|
3980
|
+
});
|
|
3981
|
+
linkNodeToShadow(elm, owner);
|
|
3982
|
+
vnode.elm = elm;
|
|
3983
|
+
|
|
3984
|
+
if (vm) {
|
|
3985
|
+
allocateChildren(vnode, vm);
|
|
3986
|
+
} else if (vnode.ctor !== UpgradableConstructor) {
|
|
3987
|
+
throw new TypeError(`Incorrect Component Constructor`);
|
|
3988
|
+
}
|
|
3989
|
+
|
|
3990
|
+
patchElementPropsAndAttrs$1(null, vnode);
|
|
3991
|
+
},
|
|
3992
|
+
update: (oldVnode, vnode) => {
|
|
3993
|
+
patchElementPropsAndAttrs$1(oldVnode, vnode);
|
|
3994
|
+
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
3995
|
+
|
|
3996
|
+
if (vm) {
|
|
3997
|
+
// in fallback mode, the allocation will always set children to
|
|
3998
|
+
// empty and delegate the real allocation to the slot elements
|
|
3999
|
+
allocateChildren(vnode, vm);
|
|
4000
|
+
} // in fallback mode, the children will be always empty, so, nothing
|
|
4001
|
+
// will happen, but in native, it does allocate the light dom
|
|
4002
|
+
|
|
4003
|
+
|
|
4004
|
+
patchChildren(vnode.elm, oldVnode.children, vnode.children);
|
|
4005
|
+
|
|
4006
|
+
if (vm) {
|
|
4007
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4008
|
+
shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
|
|
4009
|
+
} // this will probably update the shadowRoot, but only if the vm is in a dirty state
|
|
4010
|
+
// this is important to preserve the top to bottom synchronous rendering phase.
|
|
4011
|
+
|
|
4012
|
+
|
|
4013
|
+
rerenderVM(vm);
|
|
4014
|
+
}
|
|
4015
|
+
},
|
|
4016
|
+
insert: (vnode, parentNode, referenceNode) => {
|
|
4017
|
+
insertNode(vnode, parentNode, referenceNode);
|
|
4018
|
+
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
4019
|
+
|
|
4020
|
+
if (vm) {
|
|
4021
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4022
|
+
shared.assert.isTrue(vm.state === 0
|
|
4023
|
+
/* created */
|
|
4024
|
+
, `${vm} cannot be recycled.`);
|
|
4025
|
+
}
|
|
4026
|
+
|
|
4027
|
+
runConnectedCallback(vm);
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4030
|
+
createChildrenHook(vnode);
|
|
4031
|
+
|
|
4032
|
+
if (vm) {
|
|
4033
|
+
appendVM(vm);
|
|
4034
|
+
}
|
|
4035
|
+
},
|
|
4036
|
+
move: insertNode,
|
|
4037
|
+
remove: (vnode, parentNode) => {
|
|
4038
|
+
removeNode(vnode, parentNode);
|
|
4039
|
+
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
4040
|
+
|
|
4041
|
+
if (vm) {
|
|
4042
|
+
// for custom elements we don't have to go recursively because the removeVM routine
|
|
4043
|
+
// will take care of disconnecting any child VM attached to its shadow as well.
|
|
4044
|
+
removeVM(vm);
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
};
|
|
4048
|
+
|
|
4049
|
+
function isVNode(vnode) {
|
|
4050
|
+
return vnode != null;
|
|
4051
|
+
}
|
|
4024
4052
|
|
|
4025
4053
|
function observeElementChildNodes(elm) {
|
|
4026
4054
|
elm.$domManual$ = true;
|
|
@@ -4043,6 +4071,24 @@ function setScopeTokenClassIfNecessary(elm, owner) {
|
|
|
4043
4071
|
}
|
|
4044
4072
|
}
|
|
4045
4073
|
|
|
4074
|
+
function linkNodeToShadow(elm, owner) {
|
|
4075
|
+
const {
|
|
4076
|
+
renderRoot,
|
|
4077
|
+
renderMode,
|
|
4078
|
+
shadowMode
|
|
4079
|
+
} = owner; // TODO [#1164]: this should eventually be done by the polyfill directly
|
|
4080
|
+
|
|
4081
|
+
if (isSyntheticShadowDefined) {
|
|
4082
|
+
if (shadowMode === 1
|
|
4083
|
+
/* Synthetic */
|
|
4084
|
+
|| renderMode === 0
|
|
4085
|
+
/* Light */
|
|
4086
|
+
) {
|
|
4087
|
+
elm[shared.KEY__SHADOW_RESOLVER] = renderRoot[shared.KEY__SHADOW_RESOLVER];
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
|
|
4046
4092
|
function updateNodeHook(oldVnode, vnode) {
|
|
4047
4093
|
const {
|
|
4048
4094
|
elm,
|
|
@@ -4061,7 +4107,8 @@ function updateNodeHook(oldVnode, vnode) {
|
|
|
4061
4107
|
}
|
|
4062
4108
|
}
|
|
4063
4109
|
}
|
|
4064
|
-
|
|
4110
|
+
|
|
4111
|
+
function insertNode(vnode, parentNode, referenceNode) {
|
|
4065
4112
|
if (process.env.NODE_ENV !== 'production') {
|
|
4066
4113
|
unlockDomMutation();
|
|
4067
4114
|
}
|
|
@@ -4072,7 +4119,8 @@ function insertNodeHook(vnode, parentNode, referenceNode) {
|
|
|
4072
4119
|
lockDomMutation();
|
|
4073
4120
|
}
|
|
4074
4121
|
}
|
|
4075
|
-
|
|
4122
|
+
|
|
4123
|
+
function removeNode(vnode, parentNode) {
|
|
4076
4124
|
if (process.env.NODE_ENV !== 'production') {
|
|
4077
4125
|
unlockDomMutation();
|
|
4078
4126
|
}
|
|
@@ -4083,7 +4131,8 @@ function removeNodeHook(vnode, parentNode) {
|
|
|
4083
4131
|
lockDomMutation();
|
|
4084
4132
|
}
|
|
4085
4133
|
}
|
|
4086
|
-
|
|
4134
|
+
|
|
4135
|
+
function patchElementPropsAndAttrs$1(oldVnode, vnode) {
|
|
4087
4136
|
if (shared.isNull(oldVnode)) {
|
|
4088
4137
|
applyEventListeners(vnode);
|
|
4089
4138
|
applyStaticClassAttribute(vnode);
|
|
@@ -4097,10 +4146,7 @@ function patchElementPropsAndAttrs(oldVnode, vnode) {
|
|
|
4097
4146
|
patchAttributes(oldVnode, vnode);
|
|
4098
4147
|
patchProps(oldVnode, vnode);
|
|
4099
4148
|
}
|
|
4100
|
-
|
|
4101
|
-
applyEventListeners(vnode);
|
|
4102
|
-
patchProps(null, vnode);
|
|
4103
|
-
}
|
|
4149
|
+
|
|
4104
4150
|
function fallbackElmHook(elm, vnode) {
|
|
4105
4151
|
const {
|
|
4106
4152
|
owner
|
|
@@ -4120,7 +4166,7 @@ function fallbackElmHook(elm, vnode) {
|
|
|
4120
4166
|
} = owner.context;
|
|
4121
4167
|
|
|
4122
4168
|
if (!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual"
|
|
4123
|
-
/*
|
|
4169
|
+
/* Manual */
|
|
4124
4170
|
) {
|
|
4125
4171
|
// this element will now accept any manual content inserted into it
|
|
4126
4172
|
observeElementChildNodes(elm);
|
|
@@ -4138,7 +4184,7 @@ function fallbackElmHook(elm, vnode) {
|
|
|
4138
4184
|
}
|
|
4139
4185
|
} = vnode;
|
|
4140
4186
|
const isPortal = !shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual"
|
|
4141
|
-
/*
|
|
4187
|
+
/* Manual */
|
|
4142
4188
|
;
|
|
4143
4189
|
const isLight = owner.renderMode === 0
|
|
4144
4190
|
/* Light */
|
|
@@ -4149,6 +4195,7 @@ function fallbackElmHook(elm, vnode) {
|
|
|
4149
4195
|
});
|
|
4150
4196
|
}
|
|
4151
4197
|
}
|
|
4198
|
+
|
|
4152
4199
|
function patchChildren(parent, oldCh, newCh) {
|
|
4153
4200
|
if (hasDynamicChildren(newCh)) {
|
|
4154
4201
|
updateDynamicChildren(parent, oldCh, newCh);
|
|
@@ -4156,7 +4203,7 @@ function patchChildren(parent, oldCh, newCh) {
|
|
|
4156
4203
|
updateStaticChildren(parent, oldCh, newCh);
|
|
4157
4204
|
}
|
|
4158
4205
|
}
|
|
4159
|
-
function
|
|
4206
|
+
function allocateChildren(vnode, vm) {
|
|
4160
4207
|
// A component with slots will re-render because:
|
|
4161
4208
|
// 1- There is a change of the internal state.
|
|
4162
4209
|
// 2- There is a change on the external api (ex: slots)
|
|
@@ -4187,12 +4234,14 @@ function allocateChildrenHook(vnode, vm) {
|
|
|
4187
4234
|
vnode.children = EmptyArray;
|
|
4188
4235
|
}
|
|
4189
4236
|
}
|
|
4237
|
+
|
|
4190
4238
|
function createViewModelHook(elm, vnode) {
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4239
|
+
let vm = getAssociatedVMIfPresent(elm); // There is a possibility that a custom element is registered under tagName, in which case, the
|
|
4240
|
+
// initialization is already carry on, and there is nothing else to do here since this hook is
|
|
4241
|
+
// called right after invoking `document.createElement`.
|
|
4242
|
+
|
|
4243
|
+
if (!shared.isUndefined(vm)) {
|
|
4244
|
+
return vm;
|
|
4196
4245
|
}
|
|
4197
4246
|
|
|
4198
4247
|
const {
|
|
@@ -4214,8 +4263,7 @@ function createViewModelHook(elm, vnode) {
|
|
|
4214
4263
|
setElementShadowToken(elm, stylesheetToken);
|
|
4215
4264
|
}
|
|
4216
4265
|
|
|
4217
|
-
|
|
4218
|
-
createVM(elm, def, {
|
|
4266
|
+
vm = createVM(elm, ctor, {
|
|
4219
4267
|
mode,
|
|
4220
4268
|
owner,
|
|
4221
4269
|
tagName: sel
|
|
@@ -4224,7 +4272,10 @@ function createViewModelHook(elm, vnode) {
|
|
|
4224
4272
|
if (process.env.NODE_ENV !== 'production') {
|
|
4225
4273
|
shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
|
|
4226
4274
|
}
|
|
4275
|
+
|
|
4276
|
+
return vm;
|
|
4227
4277
|
}
|
|
4278
|
+
|
|
4228
4279
|
function createChildrenHook(vnode) {
|
|
4229
4280
|
const {
|
|
4230
4281
|
elm,
|
|
@@ -4241,173 +4292,10 @@ function createChildrenHook(vnode) {
|
|
|
4241
4292
|
}
|
|
4242
4293
|
}
|
|
4243
4294
|
|
|
4244
|
-
function
|
|
4245
|
-
//
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
function vnodesAndElementHaveCompatibleAttrs(vnode, elm) {
|
|
4250
|
-
const {
|
|
4251
|
-
data: {
|
|
4252
|
-
attrs = {}
|
|
4253
|
-
}
|
|
4254
|
-
} = vnode;
|
|
4255
|
-
let nodesAreCompatible = true; // Validate attributes, though we could always recovery from those by running the update mods.
|
|
4256
|
-
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
4257
|
-
|
|
4258
|
-
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
4259
|
-
const elmAttrValue = getAttribute(elm, attrName);
|
|
4260
|
-
|
|
4261
|
-
if (String(attrValue) !== elmAttrValue) {
|
|
4262
|
-
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
4263
|
-
nodesAreCompatible = false;
|
|
4264
|
-
}
|
|
4265
|
-
}
|
|
4266
|
-
|
|
4267
|
-
return nodesAreCompatible;
|
|
4268
|
-
}
|
|
4269
|
-
|
|
4270
|
-
function vnodesAndElementHaveCompatibleClass(vnode, elm) {
|
|
4271
|
-
const {
|
|
4272
|
-
data: {
|
|
4273
|
-
className,
|
|
4274
|
-
classMap
|
|
4275
|
-
}
|
|
4276
|
-
} = vnode;
|
|
4277
|
-
let nodesAreCompatible = true;
|
|
4278
|
-
let vnodeClassName;
|
|
4279
|
-
|
|
4280
|
-
if (!shared.isUndefined(className) && String(className) !== elm.className) {
|
|
4281
|
-
// className is used when class is bound to an expr.
|
|
4282
|
-
nodesAreCompatible = false;
|
|
4283
|
-
vnodeClassName = className;
|
|
4284
|
-
} else if (!shared.isUndefined(classMap)) {
|
|
4285
|
-
// classMap is used when class is set to static value.
|
|
4286
|
-
const classList = getClassList(elm);
|
|
4287
|
-
let computedClassName = ''; // all classes from the vnode should be in the element.classList
|
|
4288
|
-
|
|
4289
|
-
for (const name in classMap) {
|
|
4290
|
-
computedClassName += ' ' + name;
|
|
4291
|
-
|
|
4292
|
-
if (!classList.contains(name)) {
|
|
4293
|
-
nodesAreCompatible = false;
|
|
4294
|
-
}
|
|
4295
|
-
}
|
|
4296
|
-
|
|
4297
|
-
vnodeClassName = computedClassName.trim();
|
|
4298
|
-
|
|
4299
|
-
if (classList.length > shared.keys(classMap).length) {
|
|
4300
|
-
nodesAreCompatible = false;
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
|
|
4304
|
-
if (!nodesAreCompatible) {
|
|
4305
|
-
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${elm.className}"`, vnode.owner);
|
|
4306
|
-
}
|
|
4307
|
-
|
|
4308
|
-
return nodesAreCompatible;
|
|
4309
|
-
}
|
|
4310
|
-
|
|
4311
|
-
function vnodesAndElementHaveCompatibleStyle(vnode, elm) {
|
|
4312
|
-
const {
|
|
4313
|
-
data: {
|
|
4314
|
-
style,
|
|
4315
|
-
styleDecls
|
|
4316
|
-
}
|
|
4317
|
-
} = vnode;
|
|
4318
|
-
const elmStyle = getAttribute(elm, 'style') || '';
|
|
4319
|
-
let vnodeStyle;
|
|
4320
|
-
let nodesAreCompatible = true;
|
|
4321
|
-
|
|
4322
|
-
if (!shared.isUndefined(style) && style !== elmStyle) {
|
|
4323
|
-
nodesAreCompatible = false;
|
|
4324
|
-
vnodeStyle = style;
|
|
4325
|
-
} else if (!shared.isUndefined(styleDecls)) {
|
|
4326
|
-
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
4327
|
-
const expectedStyle = []; // styleMap is used when style is set to static value.
|
|
4328
|
-
|
|
4329
|
-
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
4330
|
-
const [prop, value, important] = styleDecls[i];
|
|
4331
|
-
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
4332
|
-
const parsedPropValue = parsedVnodeStyle[prop];
|
|
4333
|
-
|
|
4334
|
-
if (shared.isUndefined(parsedPropValue)) {
|
|
4335
|
-
nodesAreCompatible = false;
|
|
4336
|
-
} else if (!parsedPropValue.startsWith(value)) {
|
|
4337
|
-
nodesAreCompatible = false;
|
|
4338
|
-
} else if (important && !parsedPropValue.endsWith('!important')) {
|
|
4339
|
-
nodesAreCompatible = false;
|
|
4340
|
-
}
|
|
4341
|
-
}
|
|
4342
|
-
|
|
4343
|
-
if (shared.keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
4344
|
-
nodesAreCompatible = false;
|
|
4345
|
-
}
|
|
4346
|
-
|
|
4347
|
-
vnodeStyle = shared.ArrayJoin.call(expectedStyle, ';');
|
|
4348
|
-
}
|
|
4349
|
-
|
|
4350
|
-
if (!nodesAreCompatible) {
|
|
4351
|
-
// style is used when class is bound to an expr.
|
|
4352
|
-
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
4353
|
-
}
|
|
4354
|
-
|
|
4355
|
-
return nodesAreCompatible;
|
|
4356
|
-
}
|
|
4357
|
-
|
|
4358
|
-
function throwHydrationError() {
|
|
4359
|
-
shared.assert.fail('Server rendered elements do not match client side generated elements');
|
|
4360
|
-
}
|
|
4361
|
-
|
|
4362
|
-
function hydrateChildrenHook(elmChildren, children, vm) {
|
|
4363
|
-
var _a, _b;
|
|
4364
|
-
|
|
4365
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4366
|
-
const filteredVNodes = shared.ArrayFilter.call(children, vnode => !!vnode);
|
|
4367
|
-
|
|
4368
|
-
if (elmChildren.length !== filteredVNodes.length) {
|
|
4369
|
-
logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
|
|
4370
|
-
throwHydrationError();
|
|
4371
|
-
}
|
|
4372
|
-
}
|
|
4373
|
-
|
|
4374
|
-
let elmCurrentChildIdx = 0;
|
|
4375
|
-
|
|
4376
|
-
for (let j = 0, n = children.length; j < n; j++) {
|
|
4377
|
-
const ch = children[j];
|
|
4378
|
-
|
|
4379
|
-
if (ch != null) {
|
|
4380
|
-
const childNode = elmChildren[elmCurrentChildIdx];
|
|
4381
|
-
|
|
4382
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4383
|
-
// VComments and VTexts validation is handled in their hooks
|
|
4384
|
-
if (isElementNode(childNode)) {
|
|
4385
|
-
if (((_a = ch.sel) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== childNode.tagName.toLowerCase()) {
|
|
4386
|
-
logError(`Hydration mismatch: expecting element with tag "${(_b = ch.sel) === null || _b === void 0 ? void 0 : _b.toLowerCase()}" but found "${childNode.tagName.toLowerCase()}".`, vm);
|
|
4387
|
-
throwHydrationError();
|
|
4388
|
-
} // Note: props are not yet set
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
const hasIncompatibleAttrs = vnodesAndElementHaveCompatibleAttrs(ch, childNode);
|
|
4392
|
-
const hasIncompatibleClass = vnodesAndElementHaveCompatibleClass(ch, childNode);
|
|
4393
|
-
const hasIncompatibleStyle = vnodesAndElementHaveCompatibleStyle(ch, childNode);
|
|
4394
|
-
const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
4395
|
-
|
|
4396
|
-
if (!isVNodeAndElementCompatible) {
|
|
4397
|
-
throwHydrationError();
|
|
4398
|
-
}
|
|
4399
|
-
}
|
|
4400
|
-
}
|
|
4401
|
-
|
|
4402
|
-
ch.hook.hydrate(ch, childNode);
|
|
4403
|
-
elmCurrentChildIdx++;
|
|
4404
|
-
}
|
|
4405
|
-
}
|
|
4406
|
-
}
|
|
4407
|
-
function removeElmHook(vnode) {
|
|
4408
|
-
// this method only needs to search on child vnodes from template
|
|
4409
|
-
// to trigger the remove hook just in case some of those children
|
|
4410
|
-
// are custom elements.
|
|
4295
|
+
function removeChildren(vnode) {
|
|
4296
|
+
// this method only needs to search on child vnodes from template
|
|
4297
|
+
// to trigger the remove hook just in case some of those children
|
|
4298
|
+
// are custom elements.
|
|
4411
4299
|
const {
|
|
4412
4300
|
children,
|
|
4413
4301
|
elm
|
|
@@ -4423,6 +4311,8 @@ function removeElmHook(vnode) {
|
|
|
4423
4311
|
}
|
|
4424
4312
|
|
|
4425
4313
|
function allocateInSlot(vm, children) {
|
|
4314
|
+
var _a;
|
|
4315
|
+
|
|
4426
4316
|
const {
|
|
4427
4317
|
cmpSlots: oldSlots
|
|
4428
4318
|
} = vm;
|
|
@@ -4435,10 +4325,12 @@ function allocateInSlot(vm, children) {
|
|
|
4435
4325
|
continue;
|
|
4436
4326
|
}
|
|
4437
4327
|
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4328
|
+
let slotName = '';
|
|
4329
|
+
|
|
4330
|
+
if (isVBaseElement(vnode)) {
|
|
4331
|
+
slotName = ((_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) || '';
|
|
4332
|
+
}
|
|
4333
|
+
|
|
4442
4334
|
const vnodes = cmpSlots[slotName] = cmpSlots[slotName] || []; // re-keying the vnodes is necessary to avoid conflicts with default content for the slot
|
|
4443
4335
|
// which might have similar keys. Each vnode will always have a key that
|
|
4444
4336
|
// starts with a numeric character from compiler. In this case, we add a unique
|
|
@@ -4494,329 +4386,203 @@ function hasDynamicChildren(children) {
|
|
|
4494
4386
|
return FromIteration.has(children);
|
|
4495
4387
|
}
|
|
4496
4388
|
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
* All rights reserved.
|
|
4500
|
-
* SPDX-License-Identifier: MIT
|
|
4501
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4502
|
-
*/
|
|
4503
|
-
function getUpgradableConstructor(tagName) {
|
|
4504
|
-
// Should never get a tag with upper case letter at this point, the compiler should
|
|
4505
|
-
// produce only tags with lowercase letters
|
|
4506
|
-
// But, for backwards compatibility, we will lower case the tagName
|
|
4507
|
-
tagName = tagName.toLowerCase();
|
|
4508
|
-
let CE = getCustomElement(tagName);
|
|
4509
|
-
|
|
4510
|
-
if (!shared.isUndefined(CE)) {
|
|
4511
|
-
return CE;
|
|
4512
|
-
}
|
|
4513
|
-
/**
|
|
4514
|
-
* LWC Upgradable Element reference to an element that was created
|
|
4515
|
-
* via the scoped registry mechanism, and that is ready to be upgraded.
|
|
4516
|
-
*/
|
|
4389
|
+
function createKeyToOldIdx(children, beginIdx, endIdx) {
|
|
4390
|
+
const map = {}; // TODO [#1637]: simplify this by assuming that all vnodes has keys
|
|
4517
4391
|
|
|
4392
|
+
for (let j = beginIdx; j <= endIdx; ++j) {
|
|
4393
|
+
const ch = children[j];
|
|
4518
4394
|
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4395
|
+
if (isVNode(ch)) {
|
|
4396
|
+
const {
|
|
4397
|
+
key
|
|
4398
|
+
} = ch;
|
|
4522
4399
|
|
|
4523
|
-
if (
|
|
4524
|
-
|
|
4400
|
+
if (key !== undefined) {
|
|
4401
|
+
map[key] = j;
|
|
4525
4402
|
}
|
|
4526
4403
|
}
|
|
4404
|
+
}
|
|
4527
4405
|
|
|
4528
|
-
|
|
4529
|
-
defineCustomElement(tagName, CE);
|
|
4530
|
-
return CE;
|
|
4406
|
+
return map;
|
|
4531
4407
|
}
|
|
4532
4408
|
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
* SPDX-License-Identifier: MIT
|
|
4537
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4538
|
-
*/
|
|
4539
|
-
const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
4540
|
-
const SymbolIterator = Symbol.iterator;
|
|
4541
|
-
const TextHook = {
|
|
4542
|
-
create: vnode => {
|
|
4543
|
-
const {
|
|
4544
|
-
owner
|
|
4545
|
-
} = vnode;
|
|
4546
|
-
const elm = createText(vnode.text);
|
|
4547
|
-
linkNodeToShadow(elm, owner);
|
|
4548
|
-
vnode.elm = elm;
|
|
4549
|
-
},
|
|
4550
|
-
update: updateNodeHook,
|
|
4551
|
-
insert: insertNodeHook,
|
|
4552
|
-
move: insertNodeHook,
|
|
4553
|
-
remove: removeNodeHook,
|
|
4554
|
-
hydrate: (vNode, node) => {
|
|
4555
|
-
var _a;
|
|
4556
|
-
|
|
4557
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4558
|
-
// eslint-disable-next-line lwc-internal/no-global-node
|
|
4559
|
-
if (node.nodeType !== Node.TEXT_NODE) {
|
|
4560
|
-
logError('Hydration mismatch: incorrect node type received', vNode.owner);
|
|
4561
|
-
shared.assert.fail('Hydration mismatch: incorrect node type received.');
|
|
4562
|
-
}
|
|
4409
|
+
function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
|
|
4410
|
+
for (; startIdx <= endIdx; ++startIdx) {
|
|
4411
|
+
const ch = vnodes[startIdx];
|
|
4563
4412
|
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
}
|
|
4413
|
+
if (isVNode(ch)) {
|
|
4414
|
+
ch.hook.create(ch);
|
|
4415
|
+
ch.hook.insert(ch, parentElm, before);
|
|
4416
|
+
}
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4568
4419
|
|
|
4420
|
+
function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
|
|
4421
|
+
for (; startIdx <= endIdx; ++startIdx) {
|
|
4422
|
+
const ch = vnodes[startIdx]; // text nodes do not have logic associated to them
|
|
4569
4423
|
|
|
4570
|
-
|
|
4571
|
-
|
|
4424
|
+
if (isVNode(ch)) {
|
|
4425
|
+
ch.hook.remove(ch, parentElm);
|
|
4426
|
+
}
|
|
4572
4427
|
}
|
|
4573
|
-
}
|
|
4574
|
-
const CommentHook = {
|
|
4575
|
-
create: vnode => {
|
|
4576
|
-
const {
|
|
4577
|
-
owner,
|
|
4578
|
-
text
|
|
4579
|
-
} = vnode;
|
|
4580
|
-
const elm = createComment(text);
|
|
4581
|
-
linkNodeToShadow(elm, owner);
|
|
4582
|
-
vnode.elm = elm;
|
|
4583
|
-
},
|
|
4584
|
-
update: updateNodeHook,
|
|
4585
|
-
insert: insertNodeHook,
|
|
4586
|
-
move: insertNodeHook,
|
|
4587
|
-
remove: removeNodeHook,
|
|
4588
|
-
hydrate: (vNode, node) => {
|
|
4589
|
-
var _a;
|
|
4428
|
+
}
|
|
4590
4429
|
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4430
|
+
function updateDynamicChildren(parentElm, oldCh, newCh) {
|
|
4431
|
+
let oldStartIdx = 0;
|
|
4432
|
+
let newStartIdx = 0;
|
|
4433
|
+
let oldEndIdx = oldCh.length - 1;
|
|
4434
|
+
let oldStartVnode = oldCh[0];
|
|
4435
|
+
let oldEndVnode = oldCh[oldEndIdx];
|
|
4436
|
+
const newChEnd = newCh.length - 1;
|
|
4437
|
+
let newEndIdx = newChEnd;
|
|
4438
|
+
let newStartVnode = newCh[0];
|
|
4439
|
+
let newEndVnode = newCh[newEndIdx];
|
|
4440
|
+
let oldKeyToIdx;
|
|
4441
|
+
let idxInOld;
|
|
4442
|
+
let elmToMove;
|
|
4443
|
+
let before;
|
|
4597
4444
|
|
|
4598
|
-
|
|
4599
|
-
|
|
4445
|
+
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
|
|
4446
|
+
if (!isVNode(oldStartVnode)) {
|
|
4447
|
+
oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
|
|
4448
|
+
} else if (!isVNode(oldEndVnode)) {
|
|
4449
|
+
oldEndVnode = oldCh[--oldEndIdx];
|
|
4450
|
+
} else if (!isVNode(newStartVnode)) {
|
|
4451
|
+
newStartVnode = newCh[++newStartIdx];
|
|
4452
|
+
} else if (!isVNode(newEndVnode)) {
|
|
4453
|
+
newEndVnode = newCh[--newEndIdx];
|
|
4454
|
+
} else if (isSameVnode(oldStartVnode, newStartVnode)) {
|
|
4455
|
+
patchVnode(oldStartVnode, newStartVnode);
|
|
4456
|
+
oldStartVnode = oldCh[++oldStartIdx];
|
|
4457
|
+
newStartVnode = newCh[++newStartIdx];
|
|
4458
|
+
} else if (isSameVnode(oldEndVnode, newEndVnode)) {
|
|
4459
|
+
patchVnode(oldEndVnode, newEndVnode);
|
|
4460
|
+
oldEndVnode = oldCh[--oldEndIdx];
|
|
4461
|
+
newEndVnode = newCh[--newEndIdx];
|
|
4462
|
+
} else if (isSameVnode(oldStartVnode, newEndVnode)) {
|
|
4463
|
+
// Vnode moved right
|
|
4464
|
+
patchVnode(oldStartVnode, newEndVnode);
|
|
4465
|
+
newEndVnode.hook.move(oldStartVnode, parentElm, nextSibling(oldEndVnode.elm));
|
|
4466
|
+
oldStartVnode = oldCh[++oldStartIdx];
|
|
4467
|
+
newEndVnode = newCh[--newEndIdx];
|
|
4468
|
+
} else if (isSameVnode(oldEndVnode, newStartVnode)) {
|
|
4469
|
+
// Vnode moved left
|
|
4470
|
+
patchVnode(oldEndVnode, newStartVnode);
|
|
4471
|
+
newStartVnode.hook.move(oldEndVnode, parentElm, oldStartVnode.elm);
|
|
4472
|
+
oldEndVnode = oldCh[--oldEndIdx];
|
|
4473
|
+
newStartVnode = newCh[++newStartIdx];
|
|
4474
|
+
} else {
|
|
4475
|
+
if (oldKeyToIdx === undefined) {
|
|
4476
|
+
oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
|
|
4600
4477
|
}
|
|
4601
|
-
} // always set the text value to the one from the vnode.
|
|
4602
|
-
|
|
4603
4478
|
|
|
4604
|
-
|
|
4605
|
-
vNode.elm = node;
|
|
4606
|
-
}
|
|
4607
|
-
}; // insert is called after update, which is used somewhere else (via a module)
|
|
4608
|
-
// to mark the vm as inserted, that means we cannot use update as the main channel
|
|
4609
|
-
// to rehydrate when dirty, because sometimes the element is not inserted just yet,
|
|
4610
|
-
// which breaks some invariants. For that reason, we have the following for any
|
|
4611
|
-
// Custom Element that is inserted via a template.
|
|
4612
|
-
|
|
4613
|
-
const ElementHook = {
|
|
4614
|
-
create: vnode => {
|
|
4615
|
-
const {
|
|
4616
|
-
sel,
|
|
4617
|
-
owner,
|
|
4618
|
-
data: {
|
|
4619
|
-
svg
|
|
4620
|
-
}
|
|
4621
|
-
} = vnode;
|
|
4622
|
-
const namespace = shared.isTrue(svg) ? SVG_NAMESPACE : undefined;
|
|
4623
|
-
const elm = createElement(sel, namespace);
|
|
4624
|
-
linkNodeToShadow(elm, owner);
|
|
4625
|
-
fallbackElmHook(elm, vnode);
|
|
4626
|
-
vnode.elm = elm;
|
|
4627
|
-
patchElementPropsAndAttrs(null, vnode);
|
|
4628
|
-
},
|
|
4629
|
-
update: (oldVnode, vnode) => {
|
|
4630
|
-
patchElementPropsAndAttrs(oldVnode, vnode);
|
|
4631
|
-
patchChildren(vnode.elm, oldVnode.children, vnode.children);
|
|
4632
|
-
},
|
|
4633
|
-
insert: (vnode, parentNode, referenceNode) => {
|
|
4634
|
-
insertNodeHook(vnode, parentNode, referenceNode);
|
|
4635
|
-
createChildrenHook(vnode);
|
|
4636
|
-
},
|
|
4637
|
-
move: (vnode, parentNode, referenceNode) => {
|
|
4638
|
-
insertNodeHook(vnode, parentNode, referenceNode);
|
|
4639
|
-
},
|
|
4640
|
-
remove: (vnode, parentNode) => {
|
|
4641
|
-
removeNodeHook(vnode, parentNode);
|
|
4642
|
-
removeElmHook(vnode);
|
|
4643
|
-
},
|
|
4644
|
-
hydrate: (vnode, node) => {
|
|
4645
|
-
const elm = node;
|
|
4646
|
-
vnode.elm = elm;
|
|
4647
|
-
const {
|
|
4648
|
-
context
|
|
4649
|
-
} = vnode.data;
|
|
4650
|
-
const isDomManual = Boolean(!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual"
|
|
4651
|
-
/* manual */
|
|
4652
|
-
);
|
|
4479
|
+
idxInOld = oldKeyToIdx[newStartVnode.key];
|
|
4653
4480
|
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
}
|
|
4481
|
+
if (shared.isUndefined(idxInOld)) {
|
|
4482
|
+
// New element
|
|
4483
|
+
newStartVnode.hook.create(newStartVnode);
|
|
4484
|
+
newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
|
|
4485
|
+
newStartVnode = newCh[++newStartIdx];
|
|
4486
|
+
} else {
|
|
4487
|
+
elmToMove = oldCh[idxInOld];
|
|
4660
4488
|
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4489
|
+
if (isVNode(elmToMove)) {
|
|
4490
|
+
if (elmToMove.sel !== newStartVnode.sel) {
|
|
4491
|
+
// New element
|
|
4492
|
+
newStartVnode.hook.create(newStartVnode);
|
|
4493
|
+
newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
|
|
4494
|
+
} else {
|
|
4495
|
+
patchVnode(elmToMove, newStartVnode);
|
|
4496
|
+
oldCh[idxInOld] = undefined;
|
|
4497
|
+
newStartVnode.hook.move(elmToMove, parentElm, oldStartVnode.elm);
|
|
4498
|
+
}
|
|
4666
4499
|
}
|
|
4667
|
-
}
|
|
4668
|
-
}
|
|
4669
|
-
|
|
4670
|
-
hydrateElmHook(vnode);
|
|
4671
4500
|
|
|
4672
|
-
|
|
4673
|
-
|
|
4501
|
+
newStartVnode = newCh[++newStartIdx];
|
|
4502
|
+
}
|
|
4674
4503
|
}
|
|
4675
4504
|
}
|
|
4676
|
-
};
|
|
4677
|
-
const CustomElementHook = {
|
|
4678
|
-
create: vnode => {
|
|
4679
|
-
const {
|
|
4680
|
-
sel,
|
|
4681
|
-
owner
|
|
4682
|
-
} = vnode;
|
|
4683
|
-
const UpgradableConstructor = getUpgradableConstructor(sel);
|
|
4684
|
-
/**
|
|
4685
|
-
* Note: if the upgradable constructor does not expect, or throw when we new it
|
|
4686
|
-
* with a callback as the first argument, we could implement a more advanced
|
|
4687
|
-
* mechanism that only passes that argument if the constructor is known to be
|
|
4688
|
-
* an upgradable custom element.
|
|
4689
|
-
*/
|
|
4690
|
-
|
|
4691
|
-
const elm = new UpgradableConstructor(elm => {
|
|
4692
|
-
// the custom element from the registry is expecting an upgrade callback
|
|
4693
|
-
createViewModelHook(elm, vnode);
|
|
4694
|
-
});
|
|
4695
|
-
linkNodeToShadow(elm, owner);
|
|
4696
|
-
vnode.elm = elm;
|
|
4697
|
-
const vm = getAssociatedVMIfPresent(elm);
|
|
4698
|
-
|
|
4699
|
-
if (vm) {
|
|
4700
|
-
allocateChildrenHook(vnode, vm);
|
|
4701
|
-
} else if (vnode.ctor !== UpgradableConstructor) {
|
|
4702
|
-
throw new TypeError(`Incorrect Component Constructor`);
|
|
4703
|
-
}
|
|
4704
|
-
|
|
4705
|
-
patchElementPropsAndAttrs(null, vnode);
|
|
4706
|
-
},
|
|
4707
|
-
update: (oldVnode, vnode) => {
|
|
4708
|
-
patchElementPropsAndAttrs(oldVnode, vnode);
|
|
4709
|
-
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
4710
|
-
|
|
4711
|
-
if (vm) {
|
|
4712
|
-
// in fallback mode, the allocation will always set children to
|
|
4713
|
-
// empty and delegate the real allocation to the slot elements
|
|
4714
|
-
allocateChildrenHook(vnode, vm);
|
|
4715
|
-
} // in fallback mode, the children will be always empty, so, nothing
|
|
4716
|
-
// will happen, but in native, it does allocate the light dom
|
|
4717
4505
|
|
|
4506
|
+
if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
|
|
4507
|
+
if (oldStartIdx > oldEndIdx) {
|
|
4508
|
+
// There's some cases in which the sub array of vnodes to be inserted is followed by null(s) and an
|
|
4509
|
+
// already processed vnode, in such cases the vnodes to be inserted should be before that processed vnode.
|
|
4510
|
+
let i = newEndIdx;
|
|
4511
|
+
let n;
|
|
4718
4512
|
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
4723
|
-
shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
|
|
4724
|
-
} // this will probably update the shadowRoot, but only if the vm is in a dirty state
|
|
4725
|
-
// this is important to preserve the top to bottom synchronous rendering phase.
|
|
4726
|
-
|
|
4513
|
+
do {
|
|
4514
|
+
n = newCh[++i];
|
|
4515
|
+
} while (!isVNode(n) && i < newChEnd);
|
|
4727
4516
|
|
|
4728
|
-
|
|
4517
|
+
before = isVNode(n) ? n.elm : null;
|
|
4518
|
+
addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx);
|
|
4519
|
+
} else {
|
|
4520
|
+
removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
|
|
4729
4521
|
}
|
|
4730
|
-
}
|
|
4731
|
-
|
|
4732
|
-
insertNodeHook(vnode, parentNode, referenceNode);
|
|
4733
|
-
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
4522
|
+
}
|
|
4523
|
+
}
|
|
4734
4524
|
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
/* created */
|
|
4739
|
-
, `${vm} cannot be recycled.`);
|
|
4740
|
-
}
|
|
4525
|
+
function updateStaticChildren(parentElm, oldCh, newCh) {
|
|
4526
|
+
const oldChLength = oldCh.length;
|
|
4527
|
+
const newChLength = newCh.length;
|
|
4741
4528
|
|
|
4742
|
-
|
|
4743
|
-
|
|
4529
|
+
if (oldChLength === 0) {
|
|
4530
|
+
// the old list is empty, we can directly insert anything new
|
|
4531
|
+
addVnodes(parentElm, null, newCh, 0, newChLength);
|
|
4532
|
+
return;
|
|
4533
|
+
}
|
|
4744
4534
|
|
|
4745
|
-
|
|
4535
|
+
if (newChLength === 0) {
|
|
4536
|
+
// the old list is nonempty and the new list is empty so we can directly remove all old nodes
|
|
4537
|
+
// this is the case in which the dynamic children of an if-directive should be removed
|
|
4538
|
+
removeVnodes(parentElm, oldCh, 0, oldChLength);
|
|
4539
|
+
return;
|
|
4540
|
+
} // if the old list is not empty, the new list MUST have the same
|
|
4541
|
+
// amount of nodes, that's why we call this static children
|
|
4746
4542
|
|
|
4747
|
-
if (vm) {
|
|
4748
|
-
appendVM(vm);
|
|
4749
|
-
}
|
|
4750
|
-
},
|
|
4751
|
-
move: (vnode, parentNode, referenceNode) => {
|
|
4752
|
-
insertNodeHook(vnode, parentNode, referenceNode);
|
|
4753
|
-
},
|
|
4754
|
-
remove: (vnode, parentNode) => {
|
|
4755
|
-
removeNodeHook(vnode, parentNode);
|
|
4756
|
-
const vm = getAssociatedVMIfPresent(vnode.elm);
|
|
4757
4543
|
|
|
4758
|
-
|
|
4759
|
-
// for custom elements we don't have to go recursively because the removeVM routine
|
|
4760
|
-
// will take care of disconnecting any child VM attached to its shadow as well.
|
|
4761
|
-
removeVM(vm);
|
|
4762
|
-
}
|
|
4763
|
-
},
|
|
4764
|
-
hydrate: (vnode, elm) => {
|
|
4765
|
-
// the element is created, but the vm is not
|
|
4766
|
-
const {
|
|
4767
|
-
sel,
|
|
4768
|
-
mode,
|
|
4769
|
-
ctor,
|
|
4770
|
-
owner
|
|
4771
|
-
} = vnode;
|
|
4772
|
-
const def = getComponentInternalDef(ctor);
|
|
4773
|
-
createVM(elm, def, {
|
|
4774
|
-
mode,
|
|
4775
|
-
owner,
|
|
4776
|
-
tagName: sel
|
|
4777
|
-
});
|
|
4778
|
-
vnode.elm = elm;
|
|
4779
|
-
const vm = getAssociatedVM(elm);
|
|
4780
|
-
allocateChildrenHook(vnode, vm);
|
|
4781
|
-
hydrateElmHook(vnode); // Insert hook section:
|
|
4544
|
+
let referenceElm = null;
|
|
4782
4545
|
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
, `${vm} cannot be recycled.`);
|
|
4787
|
-
}
|
|
4546
|
+
for (let i = newChLength - 1; i >= 0; i -= 1) {
|
|
4547
|
+
const vnode = newCh[i];
|
|
4548
|
+
const oldVNode = oldCh[i];
|
|
4788
4549
|
|
|
4789
|
-
|
|
4550
|
+
if (vnode !== oldVNode) {
|
|
4551
|
+
if (isVNode(oldVNode)) {
|
|
4552
|
+
if (isVNode(vnode)) {
|
|
4553
|
+
// both vnodes must be equivalent, and se just need to patch them
|
|
4554
|
+
patchVnode(oldVNode, vnode);
|
|
4555
|
+
referenceElm = vnode.elm;
|
|
4556
|
+
} else {
|
|
4557
|
+
// removing the old vnode since the new one is null
|
|
4558
|
+
oldVNode.hook.remove(oldVNode, parentElm);
|
|
4559
|
+
}
|
|
4560
|
+
} else if (isVNode(vnode)) {
|
|
4561
|
+
// this condition is unnecessary
|
|
4562
|
+
vnode.hook.create(vnode); // insert the new node one since the old one is null
|
|
4790
4563
|
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
4795
|
-
// Note: for Light DOM, this is handled while hydrating the VM
|
|
4796
|
-
hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vm);
|
|
4564
|
+
vnode.hook.insert(vnode, parentElm, referenceElm);
|
|
4565
|
+
referenceElm = vnode.elm;
|
|
4566
|
+
}
|
|
4797
4567
|
}
|
|
4798
|
-
|
|
4799
|
-
hydrateVM(vm);
|
|
4800
4568
|
}
|
|
4801
|
-
}
|
|
4802
|
-
|
|
4803
|
-
function linkNodeToShadow(elm, owner) {
|
|
4804
|
-
const {
|
|
4805
|
-
renderMode,
|
|
4806
|
-
shadowMode
|
|
4807
|
-
} = owner; // TODO [#1164]: this should eventually be done by the polyfill directly
|
|
4569
|
+
}
|
|
4808
4570
|
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
/* Light */
|
|
4814
|
-
) {
|
|
4815
|
-
elm[shared.KEY__SHADOW_RESOLVER] = getRenderRoot(owner)[shared.KEY__SHADOW_RESOLVER];
|
|
4816
|
-
}
|
|
4571
|
+
function patchVnode(oldVnode, vnode) {
|
|
4572
|
+
if (oldVnode !== vnode) {
|
|
4573
|
+
vnode.elm = oldVnode.elm;
|
|
4574
|
+
vnode.hook.update(oldVnode, vnode);
|
|
4817
4575
|
}
|
|
4818
4576
|
}
|
|
4819
4577
|
|
|
4578
|
+
/*
|
|
4579
|
+
* Copyright (c) 2018, salesforce.com, inc.
|
|
4580
|
+
* All rights reserved.
|
|
4581
|
+
* SPDX-License-Identifier: MIT
|
|
4582
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
4583
|
+
*/
|
|
4584
|
+
const SymbolIterator = Symbol.iterator;
|
|
4585
|
+
|
|
4820
4586
|
function addVNodeToChildLWC(vnode) {
|
|
4821
4587
|
shared.ArrayPush.call(getVMBeingRendered().velements, vnode);
|
|
4822
4588
|
} // [h]tml node
|
|
@@ -4840,20 +4606,22 @@ function h(sel, data, children) {
|
|
|
4840
4606
|
|
|
4841
4607
|
shared.forEach.call(children, childVnode => {
|
|
4842
4608
|
if (childVnode != null) {
|
|
4843
|
-
shared.assert.isTrue(
|
|
4609
|
+
shared.assert.isTrue('type' in childVnode && 'sel' in childVnode && 'elm' in childVnode && 'key' in childVnode, `${childVnode} is not a vnode.`);
|
|
4844
4610
|
}
|
|
4845
4611
|
});
|
|
4846
4612
|
}
|
|
4847
4613
|
|
|
4848
|
-
let
|
|
4614
|
+
let elm;
|
|
4849
4615
|
const {
|
|
4850
4616
|
key
|
|
4851
4617
|
} = data;
|
|
4852
4618
|
return {
|
|
4619
|
+
type: 2
|
|
4620
|
+
/* Element */
|
|
4621
|
+
,
|
|
4853
4622
|
sel,
|
|
4854
4623
|
data,
|
|
4855
4624
|
children,
|
|
4856
|
-
text,
|
|
4857
4625
|
elm,
|
|
4858
4626
|
key,
|
|
4859
4627
|
hook: ElementHook,
|
|
@@ -4934,7 +4702,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4934
4702
|
if (arguments.length === 4) {
|
|
4935
4703
|
shared.forEach.call(children, childVnode => {
|
|
4936
4704
|
if (childVnode != null) {
|
|
4937
|
-
shared.assert.isTrue(
|
|
4705
|
+
shared.assert.isTrue('type' in childVnode && 'sel' in childVnode && 'elm' in childVnode && 'key' in childVnode, `${childVnode} is not a vnode.`);
|
|
4938
4706
|
}
|
|
4939
4707
|
});
|
|
4940
4708
|
}
|
|
@@ -4943,12 +4711,14 @@ function c(sel, Ctor, data, children = EmptyArray) {
|
|
|
4943
4711
|
const {
|
|
4944
4712
|
key
|
|
4945
4713
|
} = data;
|
|
4946
|
-
let
|
|
4714
|
+
let elm;
|
|
4947
4715
|
const vnode = {
|
|
4716
|
+
type: 3
|
|
4717
|
+
/* CustomElement */
|
|
4718
|
+
,
|
|
4948
4719
|
sel,
|
|
4949
4720
|
data,
|
|
4950
4721
|
children,
|
|
4951
|
-
text,
|
|
4952
4722
|
elm,
|
|
4953
4723
|
key,
|
|
4954
4724
|
hook: CustomElementHook,
|
|
@@ -5076,12 +4846,12 @@ function f(items) {
|
|
|
5076
4846
|
|
|
5077
4847
|
|
|
5078
4848
|
function t(text) {
|
|
5079
|
-
|
|
5080
|
-
let sel, children, key, elm;
|
|
4849
|
+
let sel, key, elm;
|
|
5081
4850
|
return {
|
|
4851
|
+
type: 0
|
|
4852
|
+
/* Text */
|
|
4853
|
+
,
|
|
5082
4854
|
sel,
|
|
5083
|
-
data,
|
|
5084
|
-
children,
|
|
5085
4855
|
text,
|
|
5086
4856
|
elm,
|
|
5087
4857
|
key,
|
|
@@ -5092,12 +4862,12 @@ function t(text) {
|
|
|
5092
4862
|
|
|
5093
4863
|
|
|
5094
4864
|
function co(text) {
|
|
5095
|
-
|
|
5096
|
-
let sel, children, key, elm;
|
|
4865
|
+
let sel, key, elm;
|
|
5097
4866
|
return {
|
|
4867
|
+
type: 1
|
|
4868
|
+
/* Comment */
|
|
4869
|
+
,
|
|
5098
4870
|
sel,
|
|
5099
|
-
data,
|
|
5100
|
-
children,
|
|
5101
4871
|
text,
|
|
5102
4872
|
elm,
|
|
5103
4873
|
key,
|
|
@@ -5534,7 +5304,7 @@ function createStylesheet(vm, stylesheets) {
|
|
|
5534
5304
|
insertGlobalStylesheet(stylesheets[i]);
|
|
5535
5305
|
} else {
|
|
5536
5306
|
// local level
|
|
5537
|
-
insertStylesheet(stylesheets[i], root.
|
|
5307
|
+
insertStylesheet(stylesheets[i], root.shadowRoot);
|
|
5538
5308
|
}
|
|
5539
5309
|
}
|
|
5540
5310
|
}
|
|
@@ -5826,24 +5596,6 @@ function computeHasScopedStyles(template) {
|
|
|
5826
5596
|
return false;
|
|
5827
5597
|
}
|
|
5828
5598
|
|
|
5829
|
-
/*
|
|
5830
|
-
* Copyright (c) 2018, salesforce.com, inc.
|
|
5831
|
-
* All rights reserved.
|
|
5832
|
-
* SPDX-License-Identifier: MIT
|
|
5833
|
-
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5834
|
-
*/
|
|
5835
|
-
function addErrorComponentStack(vm, error) {
|
|
5836
|
-
if (!shared.isFrozen(error) && shared.isUndefined(error.wcStack)) {
|
|
5837
|
-
const wcStack = getErrorComponentStack(vm);
|
|
5838
|
-
shared.defineProperty(error, 'wcStack', {
|
|
5839
|
-
get() {
|
|
5840
|
-
return wcStack;
|
|
5841
|
-
}
|
|
5842
|
-
|
|
5843
|
-
});
|
|
5844
|
-
}
|
|
5845
|
-
}
|
|
5846
|
-
|
|
5847
5599
|
/*
|
|
5848
5600
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
5849
5601
|
* All rights reserved.
|
|
@@ -6073,6 +5825,320 @@ function invokeServiceHook(vm, cbs) {
|
|
|
6073
5825
|
}
|
|
6074
5826
|
}
|
|
6075
5827
|
|
|
5828
|
+
/*
|
|
5829
|
+
* Copyright (c) 2022, salesforce.com, inc.
|
|
5830
|
+
* All rights reserved.
|
|
5831
|
+
* SPDX-License-Identifier: MIT
|
|
5832
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
|
|
5833
|
+
*/
|
|
5834
|
+
|
|
5835
|
+
function hydrate$1(vnode, node) {
|
|
5836
|
+
switch (vnode.type) {
|
|
5837
|
+
case 0
|
|
5838
|
+
/* Text */
|
|
5839
|
+
:
|
|
5840
|
+
hydrateText(vnode, node);
|
|
5841
|
+
break;
|
|
5842
|
+
|
|
5843
|
+
case 1
|
|
5844
|
+
/* Comment */
|
|
5845
|
+
:
|
|
5846
|
+
hydrateComment(vnode, node);
|
|
5847
|
+
break;
|
|
5848
|
+
|
|
5849
|
+
case 2
|
|
5850
|
+
/* Element */
|
|
5851
|
+
:
|
|
5852
|
+
hydrateElement(vnode, node);
|
|
5853
|
+
break;
|
|
5854
|
+
|
|
5855
|
+
case 3
|
|
5856
|
+
/* CustomElement */
|
|
5857
|
+
:
|
|
5858
|
+
hydrateCustomElement(vnode, node);
|
|
5859
|
+
break;
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
5862
|
+
|
|
5863
|
+
function hydrateText(vnode, node) {
|
|
5864
|
+
var _a;
|
|
5865
|
+
|
|
5866
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5867
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
5868
|
+
validateNodeType(vnode, node, Node.TEXT_NODE);
|
|
5869
|
+
|
|
5870
|
+
if (node.nodeValue !== vnode.text && !(node.nodeValue === '\u200D' && vnode.text === '')) {
|
|
5871
|
+
logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
|
|
5872
|
+
}
|
|
5873
|
+
} // always set the text value to the one from the vnode.
|
|
5874
|
+
|
|
5875
|
+
|
|
5876
|
+
node.nodeValue = (_a = vnode.text) !== null && _a !== void 0 ? _a : null;
|
|
5877
|
+
vnode.elm = node;
|
|
5878
|
+
}
|
|
5879
|
+
|
|
5880
|
+
function hydrateComment(vnode, node) {
|
|
5881
|
+
var _a;
|
|
5882
|
+
|
|
5883
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5884
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
5885
|
+
validateNodeType(vnode, node, Node.COMMENT_NODE);
|
|
5886
|
+
|
|
5887
|
+
if (node.nodeValue !== vnode.text) {
|
|
5888
|
+
logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
|
|
5889
|
+
}
|
|
5890
|
+
} // always set the text value to the one from the vnode.
|
|
5891
|
+
|
|
5892
|
+
|
|
5893
|
+
node.nodeValue = (_a = vnode.text) !== null && _a !== void 0 ? _a : null;
|
|
5894
|
+
vnode.elm = node;
|
|
5895
|
+
}
|
|
5896
|
+
|
|
5897
|
+
function hydrateElement(vnode, node) {
|
|
5898
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5899
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
5900
|
+
validateNodeType(vnode, node, Node.ELEMENT_NODE);
|
|
5901
|
+
validateElement(vnode, node);
|
|
5902
|
+
}
|
|
5903
|
+
|
|
5904
|
+
const elm = node;
|
|
5905
|
+
vnode.elm = elm;
|
|
5906
|
+
const {
|
|
5907
|
+
context
|
|
5908
|
+
} = vnode.data;
|
|
5909
|
+
const isDomManual = Boolean(!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual"
|
|
5910
|
+
/* Manual */
|
|
5911
|
+
);
|
|
5912
|
+
|
|
5913
|
+
if (isDomManual) {
|
|
5914
|
+
// it may be that this element has lwc:inner-html, we need to diff and in case are the same,
|
|
5915
|
+
// remove the innerHTML from props so it reuses the existing dom elements.
|
|
5916
|
+
const {
|
|
5917
|
+
props
|
|
5918
|
+
} = vnode.data;
|
|
5919
|
+
|
|
5920
|
+
if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
|
|
5921
|
+
if (elm.innerHTML === props.innerHTML) {
|
|
5922
|
+
delete props.innerHTML;
|
|
5923
|
+
} else {
|
|
5924
|
+
logWarn(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
|
|
5925
|
+
}
|
|
5926
|
+
}
|
|
5927
|
+
}
|
|
5928
|
+
|
|
5929
|
+
patchElementPropsAndAttrs(vnode);
|
|
5930
|
+
|
|
5931
|
+
if (!isDomManual) {
|
|
5932
|
+
hydrateChildren(vnode.elm.childNodes, vnode.children, vnode.owner);
|
|
5933
|
+
}
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5936
|
+
function hydrateCustomElement(vnode, node) {
|
|
5937
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5938
|
+
// eslint-disable-next-line lwc-internal/no-global-node
|
|
5939
|
+
validateNodeType(vnode, node, Node.ELEMENT_NODE);
|
|
5940
|
+
validateElement(vnode, node);
|
|
5941
|
+
}
|
|
5942
|
+
|
|
5943
|
+
const elm = node;
|
|
5944
|
+
vnode.elm = elm;
|
|
5945
|
+
const {
|
|
5946
|
+
sel,
|
|
5947
|
+
mode,
|
|
5948
|
+
ctor,
|
|
5949
|
+
owner
|
|
5950
|
+
} = vnode;
|
|
5951
|
+
const vm = createVM(elm, ctor, {
|
|
5952
|
+
mode,
|
|
5953
|
+
owner,
|
|
5954
|
+
tagName: sel
|
|
5955
|
+
});
|
|
5956
|
+
allocateChildren(vnode, vm);
|
|
5957
|
+
patchElementPropsAndAttrs(vnode); // Insert hook section:
|
|
5958
|
+
|
|
5959
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5960
|
+
shared.assert.isTrue(vm.state === 0
|
|
5961
|
+
/* created */
|
|
5962
|
+
, `${vm} cannot be recycled.`);
|
|
5963
|
+
}
|
|
5964
|
+
|
|
5965
|
+
runConnectedCallback(vm);
|
|
5966
|
+
|
|
5967
|
+
if (vm.renderMode !== 0
|
|
5968
|
+
/* Light */
|
|
5969
|
+
) {
|
|
5970
|
+
// VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
|
|
5971
|
+
// Note: for Light DOM, this is handled while hydrating the VM
|
|
5972
|
+
hydrateChildren(vnode.elm.childNodes, vnode.children, vm);
|
|
5973
|
+
}
|
|
5974
|
+
|
|
5975
|
+
hydrateVM(vm);
|
|
5976
|
+
}
|
|
5977
|
+
|
|
5978
|
+
function hydrateChildren(elmChildren, children, vm) {
|
|
5979
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
5980
|
+
const filteredVNodes = shared.ArrayFilter.call(children, vnode => !!vnode);
|
|
5981
|
+
|
|
5982
|
+
if (elmChildren.length !== filteredVNodes.length) {
|
|
5983
|
+
logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
|
|
5984
|
+
throwHydrationError();
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
|
|
5988
|
+
let childNodeIndex = 0;
|
|
5989
|
+
|
|
5990
|
+
for (let i = 0; i < children.length; i++) {
|
|
5991
|
+
const childVnode = children[i];
|
|
5992
|
+
|
|
5993
|
+
if (!shared.isNull(childVnode)) {
|
|
5994
|
+
const childNode = elmChildren[childNodeIndex];
|
|
5995
|
+
hydrate$1(childVnode, childNode);
|
|
5996
|
+
childNodeIndex++;
|
|
5997
|
+
}
|
|
5998
|
+
}
|
|
5999
|
+
}
|
|
6000
|
+
|
|
6001
|
+
function patchElementPropsAndAttrs(vnode) {
|
|
6002
|
+
applyEventListeners(vnode);
|
|
6003
|
+
patchProps(null, vnode);
|
|
6004
|
+
}
|
|
6005
|
+
|
|
6006
|
+
function throwHydrationError() {
|
|
6007
|
+
shared.assert.fail('Server rendered elements do not match client side generated elements');
|
|
6008
|
+
}
|
|
6009
|
+
|
|
6010
|
+
function validateNodeType(vnode, node, nodeType) {
|
|
6011
|
+
if (node.nodeType !== nodeType) {
|
|
6012
|
+
logError('Hydration mismatch: incorrect node type received', vnode.owner);
|
|
6013
|
+
shared.assert.fail('Hydration mismatch: incorrect node type received.');
|
|
6014
|
+
}
|
|
6015
|
+
}
|
|
6016
|
+
|
|
6017
|
+
function validateElement(vnode, elm) {
|
|
6018
|
+
if (vnode.sel.toLowerCase() !== elm.tagName.toLowerCase()) {
|
|
6019
|
+
logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${elm.tagName.toLowerCase()}".`, vnode.owner);
|
|
6020
|
+
throwHydrationError();
|
|
6021
|
+
}
|
|
6022
|
+
|
|
6023
|
+
const hasIncompatibleAttrs = validateAttrs(vnode, elm);
|
|
6024
|
+
const hasIncompatibleClass = validateClassAttr(vnode, elm);
|
|
6025
|
+
const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
|
|
6026
|
+
const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
|
|
6027
|
+
|
|
6028
|
+
if (!isVNodeAndElementCompatible) {
|
|
6029
|
+
throwHydrationError();
|
|
6030
|
+
}
|
|
6031
|
+
}
|
|
6032
|
+
|
|
6033
|
+
function validateAttrs(vnode, elm) {
|
|
6034
|
+
const {
|
|
6035
|
+
data: {
|
|
6036
|
+
attrs = {}
|
|
6037
|
+
}
|
|
6038
|
+
} = vnode;
|
|
6039
|
+
let nodesAreCompatible = true; // Validate attributes, though we could always recovery from those by running the update mods.
|
|
6040
|
+
// Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
|
|
6041
|
+
|
|
6042
|
+
for (const [attrName, attrValue] of Object.entries(attrs)) {
|
|
6043
|
+
const elmAttrValue = getAttribute(elm, attrName);
|
|
6044
|
+
|
|
6045
|
+
if (String(attrValue) !== elmAttrValue) {
|
|
6046
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
|
|
6047
|
+
nodesAreCompatible = false;
|
|
6048
|
+
}
|
|
6049
|
+
}
|
|
6050
|
+
|
|
6051
|
+
return nodesAreCompatible;
|
|
6052
|
+
}
|
|
6053
|
+
|
|
6054
|
+
function validateClassAttr(vnode, elm) {
|
|
6055
|
+
const {
|
|
6056
|
+
data: {
|
|
6057
|
+
className,
|
|
6058
|
+
classMap
|
|
6059
|
+
}
|
|
6060
|
+
} = vnode;
|
|
6061
|
+
let nodesAreCompatible = true;
|
|
6062
|
+
let vnodeClassName;
|
|
6063
|
+
|
|
6064
|
+
if (!shared.isUndefined(className) && String(className) !== elm.className) {
|
|
6065
|
+
// className is used when class is bound to an expr.
|
|
6066
|
+
nodesAreCompatible = false;
|
|
6067
|
+
vnodeClassName = className;
|
|
6068
|
+
} else if (!shared.isUndefined(classMap)) {
|
|
6069
|
+
// classMap is used when class is set to static value.
|
|
6070
|
+
const classList = getClassList(elm);
|
|
6071
|
+
let computedClassName = ''; // all classes from the vnode should be in the element.classList
|
|
6072
|
+
|
|
6073
|
+
for (const name in classMap) {
|
|
6074
|
+
computedClassName += ' ' + name;
|
|
6075
|
+
|
|
6076
|
+
if (!classList.contains(name)) {
|
|
6077
|
+
nodesAreCompatible = false;
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
|
|
6081
|
+
vnodeClassName = computedClassName.trim();
|
|
6082
|
+
|
|
6083
|
+
if (classList.length > shared.keys(classMap).length) {
|
|
6084
|
+
nodesAreCompatible = false;
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
|
|
6088
|
+
if (!nodesAreCompatible) {
|
|
6089
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${elm.className}"`, vnode.owner);
|
|
6090
|
+
}
|
|
6091
|
+
|
|
6092
|
+
return nodesAreCompatible;
|
|
6093
|
+
}
|
|
6094
|
+
|
|
6095
|
+
function validateStyleAttr(vnode, elm) {
|
|
6096
|
+
const {
|
|
6097
|
+
data: {
|
|
6098
|
+
style,
|
|
6099
|
+
styleDecls
|
|
6100
|
+
}
|
|
6101
|
+
} = vnode;
|
|
6102
|
+
const elmStyle = getAttribute(elm, 'style') || '';
|
|
6103
|
+
let vnodeStyle;
|
|
6104
|
+
let nodesAreCompatible = true;
|
|
6105
|
+
|
|
6106
|
+
if (!shared.isUndefined(style) && style !== elmStyle) {
|
|
6107
|
+
nodesAreCompatible = false;
|
|
6108
|
+
vnodeStyle = style;
|
|
6109
|
+
} else if (!shared.isUndefined(styleDecls)) {
|
|
6110
|
+
const parsedVnodeStyle = parseStyleText(elmStyle);
|
|
6111
|
+
const expectedStyle = []; // styleMap is used when style is set to static value.
|
|
6112
|
+
|
|
6113
|
+
for (let i = 0, n = styleDecls.length; i < n; i++) {
|
|
6114
|
+
const [prop, value, important] = styleDecls[i];
|
|
6115
|
+
expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
|
|
6116
|
+
const parsedPropValue = parsedVnodeStyle[prop];
|
|
6117
|
+
|
|
6118
|
+
if (shared.isUndefined(parsedPropValue)) {
|
|
6119
|
+
nodesAreCompatible = false;
|
|
6120
|
+
} else if (!parsedPropValue.startsWith(value)) {
|
|
6121
|
+
nodesAreCompatible = false;
|
|
6122
|
+
} else if (important && !parsedPropValue.endsWith('!important')) {
|
|
6123
|
+
nodesAreCompatible = false;
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
|
|
6127
|
+
if (shared.keys(parsedVnodeStyle).length > styleDecls.length) {
|
|
6128
|
+
nodesAreCompatible = false;
|
|
6129
|
+
}
|
|
6130
|
+
|
|
6131
|
+
vnodeStyle = shared.ArrayJoin.call(expectedStyle, ';');
|
|
6132
|
+
}
|
|
6133
|
+
|
|
6134
|
+
if (!nodesAreCompatible) {
|
|
6135
|
+
// style is used when class is bound to an expr.
|
|
6136
|
+
logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
|
|
6137
|
+
}
|
|
6138
|
+
|
|
6139
|
+
return nodesAreCompatible;
|
|
6140
|
+
}
|
|
6141
|
+
|
|
6076
6142
|
/*
|
|
6077
6143
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
6078
6144
|
* All rights reserved.
|
|
@@ -6191,12 +6257,13 @@ function getNearestShadowAncestor(vm) {
|
|
|
6191
6257
|
return ancestor;
|
|
6192
6258
|
}
|
|
6193
6259
|
|
|
6194
|
-
function createVM(elm,
|
|
6260
|
+
function createVM(elm, ctor, options) {
|
|
6195
6261
|
const {
|
|
6196
6262
|
mode,
|
|
6197
6263
|
owner,
|
|
6198
6264
|
tagName
|
|
6199
6265
|
} = options;
|
|
6266
|
+
const def = getComponentInternalDef(ctor);
|
|
6200
6267
|
const vm = {
|
|
6201
6268
|
elm,
|
|
6202
6269
|
def,
|
|
@@ -6218,7 +6285,6 @@ function createVM(elm, def, options) {
|
|
|
6218
6285
|
oar: shared.create(null),
|
|
6219
6286
|
cmpTemplate: null,
|
|
6220
6287
|
renderMode: def.renderMode,
|
|
6221
|
-
shadowMode: null,
|
|
6222
6288
|
context: {
|
|
6223
6289
|
stylesheetToken: undefined,
|
|
6224
6290
|
hasTokenInClass: undefined,
|
|
@@ -6229,9 +6295,13 @@ function createVM(elm, def, options) {
|
|
|
6229
6295
|
wiredConnecting: EmptyArray,
|
|
6230
6296
|
wiredDisconnecting: EmptyArray
|
|
6231
6297
|
},
|
|
6298
|
+
// Properties set right after VM creation.
|
|
6232
6299
|
tro: null,
|
|
6300
|
+
shadowMode: null,
|
|
6301
|
+
// Properties set by the LightningElement constructor.
|
|
6233
6302
|
component: null,
|
|
6234
|
-
|
|
6303
|
+
shadowRoot: null,
|
|
6304
|
+
renderRoot: null,
|
|
6235
6305
|
callHook,
|
|
6236
6306
|
setHook,
|
|
6237
6307
|
getHook
|
|
@@ -6319,7 +6389,7 @@ function computeShadowMode(vm) {
|
|
|
6319
6389
|
}
|
|
6320
6390
|
|
|
6321
6391
|
function assertIsVM(obj) {
|
|
6322
|
-
if (shared.isNull(obj) || !shared.isObject(obj) || !('
|
|
6392
|
+
if (shared.isNull(obj) || !shared.isObject(obj) || !('renderRoot' in obj)) {
|
|
6323
6393
|
throw new TypeError(`${obj} is not a VM.`);
|
|
6324
6394
|
}
|
|
6325
6395
|
}
|
|
@@ -6366,13 +6436,14 @@ function hydrate(vm) {
|
|
|
6366
6436
|
const vmChildren = vm.renderMode === 0
|
|
6367
6437
|
/* Light */
|
|
6368
6438
|
? vm.elm.childNodes : vm.elm.shadowRoot.childNodes;
|
|
6369
|
-
|
|
6439
|
+
hydrateChildren(vmChildren, children, vm);
|
|
6370
6440
|
runRenderedCallback(vm);
|
|
6371
6441
|
}
|
|
6372
6442
|
}
|
|
6373
6443
|
|
|
6374
6444
|
function patchShadowRoot(vm, newCh) {
|
|
6375
6445
|
const {
|
|
6446
|
+
renderRoot,
|
|
6376
6447
|
children: oldCh
|
|
6377
6448
|
} = vm; // caching the new children collection
|
|
6378
6449
|
|
|
@@ -6389,7 +6460,6 @@ function patchShadowRoot(vm, newCh) {
|
|
|
6389
6460
|
, vm);
|
|
6390
6461
|
}, () => {
|
|
6391
6462
|
// job
|
|
6392
|
-
const renderRoot = getRenderRoot(vm);
|
|
6393
6463
|
patchChildren(renderRoot, oldCh, newCh);
|
|
6394
6464
|
}, () => {
|
|
6395
6465
|
// post
|
|
@@ -6625,14 +6695,22 @@ function recursivelyDisconnectChildren(vnodes) {
|
|
|
6625
6695
|
for (let i = 0, len = vnodes.length; i < len; i += 1) {
|
|
6626
6696
|
const vnode = vnodes[i];
|
|
6627
6697
|
|
|
6628
|
-
if (!shared.isNull(vnode) &&
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6698
|
+
if (!shared.isNull(vnode) && !shared.isUndefined(vnode.elm)) {
|
|
6699
|
+
switch (vnode.type) {
|
|
6700
|
+
case 2
|
|
6701
|
+
/* Element */
|
|
6702
|
+
:
|
|
6703
|
+
recursivelyDisconnectChildren(vnode.children);
|
|
6704
|
+
break;
|
|
6705
|
+
|
|
6706
|
+
case 3
|
|
6707
|
+
/* CustomElement */
|
|
6708
|
+
:
|
|
6709
|
+
{
|
|
6710
|
+
const vm = getAssociatedVM(vnode.elm);
|
|
6711
|
+
resetComponentStateWhenRemoved(vm);
|
|
6712
|
+
break;
|
|
6713
|
+
}
|
|
6636
6714
|
}
|
|
6637
6715
|
}
|
|
6638
6716
|
}
|
|
@@ -6644,15 +6722,15 @@ function recursivelyDisconnectChildren(vnodes) {
|
|
|
6644
6722
|
|
|
6645
6723
|
function resetComponentRoot(vm) {
|
|
6646
6724
|
const {
|
|
6647
|
-
children
|
|
6725
|
+
children,
|
|
6726
|
+
renderRoot
|
|
6648
6727
|
} = vm;
|
|
6649
|
-
const rootNode = getRenderRoot(vm);
|
|
6650
6728
|
|
|
6651
6729
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
6652
6730
|
const child = children[i];
|
|
6653
6731
|
|
|
6654
6732
|
if (!shared.isNull(child) && !shared.isUndefined(child.elm)) {
|
|
6655
|
-
remove(child.elm,
|
|
6733
|
+
remove(child.elm, renderRoot);
|
|
6656
6734
|
}
|
|
6657
6735
|
}
|
|
6658
6736
|
|
|
@@ -6736,11 +6814,6 @@ function forceRehydration(vm) {
|
|
|
6736
6814
|
scheduleRehydration(vm);
|
|
6737
6815
|
}
|
|
6738
6816
|
}
|
|
6739
|
-
function getRenderRoot(vm) {
|
|
6740
|
-
return vm.renderMode === 1
|
|
6741
|
-
/* Shadow */
|
|
6742
|
-
? vm.cmpRoot : vm.elm;
|
|
6743
|
-
}
|
|
6744
6817
|
|
|
6745
6818
|
/*
|
|
6746
6819
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
@@ -7138,7 +7211,7 @@ exports.createVM = createVM;
|
|
|
7138
7211
|
exports.disconnectRootElement = disconnectRootElement;
|
|
7139
7212
|
exports.getAssociatedVMIfPresent = getAssociatedVMIfPresent;
|
|
7140
7213
|
exports.getComponentDef = getComponentDef;
|
|
7141
|
-
exports.
|
|
7214
|
+
exports.getComponentHtmlPrototype = getComponentHtmlPrototype;
|
|
7142
7215
|
exports.getUpgradableConstructor = getUpgradableConstructor;
|
|
7143
7216
|
exports.hydrateRootElement = hydrateRootElement;
|
|
7144
7217
|
exports.isComponentConstructor = isComponentConstructor;
|
|
@@ -7195,4 +7268,4 @@ exports.swapTemplate = swapTemplate;
|
|
|
7195
7268
|
exports.track = track;
|
|
7196
7269
|
exports.unwrap = unwrap;
|
|
7197
7270
|
exports.wire = wire;
|
|
7198
|
-
/* version: 2.7.
|
|
7271
|
+
/* version: 2.7.4 */
|