@lwc/engine-core 2.23.1 → 2.23.2

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.
@@ -3092,30 +3092,67 @@ function createStylesheet(vm, stylesheets) {
3092
3092
  * SPDX-License-Identifier: MIT
3093
3093
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3094
3094
  */
3095
+
3096
+ function checkHasVM(elm) {
3097
+ const hasVM = !shared.isUndefined(getAssociatedVMIfPresent(elm));
3098
+
3099
+ if (process.env.NODE_ENV !== 'production' && !hasVM) {
3100
+ // Occurs when an element is manually created with the same tag name as an existing LWC component. In that case,
3101
+ // we skip calling the LWC connectedCallback/disconnectedCallback logic and log an error.
3102
+ logError(`VM for tag name "${elm.tagName.toLowerCase()}" is undefined. ` + `This indicates that an element was created with this tag name, ` + `which is already reserved by an LWC component. Use lwc.createElement ` + `instead to create elements.`);
3103
+ }
3104
+
3105
+ return hasVM;
3106
+ }
3107
+
3095
3108
  function getUpgradableConstructor(tagName, renderer) {
3096
- const { getCustomElement, HTMLElementExported: RendererHTMLElement, defineCustomElement, } = renderer;
3097
- // Should never get a tag with upper case letter at this point, the compiler should
3098
- // produce only tags with lowercase letters
3099
- // But, for backwards compatibility, we will lower case the tagName
3100
- tagName = tagName.toLowerCase();
3101
- let CE = getCustomElement(tagName);
3102
- if (!shared.isUndefined(CE)) {
3103
- return CE;
3109
+ const {
3110
+ getCustomElement,
3111
+ HTMLElementExported: RendererHTMLElement,
3112
+ defineCustomElement
3113
+ } = renderer; // Should never get a tag with upper case letter at this point, the compiler should
3114
+ // produce only tags with lowercase letters
3115
+ // But, for backwards compatibility, we will lower case the tagName
3116
+
3117
+ tagName = tagName.toLowerCase();
3118
+ let CE = getCustomElement(tagName);
3119
+
3120
+ if (!shared.isUndefined(CE)) {
3121
+ return CE;
3122
+ }
3123
+ /**
3124
+ * LWC Upgradable Element reference to an element that was created
3125
+ * via the scoped registry mechanism, and that is ready to be upgraded.
3126
+ */
3127
+
3128
+
3129
+ CE = class LWCUpgradableElement extends RendererHTMLElement {
3130
+ constructor(upgradeCallback) {
3131
+ super();
3132
+
3133
+ if (shared.isFunction(upgradeCallback)) {
3134
+ upgradeCallback(this); // nothing to do with the result for now
3135
+ }
3104
3136
  }
3105
- /**
3106
- * LWC Upgradable Element reference to an element that was created
3107
- * via the scoped registry mechanism, and that is ready to be upgraded.
3108
- */
3109
- CE = class LWCUpgradableElement extends RendererHTMLElement {
3110
- constructor(upgradeCallback) {
3111
- super();
3112
- if (shared.isFunction(upgradeCallback)) {
3113
- upgradeCallback(this); // nothing to do with the result for now
3114
- }
3115
- }
3137
+
3138
+ };
3139
+
3140
+ if (features.lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3141
+ CE.prototype.connectedCallback = function () {
3142
+ if (checkHasVM(this)) {
3143
+ connectRootElement(this);
3144
+ }
3116
3145
  };
3117
- defineCustomElement(tagName, CE);
3118
- return CE;
3146
+
3147
+ CE.prototype.disconnectedCallback = function () {
3148
+ if (checkHasVM(this)) {
3149
+ disconnectRootElement(this);
3150
+ }
3151
+ };
3152
+ }
3153
+
3154
+ defineCustomElement(tagName, CE);
3155
+ return CE;
3119
3156
  }
3120
3157
 
3121
3158
  /*
@@ -3203,6 +3240,14 @@ function patchProps(oldVnode, vnode, renderer) {
3203
3240
  // different than the one previously set.
3204
3241
  if (isFirstPatch ||
3205
3242
  cur !== (isLiveBindingProp(sel, key) ? getProperty(elm, key) : oldProps[key])) {
3243
+ // Additional verification if properties are supported by the element
3244
+ // Validation relies on html properties and public properties being defined on the element,
3245
+ // SSR has its own custom validation.
3246
+ if (process.env.IS_BROWSER && process.env.NODE_ENV !== 'production') {
3247
+ if (!(key in elm)) {
3248
+ logWarn(`Unknown public property "${key}" of element <${elm.tagName.toLowerCase()}>. This is either a typo on the corresponding attribute "${shared.htmlPropertyToAttribute(key)}", or the attribute does not exist in this browser or DOM implementation.`);
3249
+ }
3250
+ }
3206
3251
  setProperty(elm, key, cur);
3207
3252
  }
3208
3253
  }
@@ -3361,579 +3406,802 @@ function applyStaticStyleAttribute(vnode, renderer) {
3361
3406
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3362
3407
  */
3363
3408
  function patchChildren(c1, c2, parent, renderer) {
3364
- if (hasDynamicChildren(c2)) {
3365
- updateDynamicChildren(c1, c2, parent, renderer);
3366
- }
3367
- else {
3368
- updateStaticChildren(c1, c2, parent, renderer);
3369
- }
3409
+ if (hasDynamicChildren(c2)) {
3410
+ updateDynamicChildren(c1, c2, parent, renderer);
3411
+ } else {
3412
+ updateStaticChildren(c1, c2, parent, renderer);
3413
+ }
3370
3414
  }
3415
+
3371
3416
  function patch(n1, n2, parent, renderer) {
3372
- var _a, _b;
3373
- if (n1 === n2) {
3374
- return;
3375
- }
3376
- if (process.env.NODE_ENV !== 'production') {
3377
- if (!isSameVnode(n1, n2)) {
3378
- throw new Error('Expected these VNodes to be the same: ' +
3379
- JSON.stringify({ sel: n1.sel, key: n1.key }) +
3380
- ', ' +
3381
- JSON.stringify({ sel: n2.sel, key: n2.key }));
3382
- }
3383
- }
3384
- switch (n2.type) {
3385
- case 0 /* VNodeType.Text */:
3386
- // VText has no special capability, fallback to the owner's renderer
3387
- patchText(n1, n2, renderer);
3388
- break;
3389
- case 1 /* VNodeType.Comment */:
3390
- // VComment has no special capability, fallback to the owner's renderer
3391
- patchComment(n1, n2, renderer);
3392
- break;
3393
- case 4 /* VNodeType.Static */:
3394
- n2.elm = n1.elm;
3395
- break;
3396
- case 2 /* VNodeType.Element */:
3397
- patchElement(n1, n2, (_a = n2.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3398
- break;
3399
- case 3 /* VNodeType.CustomElement */:
3400
- patchCustomElement(n1, n2, parent, (_b = n2.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3401
- break;
3417
+ var _a, _b;
3418
+
3419
+ if (n1 === n2) {
3420
+ return;
3421
+ }
3422
+
3423
+ if (process.env.NODE_ENV !== 'production') {
3424
+ if (!isSameVnode(n1, n2)) {
3425
+ throw new Error('Expected these VNodes to be the same: ' + JSON.stringify({
3426
+ sel: n1.sel,
3427
+ key: n1.key
3428
+ }) + ', ' + JSON.stringify({
3429
+ sel: n2.sel,
3430
+ key: n2.key
3431
+ }));
3402
3432
  }
3433
+ }
3434
+
3435
+ switch (n2.type) {
3436
+ case 0
3437
+ /* VNodeType.Text */
3438
+ :
3439
+ // VText has no special capability, fallback to the owner's renderer
3440
+ patchText(n1, n2, renderer);
3441
+ break;
3442
+
3443
+ case 1
3444
+ /* VNodeType.Comment */
3445
+ :
3446
+ // VComment has no special capability, fallback to the owner's renderer
3447
+ patchComment(n1, n2, renderer);
3448
+ break;
3449
+
3450
+ case 4
3451
+ /* VNodeType.Static */
3452
+ :
3453
+ n2.elm = n1.elm;
3454
+ break;
3455
+
3456
+ case 2
3457
+ /* VNodeType.Element */
3458
+ :
3459
+ patchElement(n1, n2, (_a = n2.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3460
+ break;
3461
+
3462
+ case 3
3463
+ /* VNodeType.CustomElement */
3464
+ :
3465
+ patchCustomElement(n1, n2, parent, (_b = n2.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3466
+ break;
3467
+ }
3403
3468
  }
3469
+
3404
3470
  function mount(node, parent, renderer, anchor) {
3405
- var _a, _b;
3406
- switch (node.type) {
3407
- case 0 /* VNodeType.Text */:
3408
- // VText has no special capability, fallback to the owner's renderer
3409
- mountText(node, parent, anchor, renderer);
3410
- break;
3411
- case 1 /* VNodeType.Comment */:
3412
- // VComment has no special capability, fallback to the owner's renderer
3413
- mountComment(node, parent, anchor, renderer);
3414
- break;
3415
- case 4 /* VNodeType.Static */:
3416
- // VStatic cannot have a custom renderer associated to them, using owner's renderer
3417
- mountStatic(node, parent, anchor, renderer);
3418
- break;
3419
- case 2 /* VNodeType.Element */:
3420
- // If the vnode data has a renderer override use it, else fallback to owner's renderer
3421
- mountElement(node, parent, anchor, (_a = node.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3422
- break;
3423
- case 3 /* VNodeType.CustomElement */:
3424
- // If the vnode data has a renderer override use it, else fallback to owner's renderer
3425
- mountCustomElement(node, parent, anchor, (_b = node.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3426
- break;
3427
- }
3471
+ var _a, _b;
3472
+
3473
+ switch (node.type) {
3474
+ case 0
3475
+ /* VNodeType.Text */
3476
+ :
3477
+ // VText has no special capability, fallback to the owner's renderer
3478
+ mountText(node, parent, anchor, renderer);
3479
+ break;
3480
+
3481
+ case 1
3482
+ /* VNodeType.Comment */
3483
+ :
3484
+ // VComment has no special capability, fallback to the owner's renderer
3485
+ mountComment(node, parent, anchor, renderer);
3486
+ break;
3487
+
3488
+ case 4
3489
+ /* VNodeType.Static */
3490
+ :
3491
+ // VStatic cannot have a custom renderer associated to them, using owner's renderer
3492
+ mountStatic(node, parent, anchor, renderer);
3493
+ break;
3494
+
3495
+ case 2
3496
+ /* VNodeType.Element */
3497
+ :
3498
+ // If the vnode data has a renderer override use it, else fallback to owner's renderer
3499
+ mountElement(node, parent, anchor, (_a = node.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3500
+ break;
3501
+
3502
+ case 3
3503
+ /* VNodeType.CustomElement */
3504
+ :
3505
+ // If the vnode data has a renderer override use it, else fallback to owner's renderer
3506
+ mountCustomElement(node, parent, anchor, (_b = node.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3507
+ break;
3508
+ }
3428
3509
  }
3510
+
3429
3511
  function patchText(n1, n2, renderer) {
3430
- n2.elm = n1.elm;
3431
- if (n2.text !== n1.text) {
3432
- updateTextContent(n2, renderer);
3433
- }
3512
+ n2.elm = n1.elm;
3513
+
3514
+ if (n2.text !== n1.text) {
3515
+ updateTextContent(n2, renderer);
3516
+ }
3434
3517
  }
3518
+
3435
3519
  function mountText(vnode, parent, anchor, renderer) {
3436
- const { owner } = vnode;
3437
- const { createText } = renderer;
3438
- const textNode = (vnode.elm = createText(vnode.text));
3439
- linkNodeToShadow(textNode, owner, renderer);
3440
- insertNode(textNode, parent, anchor, renderer);
3520
+ const {
3521
+ owner
3522
+ } = vnode;
3523
+ const {
3524
+ createText
3525
+ } = renderer;
3526
+ const textNode = vnode.elm = createText(vnode.text);
3527
+ linkNodeToShadow(textNode, owner, renderer);
3528
+ insertNode(textNode, parent, anchor, renderer);
3441
3529
  }
3530
+
3442
3531
  function patchComment(n1, n2, renderer) {
3443
- n2.elm = n1.elm;
3444
- // FIXME: Comment nodes should be static, we shouldn't need to diff them together. However
3445
- // it is the case today.
3446
- if (n2.text !== n1.text) {
3447
- updateTextContent(n2, renderer);
3448
- }
3532
+ n2.elm = n1.elm; // FIXME: Comment nodes should be static, we shouldn't need to diff them together. However
3533
+ // it is the case today.
3534
+
3535
+ if (n2.text !== n1.text) {
3536
+ updateTextContent(n2, renderer);
3537
+ }
3449
3538
  }
3539
+
3450
3540
  function mountComment(vnode, parent, anchor, renderer) {
3451
- const { owner } = vnode;
3452
- const { createComment } = renderer;
3453
- const commentNode = (vnode.elm = createComment(vnode.text));
3454
- linkNodeToShadow(commentNode, owner, renderer);
3455
- insertNode(commentNode, parent, anchor, renderer);
3541
+ const {
3542
+ owner
3543
+ } = vnode;
3544
+ const {
3545
+ createComment
3546
+ } = renderer;
3547
+ const commentNode = vnode.elm = createComment(vnode.text);
3548
+ linkNodeToShadow(commentNode, owner, renderer);
3549
+ insertNode(commentNode, parent, anchor, renderer);
3456
3550
  }
3551
+
3457
3552
  function mountElement(vnode, parent, anchor, renderer) {
3458
- const { sel, owner, data: { svg }, } = vnode;
3459
- const { createElement } = renderer;
3460
- const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
3461
- const elm = (vnode.elm = createElement(sel, namespace));
3462
- linkNodeToShadow(elm, owner, renderer);
3463
- applyStyleScoping(elm, owner, renderer);
3464
- applyDomManual(elm, vnode);
3465
- applyElementRestrictions(elm, vnode);
3466
- patchElementPropsAndAttrs$1(null, vnode, renderer);
3467
- insertNode(elm, parent, anchor, renderer);
3468
- mountVNodes(vnode.children, elm, renderer, null);
3553
+ const {
3554
+ sel,
3555
+ owner,
3556
+ data: {
3557
+ svg
3558
+ }
3559
+ } = vnode;
3560
+ const {
3561
+ createElement
3562
+ } = renderer;
3563
+ const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
3564
+ const elm = vnode.elm = createElement(sel, namespace);
3565
+ linkNodeToShadow(elm, owner, renderer);
3566
+ applyStyleScoping(elm, owner, renderer);
3567
+ applyDomManual(elm, vnode);
3568
+ applyElementRestrictions(elm, vnode);
3569
+ patchElementPropsAndAttrs$1(null, vnode, renderer);
3570
+ insertNode(elm, parent, anchor, renderer);
3571
+ mountVNodes(vnode.children, elm, renderer, null);
3469
3572
  }
3573
+
3470
3574
  function patchElement(n1, n2, renderer) {
3471
- const elm = (n2.elm = n1.elm);
3472
- patchElementPropsAndAttrs$1(n1, n2, renderer);
3473
- patchChildren(n1.children, n2.children, elm, renderer);
3575
+ const elm = n2.elm = n1.elm;
3576
+ patchElementPropsAndAttrs$1(n1, n2, renderer);
3577
+ patchChildren(n1.children, n2.children, elm, renderer);
3474
3578
  }
3579
+
3475
3580
  function mountStatic(vnode, parent, anchor, renderer) {
3476
- const { owner } = vnode;
3477
- const { cloneNode, isSyntheticShadowDefined } = renderer;
3478
- const elm = (vnode.elm = cloneNode(vnode.fragment, true));
3479
- linkNodeToShadow(elm, owner, renderer);
3480
- applyElementRestrictions(elm, vnode);
3481
- // Marks this node as Static to propagate the shadow resolver. must happen after elm is assigned to the proper shadow
3482
- const { renderMode, shadowMode } = owner;
3483
- if (isSyntheticShadowDefined) {
3484
- if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
3485
- elm[shared.KEY__SHADOW_STATIC] = true;
3486
- }
3581
+ const {
3582
+ owner
3583
+ } = vnode;
3584
+ const {
3585
+ cloneNode,
3586
+ isSyntheticShadowDefined
3587
+ } = renderer;
3588
+ const elm = vnode.elm = cloneNode(vnode.fragment, true);
3589
+ linkNodeToShadow(elm, owner, renderer);
3590
+ applyElementRestrictions(elm, vnode); // Marks this node as Static to propagate the shadow resolver. must happen after elm is assigned to the proper shadow
3591
+
3592
+ const {
3593
+ renderMode,
3594
+ shadowMode
3595
+ } = owner;
3596
+
3597
+ if (isSyntheticShadowDefined) {
3598
+ if (shadowMode === 1
3599
+ /* ShadowMode.Synthetic */
3600
+ || renderMode === 0
3601
+ /* RenderMode.Light */
3602
+ ) {
3603
+ elm[shared.KEY__SHADOW_STATIC] = true;
3487
3604
  }
3488
- insertNode(elm, parent, anchor, renderer);
3605
+ }
3606
+
3607
+ insertNode(elm, parent, anchor, renderer);
3489
3608
  }
3609
+
3490
3610
  function mountCustomElement(vnode, parent, anchor, renderer) {
3491
- const { sel, owner } = vnode;
3492
- const UpgradableConstructor = getUpgradableConstructor(sel, renderer);
3493
- /**
3494
- * Note: if the upgradable constructor does not expect, or throw when we new it
3495
- * with a callback as the first argument, we could implement a more advanced
3496
- * mechanism that only passes that argument if the constructor is known to be
3497
- * an upgradable custom element.
3498
- */
3499
- let vm;
3500
- const elm = new UpgradableConstructor((elm) => {
3501
- // the custom element from the registry is expecting an upgrade callback
3502
- vm = createViewModelHook(elm, vnode, renderer);
3503
- });
3504
- vnode.elm = elm;
3505
- vnode.vm = vm;
3506
- linkNodeToShadow(elm, owner, renderer);
3507
- applyStyleScoping(elm, owner, renderer);
3508
- if (vm) {
3509
- allocateChildren(vnode, vm);
3510
- }
3511
- else if (vnode.ctor !== UpgradableConstructor) {
3512
- throw new TypeError(`Incorrect Component Constructor`);
3513
- }
3514
- patchElementPropsAndAttrs$1(null, vnode, renderer);
3515
- insertNode(elm, parent, anchor, renderer);
3516
- if (vm) {
3611
+ const {
3612
+ sel,
3613
+ owner
3614
+ } = vnode;
3615
+ const UpgradableConstructor = getUpgradableConstructor(sel, renderer);
3616
+ /**
3617
+ * Note: if the upgradable constructor does not expect, or throw when we new it
3618
+ * with a callback as the first argument, we could implement a more advanced
3619
+ * mechanism that only passes that argument if the constructor is known to be
3620
+ * an upgradable custom element.
3621
+ */
3622
+
3623
+ let vm;
3624
+ const elm = new UpgradableConstructor(elm => {
3625
+ // the custom element from the registry is expecting an upgrade callback
3626
+ vm = createViewModelHook(elm, vnode, renderer);
3627
+ });
3628
+ vnode.elm = elm;
3629
+ vnode.vm = vm;
3630
+ linkNodeToShadow(elm, owner, renderer);
3631
+ applyStyleScoping(elm, owner, renderer);
3632
+
3633
+ if (vm) {
3634
+ allocateChildren(vnode, vm);
3635
+ } else if (vnode.ctor !== UpgradableConstructor) {
3636
+ throw new TypeError(`Incorrect Component Constructor`);
3637
+ }
3638
+
3639
+ patchElementPropsAndAttrs$1(null, vnode, renderer);
3640
+ insertNode(elm, parent, anchor, renderer);
3641
+
3642
+ if (vm) {
3643
+ if (process.env.IS_BROWSER) {
3644
+ if (!features.lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3517
3645
  if (process.env.NODE_ENV !== 'production') {
3518
- shared.assert.isTrue(vm.state === 0 /* VMState.created */, `${vm} cannot be recycled.`);
3646
+ // With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
3647
+ // noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
3648
+ shared.assert.isTrue(vm.state === 0
3649
+ /* VMState.created */
3650
+ , `${vm} cannot be recycled.`);
3519
3651
  }
3652
+
3520
3653
  runConnectedCallback(vm);
3654
+ }
3655
+ } else {
3656
+ // On the server, we don't have native custom element lifecycle callbacks, so we must
3657
+ // manually invoke the connectedCallback for a child component.
3658
+ runConnectedCallback(vm);
3521
3659
  }
3522
- mountVNodes(vnode.children, elm, renderer, null);
3523
- if (vm) {
3524
- appendVM(vm);
3525
- }
3660
+ }
3661
+
3662
+ mountVNodes(vnode.children, elm, renderer, null);
3663
+
3664
+ if (vm) {
3665
+ appendVM(vm);
3666
+ }
3526
3667
  }
3668
+
3527
3669
  function patchCustomElement(n1, n2, parent, renderer) {
3528
- if (n1.ctor !== n2.ctor) {
3529
- // If the constructor, unmount the current component and mount a new one using the new
3530
- // constructor.
3531
- const anchor = renderer.nextSibling(n1.elm);
3532
- unmount(n1, parent, renderer, true);
3533
- mountCustomElement(n2, parent, anchor, renderer);
3534
- }
3535
- else {
3536
- // Otherwise patch the existing component with new props/attrs/etc.
3537
- const elm = (n2.elm = n1.elm);
3538
- const vm = (n2.vm = n1.vm);
3539
- patchElementPropsAndAttrs$1(n1, n2, renderer);
3540
- if (!shared.isUndefined(vm)) {
3541
- // in fallback mode, the allocation will always set children to
3542
- // empty and delegate the real allocation to the slot elements
3543
- allocateChildren(n2, vm);
3544
- }
3545
- // in fallback mode, the children will be always empty, so, nothing
3546
- // will happen, but in native, it does allocate the light dom
3547
- patchChildren(n1.children, n2.children, elm, renderer);
3548
- if (!shared.isUndefined(vm)) {
3549
- // this will probably update the shadowRoot, but only if the vm is in a dirty state
3550
- // this is important to preserve the top to bottom synchronous rendering phase.
3551
- rerenderVM(vm);
3552
- }
3670
+ if (n1.ctor !== n2.ctor) {
3671
+ // If the constructor, unmount the current component and mount a new one using the new
3672
+ // constructor.
3673
+ const anchor = renderer.nextSibling(n1.elm);
3674
+ unmount(n1, parent, renderer, true);
3675
+ mountCustomElement(n2, parent, anchor, renderer);
3676
+ } else {
3677
+ // Otherwise patch the existing component with new props/attrs/etc.
3678
+ const elm = n2.elm = n1.elm;
3679
+ const vm = n2.vm = n1.vm;
3680
+ patchElementPropsAndAttrs$1(n1, n2, renderer);
3681
+
3682
+ if (!shared.isUndefined(vm)) {
3683
+ // in fallback mode, the allocation will always set children to
3684
+ // empty and delegate the real allocation to the slot elements
3685
+ allocateChildren(n2, vm);
3686
+ } // in fallback mode, the children will be always empty, so, nothing
3687
+ // will happen, but in native, it does allocate the light dom
3688
+
3689
+
3690
+ patchChildren(n1.children, n2.children, elm, renderer);
3691
+
3692
+ if (!shared.isUndefined(vm)) {
3693
+ // this will probably update the shadowRoot, but only if the vm is in a dirty state
3694
+ // this is important to preserve the top to bottom synchronous rendering phase.
3695
+ rerenderVM(vm);
3553
3696
  }
3697
+ }
3554
3698
  }
3699
+
3555
3700
  function mountVNodes(vnodes, parent, renderer, anchor, start = 0, end = vnodes.length) {
3556
- for (; start < end; ++start) {
3557
- const vnode = vnodes[start];
3558
- if (isVNode(vnode)) {
3559
- mount(vnode, parent, renderer, anchor);
3560
- }
3701
+ for (; start < end; ++start) {
3702
+ const vnode = vnodes[start];
3703
+
3704
+ if (isVNode(vnode)) {
3705
+ mount(vnode, parent, renderer, anchor);
3561
3706
  }
3707
+ }
3562
3708
  }
3709
+
3563
3710
  function unmount(vnode, parent, renderer, doRemove = false) {
3564
- const { type, elm, sel } = vnode;
3565
- // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
3566
- // subtree root, is the only element worth unmounting from the subtree.
3567
- if (doRemove) {
3568
- // The vnode might or might not have a data.renderer associated to it
3569
- // but the removal used here is from the owner instead.
3570
- removeNode(elm, parent, renderer);
3571
- }
3572
- switch (type) {
3573
- case 2 /* VNodeType.Element */: {
3574
- // Slot content is removed to trigger slotchange event when removing slot.
3575
- // Only required for synthetic shadow.
3576
- const shouldRemoveChildren = sel === 'slot' && vnode.owner.shadowMode === 1 /* ShadowMode.Synthetic */;
3577
- unmountVNodes(vnode.children, elm, renderer, shouldRemoveChildren);
3578
- break;
3579
- }
3580
- case 3 /* VNodeType.CustomElement */: {
3581
- const { vm } = vnode;
3582
- // No need to unmount the children here, `removeVM` will take care of removing the
3583
- // children.
3584
- if (!shared.isUndefined(vm)) {
3585
- removeVM(vm);
3586
- }
3711
+ const {
3712
+ type,
3713
+ elm,
3714
+ sel
3715
+ } = vnode; // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
3716
+ // subtree root, is the only element worth unmounting from the subtree.
3717
+
3718
+ if (doRemove) {
3719
+ // The vnode might or might not have a data.renderer associated to it
3720
+ // but the removal used here is from the owner instead.
3721
+ removeNode(elm, parent, renderer);
3722
+ }
3723
+
3724
+ switch (type) {
3725
+ case 2
3726
+ /* VNodeType.Element */
3727
+ :
3728
+ {
3729
+ // Slot content is removed to trigger slotchange event when removing slot.
3730
+ // Only required for synthetic shadow.
3731
+ const shouldRemoveChildren = sel === 'slot' && vnode.owner.shadowMode === 1
3732
+ /* ShadowMode.Synthetic */
3733
+ ;
3734
+ unmountVNodes(vnode.children, elm, renderer, shouldRemoveChildren);
3735
+ break;
3736
+ }
3737
+
3738
+ case 3
3739
+ /* VNodeType.CustomElement */
3740
+ :
3741
+ {
3742
+ const {
3743
+ vm
3744
+ } = vnode; // No need to unmount the children here, `removeVM` will take care of removing the
3745
+ // children.
3746
+
3747
+ if (!shared.isUndefined(vm)) {
3748
+ removeVM(vm);
3587
3749
  }
3588
- }
3750
+ }
3751
+ }
3589
3752
  }
3753
+
3590
3754
  function unmountVNodes(vnodes, parent, renderer, doRemove = false, start = 0, end = vnodes.length) {
3591
- for (; start < end; ++start) {
3592
- const ch = vnodes[start];
3593
- if (isVNode(ch)) {
3594
- unmount(ch, parent, renderer, doRemove);
3595
- }
3755
+ for (; start < end; ++start) {
3756
+ const ch = vnodes[start];
3757
+
3758
+ if (isVNode(ch)) {
3759
+ unmount(ch, parent, renderer, doRemove);
3596
3760
  }
3761
+ }
3597
3762
  }
3763
+
3598
3764
  function isVNode(vnode) {
3599
- return vnode != null;
3765
+ return vnode != null;
3600
3766
  }
3767
+
3601
3768
  function linkNodeToShadow(elm, owner, renderer) {
3602
- const { renderRoot, renderMode, shadowMode } = owner;
3603
- const { isSyntheticShadowDefined } = renderer;
3604
- // TODO [#1164]: this should eventually be done by the polyfill directly
3605
- if (isSyntheticShadowDefined) {
3606
- if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
3607
- elm[shared.KEY__SHADOW_RESOLVER] = renderRoot[shared.KEY__SHADOW_RESOLVER];
3608
- }
3769
+ const {
3770
+ renderRoot,
3771
+ renderMode,
3772
+ shadowMode
3773
+ } = owner;
3774
+ const {
3775
+ isSyntheticShadowDefined
3776
+ } = renderer; // TODO [#1164]: this should eventually be done by the polyfill directly
3777
+
3778
+ if (isSyntheticShadowDefined) {
3779
+ if (shadowMode === 1
3780
+ /* ShadowMode.Synthetic */
3781
+ || renderMode === 0
3782
+ /* RenderMode.Light */
3783
+ ) {
3784
+ elm[shared.KEY__SHADOW_RESOLVER] = renderRoot[shared.KEY__SHADOW_RESOLVER];
3609
3785
  }
3786
+ }
3610
3787
  }
3788
+
3611
3789
  function updateTextContent(vnode, renderer) {
3612
- const { elm, text } = vnode;
3613
- const { setText } = renderer;
3614
- if (process.env.NODE_ENV !== 'production') {
3615
- unlockDomMutation();
3616
- }
3617
- setText(elm, text);
3618
- if (process.env.NODE_ENV !== 'production') {
3619
- lockDomMutation();
3620
- }
3790
+ const {
3791
+ elm,
3792
+ text
3793
+ } = vnode;
3794
+ const {
3795
+ setText
3796
+ } = renderer;
3797
+
3798
+ if (process.env.NODE_ENV !== 'production') {
3799
+ unlockDomMutation();
3800
+ }
3801
+
3802
+ setText(elm, text);
3803
+
3804
+ if (process.env.NODE_ENV !== 'production') {
3805
+ lockDomMutation();
3806
+ }
3621
3807
  }
3808
+
3622
3809
  function insertNode(node, parent, anchor, renderer) {
3623
- if (process.env.NODE_ENV !== 'production') {
3624
- unlockDomMutation();
3625
- }
3626
- renderer.insert(node, parent, anchor);
3627
- if (process.env.NODE_ENV !== 'production') {
3628
- lockDomMutation();
3629
- }
3810
+ if (process.env.NODE_ENV !== 'production') {
3811
+ unlockDomMutation();
3812
+ }
3813
+
3814
+ renderer.insert(node, parent, anchor);
3815
+
3816
+ if (process.env.NODE_ENV !== 'production') {
3817
+ lockDomMutation();
3818
+ }
3630
3819
  }
3820
+
3631
3821
  function removeNode(node, parent, renderer) {
3632
- if (process.env.NODE_ENV !== 'production') {
3633
- unlockDomMutation();
3634
- }
3635
- renderer.remove(node, parent);
3636
- if (process.env.NODE_ENV !== 'production') {
3637
- lockDomMutation();
3638
- }
3822
+ if (process.env.NODE_ENV !== 'production') {
3823
+ unlockDomMutation();
3824
+ }
3825
+
3826
+ renderer.remove(node, parent);
3827
+
3828
+ if (process.env.NODE_ENV !== 'production') {
3829
+ lockDomMutation();
3830
+ }
3639
3831
  }
3832
+
3640
3833
  function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3641
- if (shared.isNull(oldVnode)) {
3642
- applyEventListeners(vnode, renderer);
3643
- applyStaticClassAttribute(vnode, renderer);
3644
- applyStaticStyleAttribute(vnode, renderer);
3645
- }
3646
- // Attrs need to be applied to element before props IE11 will wipe out value on radio inputs if
3647
- // value is set before type=radio.
3648
- patchClassAttribute(oldVnode, vnode, renderer);
3649
- patchStyleAttribute(oldVnode, vnode, renderer);
3650
- patchAttributes(oldVnode, vnode, renderer);
3651
- patchProps(oldVnode, vnode, renderer);
3834
+ if (shared.isNull(oldVnode)) {
3835
+ applyEventListeners(vnode, renderer);
3836
+ applyStaticClassAttribute(vnode, renderer);
3837
+ applyStaticStyleAttribute(vnode, renderer);
3838
+ } // Attrs need to be applied to element before props IE11 will wipe out value on radio inputs if
3839
+ // value is set before type=radio.
3840
+
3841
+
3842
+ patchClassAttribute(oldVnode, vnode, renderer);
3843
+ patchStyleAttribute(oldVnode, vnode, renderer);
3844
+ patchAttributes(oldVnode, vnode, renderer);
3845
+ patchProps(oldVnode, vnode, renderer);
3652
3846
  }
3847
+
3653
3848
  function applyStyleScoping(elm, owner, renderer) {
3654
- // Set the class name for `*.scoped.css` style scoping.
3655
- const scopeToken = getScopeTokenClass(owner);
3656
- if (!shared.isNull(scopeToken)) {
3657
- const { getClassList } = renderer;
3658
- // TODO [#2762]: this dot notation with add is probably problematic
3659
- // probably we should have a renderer api for just the add operation
3660
- getClassList(elm).add(scopeToken);
3661
- }
3662
- // Set property element for synthetic shadow DOM style scoping.
3663
- const { stylesheetToken: syntheticToken } = owner.context;
3664
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && !shared.isUndefined(syntheticToken)) {
3665
- elm.$shadowToken$ = syntheticToken;
3666
- }
3849
+ // Set the class name for `*.scoped.css` style scoping.
3850
+ const scopeToken = getScopeTokenClass(owner);
3851
+
3852
+ if (!shared.isNull(scopeToken)) {
3853
+ const {
3854
+ getClassList
3855
+ } = renderer; // TODO [#2762]: this dot notation with add is probably problematic
3856
+ // probably we should have a renderer api for just the add operation
3857
+
3858
+ getClassList(elm).add(scopeToken);
3859
+ } // Set property element for synthetic shadow DOM style scoping.
3860
+
3861
+
3862
+ const {
3863
+ stylesheetToken: syntheticToken
3864
+ } = owner.context;
3865
+
3866
+ if (owner.shadowMode === 1
3867
+ /* ShadowMode.Synthetic */
3868
+ && !shared.isUndefined(syntheticToken)) {
3869
+ elm.$shadowToken$ = syntheticToken;
3870
+ }
3667
3871
  }
3872
+
3668
3873
  function applyDomManual(elm, vnode) {
3669
- var _a;
3670
- const { owner, data: { context }, } = vnode;
3671
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && ((_a = context === null || context === void 0 ? void 0 : context.lwc) === null || _a === void 0 ? void 0 : _a.dom) === "manual" /* LwcDomMode.Manual */) {
3672
- elm.$domManual$ = true;
3874
+ var _a;
3875
+
3876
+ const {
3877
+ owner,
3878
+ data: {
3879
+ context
3673
3880
  }
3881
+ } = vnode;
3882
+
3883
+ if (owner.shadowMode === 1
3884
+ /* ShadowMode.Synthetic */
3885
+ && ((_a = context === null || context === void 0 ? void 0 : context.lwc) === null || _a === void 0 ? void 0 : _a.dom) === "manual"
3886
+ /* LwcDomMode.Manual */
3887
+ ) {
3888
+ elm.$domManual$ = true;
3889
+ }
3674
3890
  }
3891
+
3675
3892
  function applyElementRestrictions(elm, vnode) {
3676
- var _a, _b;
3677
- if (process.env.NODE_ENV !== 'production') {
3678
- const isPortal = vnode.type === 2 /* VNodeType.Element */ && ((_b = (_a = vnode.data.context) === null || _a === void 0 ? void 0 : _a.lwc) === null || _b === void 0 ? void 0 : _b.dom) === "manual" /* LwcDomMode.Manual */;
3679
- const isLight = vnode.owner.renderMode === 0 /* RenderMode.Light */;
3680
- patchElementWithRestrictions(elm, {
3681
- isPortal,
3682
- isLight,
3683
- });
3684
- }
3893
+ var _a, _b;
3894
+
3895
+ if (process.env.NODE_ENV !== 'production') {
3896
+ const isPortal = vnode.type === 2
3897
+ /* VNodeType.Element */
3898
+ && ((_b = (_a = vnode.data.context) === null || _a === void 0 ? void 0 : _a.lwc) === null || _b === void 0 ? void 0 : _b.dom) === "manual"
3899
+ /* LwcDomMode.Manual */
3900
+ ;
3901
+ const isLight = vnode.owner.renderMode === 0
3902
+ /* RenderMode.Light */
3903
+ ;
3904
+ patchElementWithRestrictions(elm, {
3905
+ isPortal,
3906
+ isLight
3907
+ });
3908
+ }
3685
3909
  }
3910
+
3686
3911
  function allocateChildren(vnode, vm) {
3687
- // A component with slots will re-render because:
3688
- // 1- There is a change of the internal state.
3689
- // 2- There is a change on the external api (ex: slots)
3690
- //
3691
- // In case #1, the vnodes in the cmpSlots will be reused since they didn't changed. This routine emptied the
3692
- // slotted children when those VCustomElement were rendered and therefore in subsequent calls to allocate children
3693
- // in a reused VCustomElement, there won't be any slotted children.
3694
- // For those cases, we will use the reference for allocated children stored when rendering the fresh VCustomElement.
3695
- //
3696
- // In case #2, we will always get a fresh VCustomElement.
3697
- const children = vnode.aChildren || vnode.children;
3698
- vm.aChildren = children;
3699
- const { renderMode, shadowMode } = vm;
3700
- if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
3701
- // slow path
3702
- allocateInSlot(vm, children);
3703
- // save the allocated children in case this vnode is reused.
3704
- vnode.aChildren = children;
3705
- // every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
3706
- vnode.children = EmptyArray;
3707
- }
3912
+ // A component with slots will re-render because:
3913
+ // 1- There is a change of the internal state.
3914
+ // 2- There is a change on the external api (ex: slots)
3915
+ //
3916
+ // In case #1, the vnodes in the cmpSlots will be reused since they didn't changed. This routine emptied the
3917
+ // slotted children when those VCustomElement were rendered and therefore in subsequent calls to allocate children
3918
+ // in a reused VCustomElement, there won't be any slotted children.
3919
+ // For those cases, we will use the reference for allocated children stored when rendering the fresh VCustomElement.
3920
+ //
3921
+ // In case #2, we will always get a fresh VCustomElement.
3922
+ const children = vnode.aChildren || vnode.children;
3923
+ vm.aChildren = children;
3924
+ const {
3925
+ renderMode,
3926
+ shadowMode
3927
+ } = vm;
3928
+
3929
+ if (shadowMode === 1
3930
+ /* ShadowMode.Synthetic */
3931
+ || renderMode === 0
3932
+ /* RenderMode.Light */
3933
+ ) {
3934
+ // slow path
3935
+ allocateInSlot(vm, children); // save the allocated children in case this vnode is reused.
3936
+
3937
+ vnode.aChildren = children; // every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
3938
+
3939
+ vnode.children = EmptyArray;
3940
+ }
3708
3941
  }
3942
+
3709
3943
  function createViewModelHook(elm, vnode, renderer) {
3710
- let vm = getAssociatedVMIfPresent(elm);
3711
- // There is a possibility that a custom element is registered under tagName, in which case, the
3712
- // initialization is already carry on, and there is nothing else to do here since this hook is
3713
- // called right after invoking `document.createElement`.
3714
- if (!shared.isUndefined(vm)) {
3715
- return vm;
3716
- }
3717
- const { sel, mode, ctor, owner } = vnode;
3718
- vm = createVM(elm, ctor, renderer, {
3719
- mode,
3720
- owner,
3721
- tagName: sel,
3722
- });
3723
- if (process.env.NODE_ENV !== 'production') {
3724
- shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
3725
- }
3944
+ let vm = getAssociatedVMIfPresent(elm); // There is a possibility that a custom element is registered under tagName, in which case, the
3945
+ // initialization is already carry on, and there is nothing else to do here since this hook is
3946
+ // called right after invoking `document.createElement`.
3947
+
3948
+ if (!shared.isUndefined(vm)) {
3726
3949
  return vm;
3950
+ }
3951
+
3952
+ const {
3953
+ sel,
3954
+ mode,
3955
+ ctor,
3956
+ owner
3957
+ } = vnode;
3958
+ vm = createVM(elm, ctor, renderer, {
3959
+ mode,
3960
+ owner,
3961
+ tagName: sel
3962
+ });
3963
+
3964
+ if (process.env.NODE_ENV !== 'production') {
3965
+ shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
3966
+ }
3967
+
3968
+ return vm;
3727
3969
  }
3970
+
3728
3971
  function allocateInSlot(vm, children) {
3729
- var _a;
3730
- const { cmpSlots: oldSlots } = vm;
3731
- const cmpSlots = (vm.cmpSlots = shared.create(null));
3732
- for (let i = 0, len = children.length; i < len; i += 1) {
3733
- const vnode = children[i];
3734
- if (shared.isNull(vnode)) {
3735
- continue;
3736
- }
3737
- let slotName = '';
3738
- if (isVBaseElement(vnode)) {
3739
- slotName = ((_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) || '';
3740
- }
3741
- const vnodes = (cmpSlots[slotName] = cmpSlots[slotName] || []);
3742
- shared.ArrayPush.call(vnodes, vnode);
3743
- }
3744
- if (shared.isFalse(vm.isDirty)) {
3745
- // We need to determine if the old allocation is really different from the new one
3746
- // and mark the vm as dirty
3747
- const oldKeys = shared.keys(oldSlots);
3748
- if (oldKeys.length !== shared.keys(cmpSlots).length) {
3749
- markComponentAsDirty(vm);
3750
- return;
3751
- }
3752
- for (let i = 0, len = oldKeys.length; i < len; i += 1) {
3753
- const key = oldKeys[i];
3754
- if (shared.isUndefined(cmpSlots[key]) || oldSlots[key].length !== cmpSlots[key].length) {
3755
- markComponentAsDirty(vm);
3756
- return;
3757
- }
3758
- const oldVNodes = oldSlots[key];
3759
- const vnodes = cmpSlots[key];
3760
- for (let j = 0, a = cmpSlots[key].length; j < a; j += 1) {
3761
- if (oldVNodes[j] !== vnodes[j]) {
3762
- markComponentAsDirty(vm);
3763
- return;
3764
- }
3765
- }
3972
+ var _a;
3973
+
3974
+ const {
3975
+ cmpSlots: oldSlots
3976
+ } = vm;
3977
+ const cmpSlots = vm.cmpSlots = shared.create(null);
3978
+
3979
+ for (let i = 0, len = children.length; i < len; i += 1) {
3980
+ const vnode = children[i];
3981
+
3982
+ if (shared.isNull(vnode)) {
3983
+ continue;
3984
+ }
3985
+
3986
+ let slotName = '';
3987
+
3988
+ if (isVBaseElement(vnode)) {
3989
+ slotName = ((_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) || '';
3990
+ }
3991
+
3992
+ const vnodes = cmpSlots[slotName] = cmpSlots[slotName] || [];
3993
+ shared.ArrayPush.call(vnodes, vnode);
3994
+ }
3995
+
3996
+ if (shared.isFalse(vm.isDirty)) {
3997
+ // We need to determine if the old allocation is really different from the new one
3998
+ // and mark the vm as dirty
3999
+ const oldKeys = shared.keys(oldSlots);
4000
+
4001
+ if (oldKeys.length !== shared.keys(cmpSlots).length) {
4002
+ markComponentAsDirty(vm);
4003
+ return;
4004
+ }
4005
+
4006
+ for (let i = 0, len = oldKeys.length; i < len; i += 1) {
4007
+ const key = oldKeys[i];
4008
+
4009
+ if (shared.isUndefined(cmpSlots[key]) || oldSlots[key].length !== cmpSlots[key].length) {
4010
+ markComponentAsDirty(vm);
4011
+ return;
4012
+ }
4013
+
4014
+ const oldVNodes = oldSlots[key];
4015
+ const vnodes = cmpSlots[key];
4016
+
4017
+ for (let j = 0, a = cmpSlots[key].length; j < a; j += 1) {
4018
+ if (oldVNodes[j] !== vnodes[j]) {
4019
+ markComponentAsDirty(vm);
4020
+ return;
3766
4021
  }
4022
+ }
3767
4023
  }
3768
- }
3769
- // Using a WeakMap instead of a WeakSet because this one works in IE11 :(
3770
- const FromIteration = new WeakMap();
3771
- // dynamic children means it was generated by an iteration
4024
+ }
4025
+ } // Using a WeakMap instead of a WeakSet because this one works in IE11 :(
4026
+
4027
+
4028
+ const FromIteration = new WeakMap(); // dynamic children means it was generated by an iteration
3772
4029
  // in a template, and will require a more complex diffing algo.
4030
+
3773
4031
  function markAsDynamicChildren(children) {
3774
- FromIteration.set(children, 1);
4032
+ FromIteration.set(children, 1);
3775
4033
  }
4034
+
3776
4035
  function hasDynamicChildren(children) {
3777
- return FromIteration.has(children);
4036
+ return FromIteration.has(children);
3778
4037
  }
4038
+
3779
4039
  function createKeyToOldIdx(children, beginIdx, endIdx) {
3780
- const map = {};
3781
- // TODO [#1637]: simplify this by assuming that all vnodes has keys
3782
- for (let j = beginIdx; j <= endIdx; ++j) {
3783
- const ch = children[j];
3784
- if (isVNode(ch)) {
3785
- const { key } = ch;
3786
- if (key !== undefined) {
3787
- map[key] = j;
3788
- }
3789
- }
4040
+ const map = {}; // TODO [#1637]: simplify this by assuming that all vnodes has keys
4041
+
4042
+ for (let j = beginIdx; j <= endIdx; ++j) {
4043
+ const ch = children[j];
4044
+
4045
+ if (isVNode(ch)) {
4046
+ const {
4047
+ key
4048
+ } = ch;
4049
+
4050
+ if (key !== undefined) {
4051
+ map[key] = j;
4052
+ }
3790
4053
  }
3791
- return map;
4054
+ }
4055
+
4056
+ return map;
3792
4057
  }
4058
+
3793
4059
  function updateDynamicChildren(oldCh, newCh, parent, renderer) {
3794
- let oldStartIdx = 0;
3795
- let newStartIdx = 0;
3796
- let oldEndIdx = oldCh.length - 1;
3797
- let oldStartVnode = oldCh[0];
3798
- let oldEndVnode = oldCh[oldEndIdx];
3799
- const newChEnd = newCh.length - 1;
3800
- let newEndIdx = newChEnd;
3801
- let newStartVnode = newCh[0];
3802
- let newEndVnode = newCh[newEndIdx];
3803
- let oldKeyToIdx;
3804
- let idxInOld;
3805
- let elmToMove;
3806
- let before;
3807
- let clonedOldCh = false;
3808
- while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
3809
- if (!isVNode(oldStartVnode)) {
3810
- oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
3811
- }
3812
- else if (!isVNode(oldEndVnode)) {
3813
- oldEndVnode = oldCh[--oldEndIdx];
3814
- }
3815
- else if (!isVNode(newStartVnode)) {
3816
- newStartVnode = newCh[++newStartIdx];
3817
- }
3818
- else if (!isVNode(newEndVnode)) {
3819
- newEndVnode = newCh[--newEndIdx];
3820
- }
3821
- else if (isSameVnode(oldStartVnode, newStartVnode)) {
3822
- patch(oldStartVnode, newStartVnode, parent, renderer);
3823
- oldStartVnode = oldCh[++oldStartIdx];
3824
- newStartVnode = newCh[++newStartIdx];
3825
- }
3826
- else if (isSameVnode(oldEndVnode, newEndVnode)) {
3827
- patch(oldEndVnode, newEndVnode, parent, renderer);
3828
- oldEndVnode = oldCh[--oldEndIdx];
3829
- newEndVnode = newCh[--newEndIdx];
3830
- }
3831
- else if (isSameVnode(oldStartVnode, newEndVnode)) {
3832
- // Vnode moved right
3833
- patch(oldStartVnode, newEndVnode, parent, renderer);
3834
- insertNode(oldStartVnode.elm, parent, renderer.nextSibling(oldEndVnode.elm), renderer);
3835
- oldStartVnode = oldCh[++oldStartIdx];
3836
- newEndVnode = newCh[--newEndIdx];
3837
- }
3838
- else if (isSameVnode(oldEndVnode, newStartVnode)) {
3839
- // Vnode moved left
3840
- patch(oldEndVnode, newStartVnode, parent, renderer);
3841
- insertNode(newStartVnode.elm, parent, oldStartVnode.elm, renderer);
3842
- oldEndVnode = oldCh[--oldEndIdx];
3843
- newStartVnode = newCh[++newStartIdx];
3844
- }
3845
- else {
3846
- if (oldKeyToIdx === undefined) {
3847
- oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
3848
- }
3849
- idxInOld = oldKeyToIdx[newStartVnode.key];
3850
- if (shared.isUndefined(idxInOld)) {
3851
- // New element
3852
- mount(newStartVnode, parent, renderer, oldStartVnode.elm);
3853
- newStartVnode = newCh[++newStartIdx];
3854
- }
3855
- else {
3856
- elmToMove = oldCh[idxInOld];
3857
- if (isVNode(elmToMove)) {
3858
- if (elmToMove.sel !== newStartVnode.sel) {
3859
- // New element
3860
- mount(newStartVnode, parent, renderer, oldStartVnode.elm);
3861
- }
3862
- else {
3863
- patch(elmToMove, newStartVnode, parent, renderer);
3864
- // Delete the old child, but copy the array since it is read-only.
3865
- // The `oldCh` will be GC'ed after `updateDynamicChildren` is complete,
3866
- // so we only care about the `oldCh` object inside this function.
3867
- // To avoid cloning over and over again, we check `clonedOldCh`
3868
- // and only clone once.
3869
- if (!clonedOldCh) {
3870
- clonedOldCh = true;
3871
- oldCh = [...oldCh];
3872
- }
3873
- // We've already cloned at least once, so it's no longer read-only
3874
- oldCh[idxInOld] = undefined;
3875
- insertNode(elmToMove.elm, parent, oldStartVnode.elm, renderer);
3876
- }
3877
- }
3878
- newStartVnode = newCh[++newStartIdx];
3879
- }
4060
+ let oldStartIdx = 0;
4061
+ let newStartIdx = 0;
4062
+ let oldEndIdx = oldCh.length - 1;
4063
+ let oldStartVnode = oldCh[0];
4064
+ let oldEndVnode = oldCh[oldEndIdx];
4065
+ const newChEnd = newCh.length - 1;
4066
+ let newEndIdx = newChEnd;
4067
+ let newStartVnode = newCh[0];
4068
+ let newEndVnode = newCh[newEndIdx];
4069
+ let oldKeyToIdx;
4070
+ let idxInOld;
4071
+ let elmToMove;
4072
+ let before;
4073
+ let clonedOldCh = false;
4074
+
4075
+ while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
4076
+ if (!isVNode(oldStartVnode)) {
4077
+ oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
4078
+ } else if (!isVNode(oldEndVnode)) {
4079
+ oldEndVnode = oldCh[--oldEndIdx];
4080
+ } else if (!isVNode(newStartVnode)) {
4081
+ newStartVnode = newCh[++newStartIdx];
4082
+ } else if (!isVNode(newEndVnode)) {
4083
+ newEndVnode = newCh[--newEndIdx];
4084
+ } else if (isSameVnode(oldStartVnode, newStartVnode)) {
4085
+ patch(oldStartVnode, newStartVnode, parent, renderer);
4086
+ oldStartVnode = oldCh[++oldStartIdx];
4087
+ newStartVnode = newCh[++newStartIdx];
4088
+ } else if (isSameVnode(oldEndVnode, newEndVnode)) {
4089
+ patch(oldEndVnode, newEndVnode, parent, renderer);
4090
+ oldEndVnode = oldCh[--oldEndIdx];
4091
+ newEndVnode = newCh[--newEndIdx];
4092
+ } else if (isSameVnode(oldStartVnode, newEndVnode)) {
4093
+ // Vnode moved right
4094
+ patch(oldStartVnode, newEndVnode, parent, renderer);
4095
+ insertNode(oldStartVnode.elm, parent, renderer.nextSibling(oldEndVnode.elm), renderer);
4096
+ oldStartVnode = oldCh[++oldStartIdx];
4097
+ newEndVnode = newCh[--newEndIdx];
4098
+ } else if (isSameVnode(oldEndVnode, newStartVnode)) {
4099
+ // Vnode moved left
4100
+ patch(oldEndVnode, newStartVnode, parent, renderer);
4101
+ insertNode(newStartVnode.elm, parent, oldStartVnode.elm, renderer);
4102
+ oldEndVnode = oldCh[--oldEndIdx];
4103
+ newStartVnode = newCh[++newStartIdx];
4104
+ } else {
4105
+ if (oldKeyToIdx === undefined) {
4106
+ oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
4107
+ }
4108
+
4109
+ idxInOld = oldKeyToIdx[newStartVnode.key];
4110
+
4111
+ if (shared.isUndefined(idxInOld)) {
4112
+ // New element
4113
+ mount(newStartVnode, parent, renderer, oldStartVnode.elm);
4114
+ newStartVnode = newCh[++newStartIdx];
4115
+ } else {
4116
+ elmToMove = oldCh[idxInOld];
4117
+
4118
+ if (isVNode(elmToMove)) {
4119
+ if (elmToMove.sel !== newStartVnode.sel) {
4120
+ // New element
4121
+ mount(newStartVnode, parent, renderer, oldStartVnode.elm);
4122
+ } else {
4123
+ patch(elmToMove, newStartVnode, parent, renderer); // Delete the old child, but copy the array since it is read-only.
4124
+ // The `oldCh` will be GC'ed after `updateDynamicChildren` is complete,
4125
+ // so we only care about the `oldCh` object inside this function.
4126
+ // To avoid cloning over and over again, we check `clonedOldCh`
4127
+ // and only clone once.
4128
+
4129
+ if (!clonedOldCh) {
4130
+ clonedOldCh = true;
4131
+ oldCh = [...oldCh];
4132
+ } // We've already cloned at least once, so it's no longer read-only
4133
+
4134
+
4135
+ oldCh[idxInOld] = undefined;
4136
+ insertNode(elmToMove.elm, parent, oldStartVnode.elm, renderer);
4137
+ }
3880
4138
  }
4139
+
4140
+ newStartVnode = newCh[++newStartIdx];
4141
+ }
3881
4142
  }
3882
- if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
3883
- if (oldStartIdx > oldEndIdx) {
3884
- // There's some cases in which the sub array of vnodes to be inserted is followed by null(s) and an
3885
- // already processed vnode, in such cases the vnodes to be inserted should be before that processed vnode.
3886
- let i = newEndIdx;
3887
- let n;
3888
- do {
3889
- n = newCh[++i];
3890
- } while (!isVNode(n) && i < newChEnd);
3891
- before = isVNode(n) ? n.elm : null;
3892
- mountVNodes(newCh, parent, renderer, before, newStartIdx, newEndIdx + 1);
3893
- }
3894
- else {
3895
- unmountVNodes(oldCh, parent, renderer, true, oldStartIdx, oldEndIdx + 1);
3896
- }
4143
+ }
4144
+
4145
+ if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
4146
+ if (oldStartIdx > oldEndIdx) {
4147
+ // There's some cases in which the sub array of vnodes to be inserted is followed by null(s) and an
4148
+ // already processed vnode, in such cases the vnodes to be inserted should be before that processed vnode.
4149
+ let i = newEndIdx;
4150
+ let n;
4151
+
4152
+ do {
4153
+ n = newCh[++i];
4154
+ } while (!isVNode(n) && i < newChEnd);
4155
+
4156
+ before = isVNode(n) ? n.elm : null;
4157
+ mountVNodes(newCh, parent, renderer, before, newStartIdx, newEndIdx + 1);
4158
+ } else {
4159
+ unmountVNodes(oldCh, parent, renderer, true, oldStartIdx, oldEndIdx + 1);
3897
4160
  }
4161
+ }
3898
4162
  }
4163
+
3899
4164
  function updateStaticChildren(c1, c2, parent, renderer) {
3900
- const c1Length = c1.length;
3901
- const c2Length = c2.length;
3902
- if (c1Length === 0) {
3903
- // the old list is empty, we can directly insert anything new
3904
- mountVNodes(c2, parent, renderer, null);
3905
- return;
3906
- }
3907
- if (c2Length === 0) {
3908
- // the old list is nonempty and the new list is empty so we can directly remove all old nodes
3909
- // this is the case in which the dynamic children of an if-directive should be removed
3910
- unmountVNodes(c1, parent, renderer, true);
3911
- return;
3912
- }
3913
- // if the old list is not empty, the new list MUST have the same
3914
- // amount of nodes, that's why we call this static children
3915
- let anchor = null;
3916
- for (let i = c2Length - 1; i >= 0; i -= 1) {
3917
- const n1 = c1[i];
3918
- const n2 = c2[i];
3919
- if (n2 !== n1) {
3920
- if (isVNode(n1)) {
3921
- if (isVNode(n2)) {
3922
- // both vnodes are equivalent, and we just need to patch them
3923
- patch(n1, n2, parent, renderer);
3924
- anchor = n2.elm;
3925
- }
3926
- else {
3927
- // removing the old vnode since the new one is null
3928
- unmount(n1, parent, renderer, true);
3929
- }
3930
- }
3931
- else if (isVNode(n2)) {
3932
- mount(n2, parent, renderer, anchor);
3933
- anchor = n2.elm;
3934
- }
4165
+ const c1Length = c1.length;
4166
+ const c2Length = c2.length;
4167
+
4168
+ if (c1Length === 0) {
4169
+ // the old list is empty, we can directly insert anything new
4170
+ mountVNodes(c2, parent, renderer, null);
4171
+ return;
4172
+ }
4173
+
4174
+ if (c2Length === 0) {
4175
+ // the old list is nonempty and the new list is empty so we can directly remove all old nodes
4176
+ // this is the case in which the dynamic children of an if-directive should be removed
4177
+ unmountVNodes(c1, parent, renderer, true);
4178
+ return;
4179
+ } // if the old list is not empty, the new list MUST have the same
4180
+ // amount of nodes, that's why we call this static children
4181
+
4182
+
4183
+ let anchor = null;
4184
+
4185
+ for (let i = c2Length - 1; i >= 0; i -= 1) {
4186
+ const n1 = c1[i];
4187
+ const n2 = c2[i];
4188
+
4189
+ if (n2 !== n1) {
4190
+ if (isVNode(n1)) {
4191
+ if (isVNode(n2)) {
4192
+ // both vnodes are equivalent, and we just need to patch them
4193
+ patch(n1, n2, parent, renderer);
4194
+ anchor = n2.elm;
4195
+ } else {
4196
+ // removing the old vnode since the new one is null
4197
+ unmount(n1, parent, renderer, true);
3935
4198
  }
4199
+ } else if (isVNode(n2)) {
4200
+ mount(n2, parent, renderer, anchor);
4201
+ anchor = n2.elm;
4202
+ }
3936
4203
  }
4204
+ }
3937
4205
  }
3938
4206
 
3939
4207
  /*
@@ -5892,6 +6160,7 @@ function hydrateNode(node, vnode, renderer) {
5892
6160
  }
5893
6161
  return renderer.nextSibling(hydratedNode);
5894
6162
  }
6163
+ const NODE_VALUE_PROP = 'nodeValue';
5895
6164
  function hydrateText(node, vnode, renderer) {
5896
6165
  var _a;
5897
6166
  if (!hasCorrectNodeType(vnode, node, 3 /* EnvNodeTypes.TEXT */, renderer)) {
@@ -5899,7 +6168,7 @@ function hydrateText(node, vnode, renderer) {
5899
6168
  }
5900
6169
  if (process.env.NODE_ENV !== 'production') {
5901
6170
  const { getProperty } = renderer;
5902
- const nodeValue = getProperty(node, 'nodeValue');
6171
+ const nodeValue = getProperty(node, NODE_VALUE_PROP);
5903
6172
  if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
5904
6173
  logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
5905
6174
  }
@@ -5916,13 +6185,13 @@ function hydrateComment(node, vnode, renderer) {
5916
6185
  }
5917
6186
  if (process.env.NODE_ENV !== 'production') {
5918
6187
  const { getProperty } = renderer;
5919
- const nodeValue = getProperty(node, 'nodeValue');
6188
+ const nodeValue = getProperty(node, NODE_VALUE_PROP);
5920
6189
  if (nodeValue !== vnode.text) {
5921
6190
  logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
5922
6191
  }
5923
6192
  }
5924
6193
  const { setProperty } = renderer;
5925
- setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
6194
+ setProperty(node, NODE_VALUE_PROP, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
5926
6195
  vnode.elm = node;
5927
6196
  return node;
5928
6197
  }
@@ -6190,13 +6459,13 @@ function areCompatibleNodes(client, ssr, vnode, renderer) {
6190
6459
  if (!hasCorrectNodeType(vnode, ssr, 3 /* EnvNodeTypes.TEXT */, renderer)) {
6191
6460
  return false;
6192
6461
  }
6193
- return getProperty(client, 'nodeValue') === getProperty(ssr, 'nodeValue');
6462
+ return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
6194
6463
  }
6195
6464
  if (getProperty(client, 'nodeType') === 8 /* EnvNodeTypes.COMMENT */) {
6196
6465
  if (!hasCorrectNodeType(vnode, ssr, 8 /* EnvNodeTypes.COMMENT */, renderer)) {
6197
6466
  return false;
6198
6467
  }
6199
- return getProperty(client, 'nodeValue') === getProperty(ssr, 'nodeValue');
6468
+ return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
6200
6469
  }
6201
6470
  if (!hasCorrectNodeType(vnode, ssr, 1 /* EnvNodeTypes.ELEMENT */, renderer)) {
6202
6471
  return false;
@@ -6391,4 +6660,4 @@ exports.swapTemplate = swapTemplate;
6391
6660
  exports.track = track;
6392
6661
  exports.unwrap = unwrap;
6393
6662
  exports.wire = wire;
6394
- /* version: 2.23.1 */
6663
+ /* version: 2.23.2 */