@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.
@@ -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
- function isUndef(s) {
446
- return s === undefined;
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 (c) 2018, salesforce.com, inc.
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 cmpRoot = attachShadow(elm, {
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.cmpRoot = cmpRoot;
2114
- associateVM(cmpRoot, vm);
1927
+ vm.shadowRoot = shadowRoot;
1928
+ associateVM(shadowRoot, vm);
2115
1929
 
2116
1930
  if (process.env.NODE_ENV !== 'production') {
2117
- patchShadowRootWithRestrictions(cmpRoot);
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.cmpRoot;
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, xmlNS);
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, xlinkNS);
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
- function insertNodeHook(vnode, parentNode, referenceNode) {
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
- function removeNodeHook(vnode, parentNode) {
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
- function patchElementPropsAndAttrs(oldVnode, vnode) {
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
- function hydrateElmHook(vnode) {
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
- /* manual */
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
- /* manual */
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 allocateChildrenHook(vnode, vm) {
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
- if (!shared.isUndefined(getAssociatedVMIfPresent(elm))) {
4192
- // There is a possibility that a custom element is registered under tagName,
4193
- // in which case, the initialization is already carry on, and there is nothing else
4194
- // to do here since this hook is called right after invoking `document.createElement`.
4195
- return;
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
- const def = getComponentInternalDef(ctor);
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 isElementNode(node) {
4245
- // eslint-disable-next-line lwc-internal/no-global-node
4246
- return node.nodeType === Node.ELEMENT_NODE;
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
- const {
4439
- data
4440
- } = vnode;
4441
- const slotName = data.attrs && data.attrs.slot || '';
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
- * Copyright (c) 2020, salesforce.com, inc.
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
- CE = class LWCUpgradableElement extends HTMLElementExported {
4520
- constructor(upgradeCallback) {
4521
- super();
4395
+ if (isVNode(ch)) {
4396
+ const {
4397
+ key
4398
+ } = ch;
4522
4399
 
4523
- if (shared.isFunction(upgradeCallback)) {
4524
- upgradeCallback(this); // nothing to do with the result for now
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
- * Copyright (c) 2018, salesforce.com, inc.
4535
- * All rights reserved.
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
- if (node.nodeValue !== vNode.text) {
4565
- logWarn('Hydration mismatch: text values do not match, will recover from the difference', vNode.owner);
4566
- }
4567
- } // always set the text value to the one from the vnode.
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
- node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
4571
- vNode.elm = node;
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
- if (process.env.NODE_ENV !== 'production') {
4592
- // eslint-disable-next-line lwc-internal/no-global-node
4593
- if (node.nodeType !== Node.COMMENT_NODE) {
4594
- logError('Hydration mismatch: incorrect node type received', vNode.owner);
4595
- shared.assert.fail('Hydration mismatch: incorrect node type received.');
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
- if (node.nodeValue !== vNode.text) {
4599
- logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vNode.owner);
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
- node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
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
- if (isDomManual) {
4655
- // it may be that this element has lwc:inner-html, we need to diff and in case are the same,
4656
- // remove the innerHTML from props so it reuses the existing dom elements.
4657
- const {
4658
- props
4659
- } = vnode.data;
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
- if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
4662
- if (elm.innerHTML === props.innerHTML) {
4663
- delete props.innerHTML;
4664
- } else {
4665
- logWarn(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
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
- if (!isDomManual) {
4673
- hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vnode.owner);
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
- patchChildren(vnode.elm, oldVnode.children, vnode.children);
4720
-
4721
- if (vm) {
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
- rerenderVM(vm);
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
- insert: (vnode, parentNode, referenceNode) => {
4732
- insertNodeHook(vnode, parentNode, referenceNode);
4733
- const vm = getAssociatedVMIfPresent(vnode.elm);
4522
+ }
4523
+ }
4734
4524
 
4735
- if (vm) {
4736
- if (process.env.NODE_ENV !== 'production') {
4737
- shared.assert.isTrue(vm.state === 0
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
- runConnectedCallback(vm);
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
- createChildrenHook(vnode);
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
- if (vm) {
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
- if (process.env.NODE_ENV !== 'production') {
4784
- shared.assert.isTrue(vm.state === 0
4785
- /* created */
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
- runConnectedCallback(vm);
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
- if (vm.renderMode !== 0
4792
- /* Light */
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
- if (isSyntheticShadowDefined) {
4810
- if (shadowMode === 1
4811
- /* Synthetic */
4812
- || renderMode === 0
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(childVnode && 'sel' in childVnode && 'data' in childVnode && 'children' in childVnode && 'text' in childVnode && 'elm' in childVnode && 'key' in childVnode, `${childVnode} is not a vnode.`);
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 text, elm;
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(childVnode && 'sel' in childVnode && 'data' in childVnode && 'children' in childVnode && 'text' in childVnode && 'elm' in childVnode && 'key' in childVnode, `${childVnode} is not a vnode.`);
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 text, elm;
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
- const data = EmptyObject;
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
- const data = EmptyObject;
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.cmpRoot);
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, def, options) {
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
- cmpRoot: null,
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) || !('cmpRoot' in 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
- hydrateChildrenHook(vmChildren, children, vm);
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) && shared.isArray(vnode.children) && !shared.isUndefined(vnode.elm)) {
6629
- // vnode is a VElement with children
6630
- if (shared.isUndefined(vnode.ctor)) {
6631
- // it is a VElement, just keep looking (recursively)
6632
- recursivelyDisconnectChildren(vnode.children);
6633
- } else {
6634
- // it is a VCustomElement, disconnect it and ignore its children
6635
- resetComponentStateWhenRemoved(getAssociatedVM(vnode.elm));
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, rootNode);
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.getComponentInternalDef = getComponentInternalDef;
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.3 */
7271
+ /* version: 2.7.4 */