@lwc/engine-core 2.25.1 → 2.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1465,7 +1465,9 @@ const refsCache = new WeakMap();
1465
1465
  const LightningElement = function () {
1466
1466
  // This should be as performant as possible, while any initialization should be done lazily
1467
1467
  if (shared.isNull(vmBeingConstructed)) {
1468
- throw new ReferenceError('Illegal constructor');
1468
+ // Thrown when doing something like `new LightningElement()` or
1469
+ // `class Foo extends LightningElement {}; new Foo()`
1470
+ throw new TypeError('Illegal constructor');
1469
1471
  }
1470
1472
  const vm = vmBeingConstructed;
1471
1473
  const { def, elm } = vm;
@@ -2529,274 +2531,213 @@ const swappedStyleMap = new WeakMap();
2529
2531
  const activeTemplates = new WeakMap();
2530
2532
  const activeComponents = new WeakMap();
2531
2533
  const activeStyles = new WeakMap();
2532
-
2533
2534
  function rehydrateHotTemplate(tpl) {
2534
- const list = activeTemplates.get(tpl);
2535
-
2536
- if (!shared.isUndefined(list)) {
2537
- list.forEach(vm => {
2538
- if (shared.isFalse(vm.isDirty)) {
2539
- // forcing the vm to rehydrate in the micro-task:
2540
- markComponentAsDirty(vm);
2541
- scheduleRehydration(vm);
2542
- }
2543
- }); // resetting the Set to release the memory of those vm references
2544
- // since they are not longer related to this template, instead
2545
- // they will get re-associated once these instances are rehydrated.
2546
-
2547
- list.clear();
2548
- }
2549
-
2550
- return true;
2535
+ const list = activeTemplates.get(tpl);
2536
+ if (!shared.isUndefined(list)) {
2537
+ list.forEach((vm) => {
2538
+ if (shared.isFalse(vm.isDirty)) {
2539
+ // forcing the vm to rehydrate in the micro-task:
2540
+ markComponentAsDirty(vm);
2541
+ scheduleRehydration(vm);
2542
+ }
2543
+ });
2544
+ // resetting the Set to release the memory of those vm references
2545
+ // since they are not longer related to this template, instead
2546
+ // they will get re-associated once these instances are rehydrated.
2547
+ list.clear();
2548
+ }
2549
+ return true;
2551
2550
  }
2552
-
2553
2551
  function rehydrateHotStyle(style) {
2554
- const list = activeStyles.get(style);
2555
-
2556
- if (!shared.isUndefined(list)) {
2557
- list.forEach(vm => {
2558
- // if a style definition is swapped, we must reset
2559
- // vm's template content in the next micro-task:
2560
- forceRehydration(vm);
2561
- }); // resetting the Set to release the memory of those vm references
2562
- // since they are not longer related to this style, instead
2563
- // they will get re-associated once these instances are rehydrated.
2564
-
2565
- list.clear();
2566
- }
2567
-
2568
- return true;
2552
+ const list = activeStyles.get(style);
2553
+ if (!shared.isUndefined(list)) {
2554
+ list.forEach((vm) => {
2555
+ // if a style definition is swapped, we must reset
2556
+ // vm's template content in the next micro-task:
2557
+ forceRehydration(vm);
2558
+ });
2559
+ // resetting the Set to release the memory of those vm references
2560
+ // since they are not longer related to this style, instead
2561
+ // they will get re-associated once these instances are rehydrated.
2562
+ list.clear();
2563
+ }
2564
+ return true;
2569
2565
  }
2570
-
2571
2566
  function rehydrateHotComponent(Ctor) {
2572
- const list = activeComponents.get(Ctor);
2573
- let canRefreshAllInstances = true;
2574
-
2575
- if (!shared.isUndefined(list)) {
2576
- list.forEach(vm => {
2577
- const {
2578
- owner
2579
- } = vm;
2580
-
2581
- if (!shared.isNull(owner)) {
2582
- // if a component class definition is swapped, we must reset
2583
- // owner's template content in the next micro-task:
2584
- forceRehydration(owner);
2585
- } else {
2586
- // the hot swapping for components only work for instances of components
2587
- // created from a template, root elements can't be swapped because we
2588
- // don't have a way to force the creation of the element with the same state
2589
- // of the current element.
2590
- // Instead, we can report the problem to the caller so it can take action,
2591
- // for example: reload the entire page.
2592
- canRefreshAllInstances = false;
2593
- }
2594
- }); // resetting the Set to release the memory of those vm references
2595
- // since they are not longer related to this constructor, instead
2596
- // they will get re-associated once these instances are rehydrated.
2597
-
2598
- list.clear();
2599
- }
2600
-
2601
- return canRefreshAllInstances;
2567
+ const list = activeComponents.get(Ctor);
2568
+ let canRefreshAllInstances = true;
2569
+ if (!shared.isUndefined(list)) {
2570
+ list.forEach((vm) => {
2571
+ const { owner } = vm;
2572
+ if (!shared.isNull(owner)) {
2573
+ // if a component class definition is swapped, we must reset
2574
+ // owner's template content in the next micro-task:
2575
+ forceRehydration(owner);
2576
+ }
2577
+ else {
2578
+ // the hot swapping for components only work for instances of components
2579
+ // created from a template, root elements can't be swapped because we
2580
+ // don't have a way to force the creation of the element with the same state
2581
+ // of the current element.
2582
+ // Instead, we can report the problem to the caller so it can take action,
2583
+ // for example: reload the entire page.
2584
+ canRefreshAllInstances = false;
2585
+ }
2586
+ });
2587
+ // resetting the Set to release the memory of those vm references
2588
+ // since they are not longer related to this constructor, instead
2589
+ // they will get re-associated once these instances are rehydrated.
2590
+ list.clear();
2591
+ }
2592
+ return canRefreshAllInstances;
2602
2593
  }
2603
-
2604
2594
  function getTemplateOrSwappedTemplate(tpl) {
2605
- if (process.env.NODE_ENV === 'production') {
2606
- // this method should never leak to prod
2607
- throw new ReferenceError();
2608
- }
2609
-
2610
- if (features.lwcRuntimeFlags.ENABLE_HMR) {
2595
+ if (process.env.NODE_ENV === 'production') {
2596
+ // this method should never leak to prod
2597
+ throw new ReferenceError();
2598
+ }
2611
2599
  const visited = new Set();
2612
-
2613
2600
  while (swappedTemplateMap.has(tpl) && !visited.has(tpl)) {
2614
- visited.add(tpl);
2615
- tpl = swappedTemplateMap.get(tpl);
2601
+ visited.add(tpl);
2602
+ tpl = swappedTemplateMap.get(tpl);
2616
2603
  }
2617
- }
2618
-
2619
- return tpl;
2604
+ return tpl;
2620
2605
  }
2621
2606
  function getComponentOrSwappedComponent(Ctor) {
2622
- if (process.env.NODE_ENV === 'production') {
2623
- // this method should never leak to prod
2624
- throw new ReferenceError();
2625
- }
2626
-
2627
- if (features.lwcRuntimeFlags.ENABLE_HMR) {
2607
+ if (process.env.NODE_ENV === 'production') {
2608
+ // this method should never leak to prod
2609
+ throw new ReferenceError();
2610
+ }
2628
2611
  const visited = new Set();
2629
-
2630
2612
  while (swappedComponentMap.has(Ctor) && !visited.has(Ctor)) {
2631
- visited.add(Ctor);
2632
- Ctor = swappedComponentMap.get(Ctor);
2613
+ visited.add(Ctor);
2614
+ Ctor = swappedComponentMap.get(Ctor);
2633
2615
  }
2634
- }
2635
-
2636
- return Ctor;
2616
+ return Ctor;
2637
2617
  }
2638
2618
  function getStyleOrSwappedStyle(style) {
2639
- if (process.env.NODE_ENV === 'production') {
2640
- // this method should never leak to prod
2641
- throw new ReferenceError();
2642
- }
2643
-
2644
- if (features.lwcRuntimeFlags.ENABLE_HMR) {
2619
+ if (process.env.NODE_ENV === 'production') {
2620
+ // this method should never leak to prod
2621
+ throw new ReferenceError();
2622
+ }
2645
2623
  const visited = new Set();
2646
-
2647
2624
  while (swappedStyleMap.has(style) && !visited.has(style)) {
2648
- visited.add(style);
2649
- style = swappedStyleMap.get(style);
2625
+ visited.add(style);
2626
+ style = swappedStyleMap.get(style);
2650
2627
  }
2651
- }
2652
-
2653
- return style;
2628
+ return style;
2654
2629
  }
2655
2630
  function setActiveVM(vm) {
2656
- if (process.env.NODE_ENV === 'production') {
2657
- // this method should never leak to prod
2658
- throw new ReferenceError();
2659
- }
2660
-
2661
- if (features.lwcRuntimeFlags.ENABLE_HMR) {
2631
+ if (process.env.NODE_ENV === 'production') {
2632
+ // this method should never leak to prod
2633
+ throw new ReferenceError();
2634
+ }
2662
2635
  // tracking active component
2663
2636
  const Ctor = vm.def.ctor;
2664
2637
  let componentVMs = activeComponents.get(Ctor);
2665
-
2666
2638
  if (shared.isUndefined(componentVMs)) {
2667
- componentVMs = new Set();
2668
- activeComponents.set(Ctor, componentVMs);
2669
- } // this will allow us to keep track of the hot components
2670
-
2671
-
2672
- componentVMs.add(vm); // tracking active template
2673
-
2639
+ componentVMs = new Set();
2640
+ activeComponents.set(Ctor, componentVMs);
2641
+ }
2642
+ // this will allow us to keep track of the hot components
2643
+ componentVMs.add(vm);
2644
+ // tracking active template
2674
2645
  const tpl = vm.cmpTemplate;
2675
-
2676
2646
  if (tpl) {
2677
- let templateVMs = activeTemplates.get(tpl);
2678
-
2679
- if (shared.isUndefined(templateVMs)) {
2680
- templateVMs = new Set();
2681
- activeTemplates.set(tpl, templateVMs);
2682
- } // this will allow us to keep track of the templates that are
2683
- // being used by a hot component
2684
-
2685
-
2686
- templateVMs.add(vm); // tracking active styles associated to template
2687
-
2688
- const stylesheets = tpl.stylesheets;
2689
-
2690
- if (!shared.isUndefined(stylesheets)) {
2691
- flattenStylesheets(stylesheets).forEach(stylesheet => {
2692
- // this is necessary because we don't hold the list of styles
2693
- // in the vm, we only hold the selected (already swapped template)
2694
- // but the styles attached to the template might not be the actual
2695
- // active ones, but the swapped versions of those.
2696
- stylesheet = getStyleOrSwappedStyle(stylesheet);
2697
- let stylesheetVMs = activeStyles.get(stylesheet);
2698
-
2699
- if (shared.isUndefined(stylesheetVMs)) {
2700
- stylesheetVMs = new Set();
2701
- activeStyles.set(stylesheet, stylesheetVMs);
2702
- } // this will allow us to keep track of the stylesheet that are
2703
- // being used by a hot component
2704
-
2705
-
2706
- stylesheetVMs.add(vm);
2707
- });
2708
- }
2647
+ let templateVMs = activeTemplates.get(tpl);
2648
+ if (shared.isUndefined(templateVMs)) {
2649
+ templateVMs = new Set();
2650
+ activeTemplates.set(tpl, templateVMs);
2651
+ }
2652
+ // this will allow us to keep track of the templates that are
2653
+ // being used by a hot component
2654
+ templateVMs.add(vm);
2655
+ // tracking active styles associated to template
2656
+ const stylesheets = tpl.stylesheets;
2657
+ if (!shared.isUndefined(stylesheets)) {
2658
+ flattenStylesheets(stylesheets).forEach((stylesheet) => {
2659
+ // this is necessary because we don't hold the list of styles
2660
+ // in the vm, we only hold the selected (already swapped template)
2661
+ // but the styles attached to the template might not be the actual
2662
+ // active ones, but the swapped versions of those.
2663
+ stylesheet = getStyleOrSwappedStyle(stylesheet);
2664
+ let stylesheetVMs = activeStyles.get(stylesheet);
2665
+ if (shared.isUndefined(stylesheetVMs)) {
2666
+ stylesheetVMs = new Set();
2667
+ activeStyles.set(stylesheet, stylesheetVMs);
2668
+ }
2669
+ // this will allow us to keep track of the stylesheet that are
2670
+ // being used by a hot component
2671
+ stylesheetVMs.add(vm);
2672
+ });
2673
+ }
2709
2674
  }
2710
- }
2711
2675
  }
2712
2676
  function removeActiveVM(vm) {
2713
- if (process.env.NODE_ENV === 'production') {
2714
- // this method should never leak to prod
2715
- throw new ReferenceError();
2716
- }
2717
-
2718
- if (features.lwcRuntimeFlags.ENABLE_HMR) {
2677
+ if (process.env.NODE_ENV === 'production') {
2678
+ // this method should never leak to prod
2679
+ throw new ReferenceError();
2680
+ }
2719
2681
  // tracking inactive component
2720
2682
  const Ctor = vm.def.ctor;
2721
2683
  let list = activeComponents.get(Ctor);
2722
-
2723
2684
  if (!shared.isUndefined(list)) {
2724
- // deleting the vm from the set to avoid leaking memory
2725
- list.delete(vm);
2726
- } // removing inactive template
2727
-
2728
-
2729
- const tpl = vm.cmpTemplate;
2730
-
2731
- if (tpl) {
2732
- list = activeTemplates.get(tpl);
2733
-
2734
- if (!shared.isUndefined(list)) {
2735
2685
  // deleting the vm from the set to avoid leaking memory
2736
2686
  list.delete(vm);
2737
- } // removing active styles associated to template
2738
-
2739
-
2740
- const styles = tpl.stylesheets;
2741
-
2742
- if (!shared.isUndefined(styles)) {
2743
- flattenStylesheets(styles).forEach(style => {
2744
- list = activeStyles.get(style);
2745
-
2746
- if (!shared.isUndefined(list)) {
2687
+ }
2688
+ // removing inactive template
2689
+ const tpl = vm.cmpTemplate;
2690
+ if (tpl) {
2691
+ list = activeTemplates.get(tpl);
2692
+ if (!shared.isUndefined(list)) {
2747
2693
  // deleting the vm from the set to avoid leaking memory
2748
2694
  list.delete(vm);
2749
- }
2750
- });
2751
- }
2695
+ }
2696
+ // removing active styles associated to template
2697
+ const styles = tpl.stylesheets;
2698
+ if (!shared.isUndefined(styles)) {
2699
+ flattenStylesheets(styles).forEach((style) => {
2700
+ list = activeStyles.get(style);
2701
+ if (!shared.isUndefined(list)) {
2702
+ // deleting the vm from the set to avoid leaking memory
2703
+ list.delete(vm);
2704
+ }
2705
+ });
2706
+ }
2752
2707
  }
2753
- }
2754
2708
  }
2755
2709
  function swapTemplate(oldTpl, newTpl) {
2756
- if (process.env.NODE_ENV !== 'production') {
2757
- if (isTemplateRegistered(oldTpl) && isTemplateRegistered(newTpl)) {
2758
- swappedTemplateMap.set(oldTpl, newTpl);
2759
- return rehydrateHotTemplate(oldTpl);
2760
- } else {
2761
- throw new TypeError(`Invalid Template`);
2710
+ if (process.env.NODE_ENV !== 'production') {
2711
+ if (isTemplateRegistered(oldTpl) && isTemplateRegistered(newTpl)) {
2712
+ swappedTemplateMap.set(oldTpl, newTpl);
2713
+ return rehydrateHotTemplate(oldTpl);
2714
+ }
2715
+ else {
2716
+ throw new TypeError(`Invalid Template`);
2717
+ }
2762
2718
  }
2763
- }
2764
-
2765
- if (!features.lwcRuntimeFlags.ENABLE_HMR) {
2766
- throw new Error('HMR is not enabled');
2767
- }
2768
-
2769
- return false;
2719
+ return false;
2770
2720
  }
2771
2721
  function swapComponent(oldComponent, newComponent) {
2772
- if (process.env.NODE_ENV !== 'production') {
2773
- if (isComponentConstructor(oldComponent) && isComponentConstructor(newComponent)) {
2774
- swappedComponentMap.set(oldComponent, newComponent);
2775
- return rehydrateHotComponent(oldComponent);
2776
- } else {
2777
- throw new TypeError(`Invalid Component`);
2722
+ if (process.env.NODE_ENV !== 'production') {
2723
+ if (isComponentConstructor(oldComponent) && isComponentConstructor(newComponent)) {
2724
+ swappedComponentMap.set(oldComponent, newComponent);
2725
+ return rehydrateHotComponent(oldComponent);
2726
+ }
2727
+ else {
2728
+ throw new TypeError(`Invalid Component`);
2729
+ }
2778
2730
  }
2779
- }
2780
-
2781
- if (!features.lwcRuntimeFlags.ENABLE_HMR) {
2782
- throw new Error('HMR is not enabled');
2783
- }
2784
-
2785
- return false;
2731
+ return false;
2786
2732
  }
2787
2733
  function swapStyle(oldStyle, newStyle) {
2788
- if (process.env.NODE_ENV !== 'production') {
2789
- // TODO [#1887]: once the support for registering styles is implemented
2790
- // we can add the validation of both styles around this block.
2791
- swappedStyleMap.set(oldStyle, newStyle);
2792
- return rehydrateHotStyle(oldStyle);
2793
- }
2794
-
2795
- if (!features.lwcRuntimeFlags.ENABLE_HMR) {
2796
- throw new Error('HMR is not enabled');
2797
- }
2798
-
2799
- return false;
2734
+ if (process.env.NODE_ENV !== 'production') {
2735
+ // TODO [#1887]: once the support for registering styles is implemented
2736
+ // we can add the validation of both styles around this block.
2737
+ swappedStyleMap.set(oldStyle, newStyle);
2738
+ return rehydrateHotStyle(oldStyle);
2739
+ }
2740
+ return false;
2800
2741
  }
2801
2742
 
2802
2743
  /*
@@ -3207,15 +3148,18 @@ function getScopeTokenClass(owner) {
3207
3148
  /**
3208
3149
  * This function returns the host style token for a custom element if it
3209
3150
  * exists. Otherwise it returns null.
3151
+ *
3152
+ * A host style token is applied to the component if scoped styles are used.
3210
3153
  */
3211
3154
 
3212
3155
  function getStylesheetTokenHost(vnode) {
3213
3156
  const {
3214
- template: {
3215
- stylesheetToken
3216
- }
3157
+ template
3217
3158
  } = getComponentInternalDef(vnode.ctor);
3218
- return !shared.isUndefined(stylesheetToken) ? makeHostToken(stylesheetToken) : null;
3159
+ const {
3160
+ stylesheetToken
3161
+ } = template;
3162
+ return !shared.isUndefined(stylesheetToken) && computeHasScopedStyles(template) ? makeHostToken(stylesheetToken) : null;
3219
3163
  }
3220
3164
 
3221
3165
  function getNearestNativeShadowComponent(vm) {
@@ -3269,75 +3213,6 @@ function createStylesheet(vm, stylesheets) {
3269
3213
  return null;
3270
3214
  }
3271
3215
 
3272
- /*
3273
- * Copyright (c) 2020, salesforce.com, inc.
3274
- * All rights reserved.
3275
- * SPDX-License-Identifier: MIT
3276
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3277
- */
3278
-
3279
- function checkHasVM(elm) {
3280
- const hasVM = !shared.isUndefined(getAssociatedVMIfPresent(elm));
3281
-
3282
- if (process.env.NODE_ENV !== 'production' && !hasVM) {
3283
- // Occurs when an element is manually created with the same tag name as an existing LWC component. In that case,
3284
- // we skip calling the LWC connectedCallback/disconnectedCallback logic and log an error.
3285
- 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.`);
3286
- }
3287
-
3288
- return hasVM;
3289
- }
3290
-
3291
- function getUpgradableConstructor(tagName, renderer) {
3292
- const {
3293
- getCustomElement,
3294
- HTMLElementExported: RendererHTMLElement,
3295
- defineCustomElement
3296
- } = renderer; // Should never get a tag with upper case letter at this point, the compiler should
3297
- // produce only tags with lowercase letters
3298
- // But, for backwards compatibility, we will lower case the tagName
3299
-
3300
- tagName = tagName.toLowerCase();
3301
- let CE = getCustomElement(tagName);
3302
-
3303
- if (!shared.isUndefined(CE)) {
3304
- return CE;
3305
- }
3306
- /**
3307
- * LWC Upgradable Element reference to an element that was created
3308
- * via the scoped registry mechanism, and that is ready to be upgraded.
3309
- */
3310
-
3311
-
3312
- CE = class LWCUpgradableElement extends RendererHTMLElement {
3313
- constructor(upgradeCallback) {
3314
- super();
3315
-
3316
- if (shared.isFunction(upgradeCallback)) {
3317
- upgradeCallback(this); // nothing to do with the result for now
3318
- }
3319
- }
3320
-
3321
- };
3322
-
3323
- if (features.lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3324
- CE.prototype.connectedCallback = function () {
3325
- if (checkHasVM(this)) {
3326
- connectRootElement(this);
3327
- }
3328
- };
3329
-
3330
- CE.prototype.disconnectedCallback = function () {
3331
- if (checkHasVM(this)) {
3332
- disconnectRootElement(this);
3333
- }
3334
- };
3335
- }
3336
-
3337
- defineCustomElement(tagName, CE);
3338
- return CE;
3339
- }
3340
-
3341
3216
  /*
3342
3217
  * Copyright (c) 2018, salesforce.com, inc.
3343
3218
  * All rights reserved.
@@ -3354,6 +3229,9 @@ function isSameVnode(vnode1, vnode2) {
3354
3229
  function isVCustomElement(vnode) {
3355
3230
  return vnode.type === 3 /* VNodeType.CustomElement */;
3356
3231
  }
3232
+ function isVScopedSlotFragment(vnode) {
3233
+ return vnode.type === 6 /* VNodeType.ScopedSlotFragment */;
3234
+ }
3357
3235
 
3358
3236
  /*
3359
3237
  * Copyright (c) 2018, salesforce.com, inc.
@@ -3851,7 +3729,9 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3851
3729
  sel,
3852
3730
  owner
3853
3731
  } = vnode;
3854
- const UpgradableConstructor = getUpgradableConstructor(sel, renderer);
3732
+ const {
3733
+ createCustomElement
3734
+ } = renderer;
3855
3735
  /**
3856
3736
  * Note: if the upgradable constructor does not expect, or throw when we new it
3857
3737
  * with a callback as the first argument, we could implement a more advanced
@@ -3860,10 +3740,25 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3860
3740
  */
3861
3741
 
3862
3742
  let vm;
3863
- const elm = new UpgradableConstructor(elm => {
3743
+
3744
+ const upgradeCallback = elm => {
3864
3745
  // the custom element from the registry is expecting an upgrade callback
3865
3746
  vm = createViewModelHook(elm, vnode, renderer);
3866
- });
3747
+ };
3748
+
3749
+ const connectedCallback = elm => {
3750
+ if (features.lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3751
+ connectRootElement(elm);
3752
+ }
3753
+ };
3754
+
3755
+ const disconnectedCallback = elm => {
3756
+ if (features.lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3757
+ disconnectRootElement(elm);
3758
+ }
3759
+ };
3760
+
3761
+ const elm = createCustomElement(sel, upgradeCallback, connectedCallback, disconnectedCallback);
3867
3762
  vnode.elm = elm;
3868
3763
  vnode.vm = vm;
3869
3764
  linkNodeToShadow(elm, owner, renderer);
@@ -3871,8 +3766,6 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3871
3766
 
3872
3767
  if (vm) {
3873
3768
  allocateChildren(vnode, vm);
3874
- } else if (vnode.ctor !== UpgradableConstructor) {
3875
- throw new TypeError(`Incorrect Component Constructor`);
3876
3769
  }
3877
3770
 
3878
3771
  patchElementPropsAndAttrs$1(null, vnode, renderer);
@@ -4177,7 +4070,7 @@ function allocateChildren(vnode, vm) {
4177
4070
  /* RenderMode.Light */
4178
4071
  ) {
4179
4072
  // slow path
4180
- allocateInSlot(vm, children); // save the allocated children in case this vnode is reused.
4073
+ allocateInSlot(vm, children, vnode.owner); // save the allocated children in case this vnode is reused.
4181
4074
 
4182
4075
  vnode.aChildren = children; // every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
4183
4076
 
@@ -4213,13 +4106,19 @@ function createViewModelHook(elm, vnode, renderer) {
4213
4106
  return vm;
4214
4107
  }
4215
4108
 
4216
- function allocateInSlot(vm, children) {
4217
- var _a;
4109
+ function allocateInSlot(vm, children, owner) {
4110
+ var _a, _b;
4218
4111
 
4219
4112
  const {
4220
- cmpSlots: oldSlots
4113
+ cmpSlots: {
4114
+ slotAssignments: oldSlotsMapping
4115
+ }
4221
4116
  } = vm;
4222
- const cmpSlots = vm.cmpSlots = shared.create(null);
4117
+ const cmpSlotsMapping = shared.create(null);
4118
+ vm.cmpSlots = {
4119
+ owner,
4120
+ slotAssignments: cmpSlotsMapping
4121
+ };
4223
4122
 
4224
4123
  for (let i = 0, len = children.length; i < len; i += 1) {
4225
4124
  const vnode = children[i];
@@ -4231,19 +4130,21 @@ function allocateInSlot(vm, children) {
4231
4130
  let slotName = '';
4232
4131
 
4233
4132
  if (isVBaseElement(vnode)) {
4234
- slotName = ((_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) || '';
4133
+ slotName = (_b = (_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : '';
4134
+ } else if (isVScopedSlotFragment(vnode)) {
4135
+ slotName = vnode.slotName;
4235
4136
  }
4236
4137
 
4237
- const vnodes = cmpSlots[slotName] = cmpSlots[slotName] || [];
4138
+ const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
4238
4139
  shared.ArrayPush.call(vnodes, vnode);
4239
4140
  }
4240
4141
 
4241
4142
  if (shared.isFalse(vm.isDirty)) {
4242
4143
  // We need to determine if the old allocation is really different from the new one
4243
4144
  // and mark the vm as dirty
4244
- const oldKeys = shared.keys(oldSlots);
4145
+ const oldKeys = shared.keys(oldSlotsMapping);
4245
4146
 
4246
- if (oldKeys.length !== shared.keys(cmpSlots).length) {
4147
+ if (oldKeys.length !== shared.keys(cmpSlotsMapping).length) {
4247
4148
  markComponentAsDirty(vm);
4248
4149
  return;
4249
4150
  }
@@ -4251,15 +4152,15 @@ function allocateInSlot(vm, children) {
4251
4152
  for (let i = 0, len = oldKeys.length; i < len; i += 1) {
4252
4153
  const key = oldKeys[i];
4253
4154
 
4254
- if (shared.isUndefined(cmpSlots[key]) || oldSlots[key].length !== cmpSlots[key].length) {
4155
+ if (shared.isUndefined(cmpSlotsMapping[key]) || oldSlotsMapping[key].length !== cmpSlotsMapping[key].length) {
4255
4156
  markComponentAsDirty(vm);
4256
4157
  return;
4257
4158
  }
4258
4159
 
4259
- const oldVNodes = oldSlots[key];
4260
- const vnodes = cmpSlots[key];
4160
+ const oldVNodes = oldSlotsMapping[key];
4161
+ const vnodes = cmpSlotsMapping[key];
4261
4162
 
4262
- for (let j = 0, a = cmpSlots[key].length; j < a; j += 1) {
4163
+ for (let j = 0, a = cmpSlotsMapping[key].length; j < a; j += 1) {
4263
4164
  if (oldVNodes[j] !== vnodes[j]) {
4264
4165
  markComponentAsDirty(vm);
4265
4166
  return;
@@ -4459,6 +4360,18 @@ const SymbolIterator = Symbol.iterator;
4459
4360
  function addVNodeToChildLWC(vnode) {
4460
4361
  shared.ArrayPush.call(getVMBeingRendered().velements, vnode);
4461
4362
  }
4363
+ // [s]coped [s]lot [f]actory
4364
+ function ssf(slotName, factory) {
4365
+ return {
4366
+ type: 6 /* VNodeType.ScopedSlotFragment */,
4367
+ factory,
4368
+ owner: getVMBeingRendered(),
4369
+ elm: undefined,
4370
+ sel: undefined,
4371
+ key: undefined,
4372
+ slotName,
4373
+ };
4374
+ }
4462
4375
  // [st]atic node
4463
4376
  function st(fragment, key) {
4464
4377
  return {
@@ -4542,9 +4455,31 @@ function s(slotName, data, children, slotset) {
4542
4455
  shared.assert.isTrue(shared.isArray(children), `h() 3rd argument children must be an array.`);
4543
4456
  }
4544
4457
  if (!shared.isUndefined(slotset) &&
4545
- !shared.isUndefined(slotset[slotName]) &&
4546
- slotset[slotName].length !== 0) {
4547
- children = slotset[slotName];
4458
+ !shared.isUndefined(slotset.slotAssignments) &&
4459
+ !shared.isUndefined(slotset.slotAssignments[slotName]) &&
4460
+ slotset.slotAssignments[slotName].length !== 0) {
4461
+ children = slotset.slotAssignments[slotName].reduce((acc, vnode) => {
4462
+ // If the passed slot content is factory, evaluate it and use the produced vnodes
4463
+ if (vnode && isVScopedSlotFragment(vnode)) {
4464
+ const vmBeingRenderedInception = getVMBeingRendered();
4465
+ let children = [];
4466
+ // Evaluate in the scope of the slot content's owner
4467
+ // if a slotset is provided, there will always be an owner. The only case where owner is
4468
+ // undefined is for root components, but root components cannot accept slotted content
4469
+ setVMBeingRendered(slotset.owner);
4470
+ try {
4471
+ children = vnode.factory(data.slotData);
4472
+ }
4473
+ finally {
4474
+ setVMBeingRendered(vmBeingRenderedInception);
4475
+ }
4476
+ return shared.ArrayConcat.call(acc, children);
4477
+ }
4478
+ else {
4479
+ // If the slot content is a static list of child nodes provided by the parent, nothing to do
4480
+ return shared.ArrayConcat.call(acc, vnode);
4481
+ }
4482
+ }, []);
4548
4483
  }
4549
4484
  const vmBeingRendered = getVMBeingRendered();
4550
4485
  const { renderMode, shadowMode } = vmBeingRendered;
@@ -4864,6 +4799,7 @@ const api = shared.freeze({
4864
4799
  gid,
4865
4800
  fid,
4866
4801
  shc,
4802
+ ssf,
4867
4803
  });
4868
4804
 
4869
4805
  /*
@@ -5000,9 +4936,9 @@ function validateSlots(vm, html) {
5000
4936
  }
5001
4937
  const { cmpSlots } = vm;
5002
4938
  const { slots = EmptyArray } = html;
5003
- for (const slotName in cmpSlots) {
4939
+ for (const slotName in cmpSlots.slotAssignments) {
5004
4940
  // eslint-disable-next-line @lwc/lwc-internal/no-production-assert
5005
- shared.assert.isTrue(shared.isArray(cmpSlots[slotName]), `Slots can only be set to an array, instead received ${shared.toString(cmpSlots[slotName])} for slot "${slotName}" in ${vm}.`);
4941
+ shared.assert.isTrue(shared.isArray(cmpSlots.slotAssignments[slotName]), `Slots can only be set to an array, instead received ${shared.toString(cmpSlots.slotAssignments[slotName])} for slot "${slotName}" in ${vm}.`);
5006
4942
  if (slotName !== '' && shared.ArrayIndexOf.call(slots, slotName) === -1) {
5007
4943
  // TODO [#1297]: this should never really happen because the compiler should always validate
5008
4944
  // eslint-disable-next-line @lwc/lwc-internal/no-production-assert
@@ -5499,7 +5435,9 @@ function createVM(elm, ctor, renderer, options) {
5499
5435
  velements: EmptyArray,
5500
5436
  cmpProps: shared.create(null),
5501
5437
  cmpFields: shared.create(null),
5502
- cmpSlots: shared.create(null),
5438
+ cmpSlots: {
5439
+ slotAssignments: shared.create(null)
5440
+ },
5503
5441
  oar: shared.create(null),
5504
5442
  cmpTemplate: null,
5505
5443
  hydrated: Boolean(hydrated),
@@ -6654,19 +6592,23 @@ function validateClassAttr(vnode, elm, renderer) {
6654
6592
  //
6655
6593
  // Consequently, hydration mismatches will occur if scoped CSS token classnames
6656
6594
  // are rendered during SSR. This needs to be accounted for when validating.
6657
- if (scopedToken) {
6595
+ if (!shared.isNull(scopedToken) || !shared.isNull(stylesheetTokenHost)) {
6658
6596
  if (!shared.isUndefined(className)) {
6659
- className = shared.isNull(stylesheetTokenHost)
6660
- ? `${scopedToken} ${className}`
6661
- : `${scopedToken} ${className} ${stylesheetTokenHost}`;
6597
+ // The order of the className should be scopedToken className stylesheetTokenHost
6598
+ const classTokens = [scopedToken, className, stylesheetTokenHost];
6599
+ const classNames = shared.ArrayFilter.call(classTokens, (token) => !shared.isNull(token));
6600
+ className = shared.ArrayJoin.call(classNames, ' ');
6662
6601
  }
6663
6602
  else if (!shared.isUndefined(classMap)) {
6664
- classMap = Object.assign(Object.assign(Object.assign({}, classMap), { [scopedToken]: true }), (shared.isNull(stylesheetTokenHost) ? {} : { [stylesheetTokenHost]: true }));
6603
+ classMap = Object.assign(Object.assign(Object.assign({}, classMap), (!shared.isNull(scopedToken) ? { [scopedToken]: true } : {})), (!shared.isNull(stylesheetTokenHost) ? { [stylesheetTokenHost]: true } : {}));
6665
6604
  }
6666
6605
  else {
6667
- className = shared.isNull(stylesheetTokenHost)
6668
- ? `${scopedToken}`
6669
- : `${scopedToken} ${stylesheetTokenHost}`;
6606
+ // The order of the className should be scopedToken stylesheetTokenHost
6607
+ const classTokens = [scopedToken, stylesheetTokenHost];
6608
+ const classNames = shared.ArrayFilter.call(classTokens, (token) => !shared.isNull(token));
6609
+ if (classNames.length) {
6610
+ className = shared.ArrayJoin.call(classNames, ' ');
6611
+ }
6670
6612
  }
6671
6613
  }
6672
6614
  let nodesAreCompatible = true;
@@ -6929,7 +6871,6 @@ exports.getAssociatedVMIfPresent = getAssociatedVMIfPresent;
6929
6871
  exports.getComponentConstructor = getComponentConstructor;
6930
6872
  exports.getComponentDef = getComponentDef;
6931
6873
  exports.getComponentHtmlPrototype = getComponentHtmlPrototype;
6932
- exports.getUpgradableConstructor = getUpgradableConstructor;
6933
6874
  exports.hydrateRoot = hydrateRoot;
6934
6875
  exports.isComponentConstructor = isComponentConstructor;
6935
6876
  exports.parseFragment = parseFragment;
@@ -6947,4 +6888,4 @@ exports.swapTemplate = swapTemplate;
6947
6888
  exports.track = track;
6948
6889
  exports.unwrap = unwrap;
6949
6890
  exports.wire = wire;
6950
- /* version: 2.25.1 */
6891
+ /* version: 2.27.0 */