@lwc/engine-core 2.9.0 → 2.10.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.
@@ -84,6 +84,19 @@ function cloneAndOmitKey(object, keyToOmit) {
84
84
 
85
85
  return result;
86
86
  }
87
+ function flattenStylesheets(stylesheets) {
88
+ const list = [];
89
+
90
+ for (const stylesheet of stylesheets) {
91
+ if (!Array.isArray(stylesheet)) {
92
+ list.push(stylesheet);
93
+ } else {
94
+ list.push(...flattenStylesheets(stylesheet));
95
+ }
96
+ }
97
+
98
+ return list;
99
+ }
87
100
 
88
101
  //
89
102
  // Primitives
@@ -2777,6 +2790,45 @@ function getDecoratorsMeta(Ctor) {
2777
2790
  return shared.isUndefined(meta) ? defaultMeta : meta;
2778
2791
  }
2779
2792
 
2793
+ /*
2794
+ * Copyright (c) 2018, salesforce.com, inc.
2795
+ * All rights reserved.
2796
+ * SPDX-License-Identifier: MIT
2797
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2798
+ */
2799
+ let warned = false;
2800
+
2801
+ if (process.env.NODE_ENV === 'development') {
2802
+ // @ts-ignore
2803
+ window.__lwcResetWarnedOnVersionMismatch = () => {
2804
+ warned = false;
2805
+ };
2806
+ }
2807
+
2808
+ function checkVersionMismatch(func, type) {
2809
+ const versionMatcher = func.toString().match(shared.LWC_VERSION_COMMENT_REGEX);
2810
+
2811
+ if (!shared.isNull(versionMatcher) && !warned) {
2812
+ const version = versionMatcher[1];
2813
+ const [major, minor] = version.split('.');
2814
+ const [expectedMajor, expectedMinor] = shared.LWC_VERSION.split('.');
2815
+
2816
+ if (major !== expectedMajor || minor !== expectedMinor) {
2817
+ warned = true; // only warn once to avoid flooding the console
2818
+ // stylesheets and templates do not have user-meaningful names, but components do
2819
+
2820
+ const friendlyName = type === 'component' ? `${type} ${func.name}` : type;
2821
+ logError(`LWC WARNING: current engine is v${shared.LWC_VERSION}, but ${friendlyName} was compiled with v${version}.\nPlease update your compiled code or LWC engine so that the versions match.\nNo further warnings will appear.`);
2822
+ }
2823
+ }
2824
+ }
2825
+
2826
+ /*
2827
+ * Copyright (c) 2018, salesforce.com, inc.
2828
+ * All rights reserved.
2829
+ * SPDX-License-Identifier: MIT
2830
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2831
+ */
2780
2832
  const signedTemplateSet = new Set();
2781
2833
  function defaultEmptyTemplate() {
2782
2834
  return [];
@@ -2785,12 +2837,27 @@ signedTemplateSet.add(defaultEmptyTemplate);
2785
2837
  function isTemplateRegistered(tpl) {
2786
2838
  return signedTemplateSet.has(tpl);
2787
2839
  }
2840
+
2841
+ function checkTemplateVersionMismatch(template) {
2842
+ checkVersionMismatch(template, 'template');
2843
+
2844
+ if (!shared.isUndefined(template.stylesheets)) {
2845
+ for (const stylesheet of flattenStylesheets(template.stylesheets)) {
2846
+ checkVersionMismatch(stylesheet, 'stylesheet');
2847
+ }
2848
+ }
2849
+ }
2788
2850
  /**
2789
2851
  * INTERNAL: This function can only be invoked by compiled code. The compiler
2790
2852
  * will prevent this function from being imported by userland code.
2791
2853
  */
2792
2854
 
2855
+
2793
2856
  function registerTemplate(tpl) {
2857
+ if (process.env.NODE_ENV !== 'production') {
2858
+ checkTemplateVersionMismatch(tpl);
2859
+ }
2860
+
2794
2861
  signedTemplateSet.add(tpl); // chaining this method as a way to wrap existing
2795
2862
  // assignment of templates easily, without too much transformation
2796
2863
 
@@ -3082,20 +3149,6 @@ function rehydrateHotComponent(Ctor) {
3082
3149
  return canRefreshAllInstances;
3083
3150
  }
3084
3151
 
3085
- function flattenStylesheets(stylesheets) {
3086
- const list = [];
3087
-
3088
- for (const stylesheet of stylesheets) {
3089
- if (!Array.isArray(stylesheet)) {
3090
- list.push(stylesheet);
3091
- } else {
3092
- list.push(...flattenStylesheets(stylesheet));
3093
- }
3094
- }
3095
-
3096
- return list;
3097
- }
3098
-
3099
3152
  function getTemplateOrSwappedTemplate(tpl) {
3100
3153
  if (process.env.NODE_ENV === 'production') {
3101
3154
  // this method should never leak to prod
@@ -3907,156 +3960,268 @@ function applyStaticStyleAttribute(vnode) {
3907
3960
  * SPDX-License-Identifier: MIT
3908
3961
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3909
3962
  */
3910
- const TextHook = {
3911
- create: vnode => {
3912
- const {
3913
- owner
3914
- } = vnode;
3915
- const elm = createText(vnode.text);
3916
- linkNodeToShadow(elm, owner);
3917
- vnode.elm = elm;
3918
- },
3919
- update: updateNodeHook,
3920
- insert: insertNode,
3921
- move: insertNode,
3922
- remove: removeNode
3923
- };
3924
- const CommentHook = {
3925
- create: vnode => {
3926
- const {
3927
- owner,
3928
- text
3929
- } = vnode;
3930
- const elm = createComment(text);
3931
- linkNodeToShadow(elm, owner);
3932
- vnode.elm = elm;
3933
- },
3934
- update: updateNodeHook,
3935
- insert: insertNode,
3936
- move: insertNode,
3937
- remove: removeNode
3938
- }; // insert is called after update, which is used somewhere else (via a module)
3939
- // to mark the vm as inserted, that means we cannot use update as the main channel
3940
- // to rehydrate when dirty, because sometimes the element is not inserted just yet,
3941
- // which breaks some invariants. For that reason, we have the following for any
3942
- // Custom Element that is inserted via a template.
3943
-
3944
- const ElementHook = {
3945
- create: vnode => {
3946
- const {
3947
- sel,
3948
- owner,
3949
- data: {
3950
- svg
3951
- }
3952
- } = vnode;
3953
- const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
3954
- const elm = createElement(sel, namespace);
3955
- linkNodeToShadow(elm, owner);
3956
- fallbackElmHook(elm, vnode);
3957
- vnode.elm = elm;
3958
- patchElementPropsAndAttrs$1(null, vnode);
3959
- },
3960
- update: (oldVnode, vnode) => {
3961
- patchElementPropsAndAttrs$1(oldVnode, vnode);
3962
- patchChildren(vnode.elm, oldVnode.children, vnode.children);
3963
- },
3964
- insert: (vnode, parentNode, referenceNode) => {
3965
- insertNode(vnode, parentNode, referenceNode);
3966
- createChildrenHook(vnode);
3967
- },
3968
- move: insertNode,
3969
- remove: (vnode, parentNode) => {
3970
- removeNode(vnode, parentNode);
3971
- removeChildren(vnode);
3963
+ function patchChildren(c1, c2, parent) {
3964
+ if (hasDynamicChildren(c2)) {
3965
+ updateDynamicChildren(c1, c2, parent);
3966
+ } else {
3967
+ updateStaticChildren(c1, c2, parent);
3968
+ }
3969
+ }
3970
+
3971
+ function patch(n1, n2) {
3972
+ if (n1 === n2) {
3973
+ return;
3972
3974
  }
3973
- };
3974
- const CustomElementHook = {
3975
- create: vnode => {
3976
- const {
3977
- sel,
3978
- owner
3979
- } = vnode;
3980
- const UpgradableConstructor = getUpgradableConstructor(sel);
3981
- /**
3982
- * Note: if the upgradable constructor does not expect, or throw when we new it
3983
- * with a callback as the first argument, we could implement a more advanced
3984
- * mechanism that only passes that argument if the constructor is known to be
3985
- * an upgradable custom element.
3986
- */
3987
-
3988
- let vm;
3989
- const elm = new UpgradableConstructor(elm => {
3990
- // the custom element from the registry is expecting an upgrade callback
3991
- vm = createViewModelHook(elm, vnode);
3992
- });
3993
- linkNodeToShadow(elm, owner);
3994
- vnode.elm = elm;
3995
3975
 
3996
- if (vm) {
3997
- allocateChildren(vnode, vm);
3998
- } else if (vnode.ctor !== UpgradableConstructor) {
3999
- throw new TypeError(`Incorrect Component Constructor`);
3976
+ if (process.env.NODE_ENV !== 'production') {
3977
+ if (!isSameVnode(n1, n2)) {
3978
+ throw new Error('Expected these VNodes to be the same: ' + JSON.stringify({
3979
+ sel: n1.sel,
3980
+ key: n1.key
3981
+ }) + ', ' + JSON.stringify({
3982
+ sel: n2.sel,
3983
+ key: n2.key
3984
+ }));
4000
3985
  }
3986
+ }
4001
3987
 
4002
- patchElementPropsAndAttrs$1(null, vnode);
4003
- },
4004
- update: (oldVnode, vnode) => {
4005
- patchElementPropsAndAttrs$1(oldVnode, vnode);
4006
- const vm = getAssociatedVMIfPresent(vnode.elm);
3988
+ switch (n2.type) {
3989
+ case 0
3990
+ /* Text */
3991
+ :
3992
+ patchText(n1, n2);
3993
+ break;
3994
+
3995
+ case 1
3996
+ /* Comment */
3997
+ :
3998
+ patchComment(n1, n2);
3999
+ break;
4007
4000
 
4008
- if (vm) {
4009
- // in fallback mode, the allocation will always set children to
4010
- // empty and delegate the real allocation to the slot elements
4011
- allocateChildren(vnode, vm);
4012
- } // in fallback mode, the children will be always empty, so, nothing
4013
- // will happen, but in native, it does allocate the light dom
4001
+ case 2
4002
+ /* Element */
4003
+ :
4004
+ patchElement(n1, n2);
4005
+ break;
4014
4006
 
4007
+ case 3
4008
+ /* CustomElement */
4009
+ :
4010
+ patchCustomElement(n1, n2);
4011
+ break;
4012
+ }
4013
+ }
4015
4014
 
4016
- patchChildren(vnode.elm, oldVnode.children, vnode.children);
4015
+ function mount(node, parent, anchor) {
4016
+ switch (node.type) {
4017
+ case 0
4018
+ /* Text */
4019
+ :
4020
+ mountText(node, parent, anchor);
4021
+ break;
4017
4022
 
4018
- if (vm) {
4019
- if (process.env.NODE_ENV !== 'production') {
4020
- shared.assert.isTrue(shared.isArray(vnode.children), `Invalid vnode for a custom element, it must have children defined.`);
4021
- } // this will probably update the shadowRoot, but only if the vm is in a dirty state
4022
- // this is important to preserve the top to bottom synchronous rendering phase.
4023
+ case 1
4024
+ /* Comment */
4025
+ :
4026
+ mountComment(node, parent, anchor);
4027
+ break;
4028
+
4029
+ case 2
4030
+ /* Element */
4031
+ :
4032
+ mountElement(node, parent, anchor);
4033
+ break;
4034
+
4035
+ case 3
4036
+ /* CustomElement */
4037
+ :
4038
+ mountCustomElement(node, parent, anchor);
4039
+ break;
4040
+ }
4041
+ }
4042
+
4043
+ function patchText(n1, n2) {
4044
+ n2.elm = n1.elm;
4045
+
4046
+ if (n2.text !== n1.text) {
4047
+ updateTextContent(n2);
4048
+ }
4049
+ }
4050
+
4051
+ function mountText(node, parent, anchor) {
4052
+ const {
4053
+ owner
4054
+ } = node;
4055
+ const textNode = node.elm = createText(node.text);
4056
+ linkNodeToShadow(textNode, owner);
4057
+ insertNode(textNode, parent, anchor);
4058
+ }
4059
+
4060
+ function patchComment(n1, n2) {
4061
+ n2.elm = n1.elm; // FIXME: Comment nodes should be static, we shouldn't need to diff them together. However
4062
+ // it is the case today.
4063
+
4064
+ if (n2.text !== n1.text) {
4065
+ updateTextContent(n2);
4066
+ }
4067
+ }
4023
4068
 
4069
+ function mountComment(node, parent, anchor) {
4070
+ const {
4071
+ owner
4072
+ } = node;
4073
+ const commentNode = node.elm = createComment(node.text);
4074
+ linkNodeToShadow(commentNode, owner);
4075
+ insertNode(commentNode, parent, anchor);
4076
+ }
4024
4077
 
4025
- rerenderVM(vm);
4078
+ function mountElement(vnode, parent, anchor) {
4079
+ const {
4080
+ sel,
4081
+ owner,
4082
+ data: {
4083
+ svg
4026
4084
  }
4027
- },
4028
- insert: (vnode, parentNode, referenceNode) => {
4029
- insertNode(vnode, parentNode, referenceNode);
4030
- const vm = getAssociatedVMIfPresent(vnode.elm);
4085
+ } = vnode;
4086
+ const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
4087
+ const elm = createElement(sel, namespace);
4088
+ linkNodeToShadow(elm, owner);
4089
+ fallbackElmHook(elm, vnode);
4090
+ vnode.elm = elm;
4091
+ patchElementPropsAndAttrs$1(null, vnode);
4092
+ insertNode(elm, parent, anchor);
4093
+ mountVNodes(vnode.children, elm, null);
4094
+ }
4031
4095
 
4032
- if (vm) {
4033
- if (process.env.NODE_ENV !== 'production') {
4034
- shared.assert.isTrue(vm.state === 0
4035
- /* created */
4036
- , `${vm} cannot be recycled.`);
4037
- }
4096
+ function patchElement(n1, n2) {
4097
+ const elm = n2.elm = n1.elm;
4098
+ patchElementPropsAndAttrs$1(n1, n2);
4099
+ patchChildren(n1.children, n2.children, elm);
4100
+ }
4101
+
4102
+ function mountCustomElement(vnode, parent, anchor) {
4103
+ const {
4104
+ sel,
4105
+ owner
4106
+ } = vnode;
4107
+ const UpgradableConstructor = getUpgradableConstructor(sel);
4108
+ /**
4109
+ * Note: if the upgradable constructor does not expect, or throw when we new it
4110
+ * with a callback as the first argument, we could implement a more advanced
4111
+ * mechanism that only passes that argument if the constructor is known to be
4112
+ * an upgradable custom element.
4113
+ */
4114
+
4115
+ let vm;
4116
+ const elm = new UpgradableConstructor(elm => {
4117
+ // the custom element from the registry is expecting an upgrade callback
4118
+ vm = createViewModelHook(elm, vnode);
4119
+ });
4120
+ linkNodeToShadow(elm, owner);
4121
+ vnode.elm = elm;
4122
+ vnode.vm = vm;
4123
+
4124
+ if (vm) {
4125
+ allocateChildren(vnode, vm);
4126
+ } else if (vnode.ctor !== UpgradableConstructor) {
4127
+ throw new TypeError(`Incorrect Component Constructor`);
4128
+ }
4129
+
4130
+ patchElementPropsAndAttrs$1(null, vnode);
4131
+ insertNode(elm, parent, anchor);
4038
4132
 
4039
- runConnectedCallback(vm);
4133
+ if (vm) {
4134
+ if (process.env.NODE_ENV !== 'production') {
4135
+ shared.assert.isTrue(vm.state === 0
4136
+ /* created */
4137
+ , `${vm} cannot be recycled.`);
4040
4138
  }
4041
4139
 
4042
- createChildrenHook(vnode);
4140
+ runConnectedCallback(vm);
4141
+ }
4142
+
4143
+ mountVNodes(vnode.children, elm, null);
4144
+
4145
+ if (vm) {
4146
+ appendVM(vm);
4147
+ }
4148
+ }
4149
+
4150
+ function patchCustomElement(n1, n2) {
4151
+ const elm = n2.elm = n1.elm;
4152
+ const vm = n2.vm = n1.vm;
4153
+ patchElementPropsAndAttrs$1(n1, n2);
4154
+
4155
+ if (!shared.isUndefined(vm)) {
4156
+ // in fallback mode, the allocation will always set children to
4157
+ // empty and delegate the real allocation to the slot elements
4158
+ allocateChildren(n2, vm);
4159
+ } // in fallback mode, the children will be always empty, so, nothing
4160
+ // will happen, but in native, it does allocate the light dom
4161
+
4162
+
4163
+ patchChildren(n1.children, n2.children, elm);
4043
4164
 
4044
- if (vm) {
4045
- appendVM(vm);
4165
+ if (!shared.isUndefined(vm)) {
4166
+ // this will probably update the shadowRoot, but only if the vm is in a dirty state
4167
+ // this is important to preserve the top to bottom synchronous rendering phase.
4168
+ rerenderVM(vm);
4169
+ }
4170
+ }
4171
+
4172
+ function mountVNodes(vnodes, parent, anchor, start = 0, end = vnodes.length) {
4173
+ for (; start < end; ++start) {
4174
+ const vnode = vnodes[start];
4175
+
4176
+ if (isVNode(vnode)) {
4177
+ mount(vnode, parent, anchor);
4046
4178
  }
4047
- },
4048
- move: insertNode,
4049
- remove: (vnode, parentNode) => {
4050
- removeNode(vnode, parentNode);
4051
- const vm = getAssociatedVMIfPresent(vnode.elm);
4179
+ }
4180
+ }
4181
+
4182
+ function unmount(vnode, parent, doRemove = false) {
4183
+ const {
4184
+ type,
4185
+ elm
4186
+ } = vnode; // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
4187
+ // subtree root, is the only element worth unmounting from the subtree.
4188
+
4189
+ if (doRemove) {
4190
+ removeNode(elm, parent);
4191
+ }
4192
+
4193
+ switch (type) {
4194
+ case 2
4195
+ /* Element */
4196
+ :
4197
+ unmountVNodes(vnode.children, elm);
4198
+ break;
4199
+
4200
+ case 3
4201
+ /* CustomElement */
4202
+ :
4203
+ {
4204
+ const {
4205
+ vm
4206
+ } = vnode; // No need to unmount the children here, `removeVM` will take care of removing the
4207
+ // children.
4208
+
4209
+ if (!shared.isUndefined(vm)) {
4210
+ removeVM(vm);
4211
+ }
4212
+ }
4213
+ }
4214
+ }
4052
4215
 
4053
- if (vm) {
4054
- // for custom elements we don't have to go recursively because the removeVM routine
4055
- // will take care of disconnecting any child VM attached to its shadow as well.
4056
- removeVM(vm);
4216
+ function unmountVNodes(vnodes, parent, doRemove = false, start = 0, end = vnodes.length) {
4217
+ for (; start < end; ++start) {
4218
+ const ch = vnodes[start];
4219
+
4220
+ if (isVNode(ch)) {
4221
+ unmount(ch, parent, doRemove);
4057
4222
  }
4058
4223
  }
4059
- };
4224
+ }
4060
4225
 
4061
4226
  function isVNode(vnode) {
4062
4227
  return vnode != null;
@@ -4101,43 +4266,41 @@ function linkNodeToShadow(elm, owner) {
4101
4266
  }
4102
4267
  }
4103
4268
 
4104
- function updateNodeHook(oldVnode, vnode) {
4269
+ function updateTextContent(vnode) {
4105
4270
  const {
4106
4271
  elm,
4107
4272
  text
4108
4273
  } = vnode;
4109
4274
 
4110
- if (oldVnode.text !== text) {
4111
- if (process.env.NODE_ENV !== 'production') {
4112
- unlockDomMutation();
4113
- }
4275
+ if (process.env.NODE_ENV !== 'production') {
4276
+ unlockDomMutation();
4277
+ }
4114
4278
 
4115
- setText(elm, text);
4279
+ setText(elm, text);
4116
4280
 
4117
- if (process.env.NODE_ENV !== 'production') {
4118
- lockDomMutation();
4119
- }
4281
+ if (process.env.NODE_ENV !== 'production') {
4282
+ lockDomMutation();
4120
4283
  }
4121
4284
  }
4122
4285
 
4123
- function insertNode(vnode, parentNode, referenceNode) {
4286
+ function insertNode(node, parent, anchor) {
4124
4287
  if (process.env.NODE_ENV !== 'production') {
4125
4288
  unlockDomMutation();
4126
4289
  }
4127
4290
 
4128
- insert(vnode.elm, parentNode, referenceNode);
4291
+ insert(node, parent, anchor);
4129
4292
 
4130
4293
  if (process.env.NODE_ENV !== 'production') {
4131
4294
  lockDomMutation();
4132
4295
  }
4133
4296
  }
4134
4297
 
4135
- function removeNode(vnode, parentNode) {
4298
+ function removeNode(node, parent) {
4136
4299
  if (process.env.NODE_ENV !== 'production') {
4137
4300
  unlockDomMutation();
4138
4301
  }
4139
4302
 
4140
- remove(vnode.elm, parentNode);
4303
+ remove(node, parent);
4141
4304
 
4142
4305
  if (process.env.NODE_ENV !== 'production') {
4143
4306
  lockDomMutation();
@@ -4210,13 +4373,6 @@ function fallbackElmHook(elm, vnode) {
4210
4373
  }
4211
4374
  }
4212
4375
 
4213
- function patchChildren(parent, oldCh, newCh) {
4214
- if (hasDynamicChildren(newCh)) {
4215
- updateDynamicChildren(parent, oldCh, newCh);
4216
- } else {
4217
- updateStaticChildren(parent, oldCh, newCh);
4218
- }
4219
- }
4220
4376
  function allocateChildren(vnode, vm) {
4221
4377
  // A component with slots will re-render because:
4222
4378
  // 1- There is a change of the internal state.
@@ -4292,40 +4448,6 @@ function createViewModelHook(elm, vnode) {
4292
4448
  return vm;
4293
4449
  }
4294
4450
 
4295
- function createChildrenHook(vnode) {
4296
- const {
4297
- elm,
4298
- children
4299
- } = vnode;
4300
-
4301
- for (let j = 0; j < children.length; ++j) {
4302
- const ch = children[j];
4303
-
4304
- if (ch != null) {
4305
- ch.hook.create(ch);
4306
- ch.hook.insert(ch, elm, null);
4307
- }
4308
- }
4309
- }
4310
-
4311
- function removeChildren(vnode) {
4312
- // this method only needs to search on child vnodes from template
4313
- // to trigger the remove hook just in case some of those children
4314
- // are custom elements.
4315
- const {
4316
- children,
4317
- elm
4318
- } = vnode;
4319
-
4320
- for (let j = 0, len = children.length; j < len; ++j) {
4321
- const ch = children[j];
4322
-
4323
- if (!shared.isNull(ch)) {
4324
- ch.hook.remove(ch, elm);
4325
- }
4326
- }
4327
- }
4328
-
4329
4451
  function allocateInSlot(vm, children) {
4330
4452
  var _a;
4331
4453
 
@@ -4422,28 +4544,7 @@ function createKeyToOldIdx(children, beginIdx, endIdx) {
4422
4544
  return map;
4423
4545
  }
4424
4546
 
4425
- function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
4426
- for (; startIdx <= endIdx; ++startIdx) {
4427
- const ch = vnodes[startIdx];
4428
-
4429
- if (isVNode(ch)) {
4430
- ch.hook.create(ch);
4431
- ch.hook.insert(ch, parentElm, before);
4432
- }
4433
- }
4434
- }
4435
-
4436
- function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
4437
- for (; startIdx <= endIdx; ++startIdx) {
4438
- const ch = vnodes[startIdx]; // text nodes do not have logic associated to them
4439
-
4440
- if (isVNode(ch)) {
4441
- ch.hook.remove(ch, parentElm);
4442
- }
4443
- }
4444
- }
4445
-
4446
- function updateDynamicChildren(parentElm, oldCh, newCh) {
4547
+ function updateDynamicChildren(oldCh, newCh, parent) {
4447
4548
  let oldStartIdx = 0;
4448
4549
  let newStartIdx = 0;
4449
4550
  let oldEndIdx = oldCh.length - 1;
@@ -4469,23 +4570,23 @@ function updateDynamicChildren(parentElm, oldCh, newCh) {
4469
4570
  } else if (!isVNode(newEndVnode)) {
4470
4571
  newEndVnode = newCh[--newEndIdx];
4471
4572
  } else if (isSameVnode(oldStartVnode, newStartVnode)) {
4472
- patchVnode(oldStartVnode, newStartVnode);
4573
+ patch(oldStartVnode, newStartVnode);
4473
4574
  oldStartVnode = oldCh[++oldStartIdx];
4474
4575
  newStartVnode = newCh[++newStartIdx];
4475
4576
  } else if (isSameVnode(oldEndVnode, newEndVnode)) {
4476
- patchVnode(oldEndVnode, newEndVnode);
4577
+ patch(oldEndVnode, newEndVnode);
4477
4578
  oldEndVnode = oldCh[--oldEndIdx];
4478
4579
  newEndVnode = newCh[--newEndIdx];
4479
4580
  } else if (isSameVnode(oldStartVnode, newEndVnode)) {
4480
4581
  // Vnode moved right
4481
- patchVnode(oldStartVnode, newEndVnode);
4482
- newEndVnode.hook.move(oldStartVnode, parentElm, nextSibling(oldEndVnode.elm));
4582
+ patch(oldStartVnode, newEndVnode);
4583
+ insertNode(oldStartVnode.elm, parent, nextSibling(oldEndVnode.elm));
4483
4584
  oldStartVnode = oldCh[++oldStartIdx];
4484
4585
  newEndVnode = newCh[--newEndIdx];
4485
4586
  } else if (isSameVnode(oldEndVnode, newStartVnode)) {
4486
4587
  // Vnode moved left
4487
- patchVnode(oldEndVnode, newStartVnode);
4488
- newStartVnode.hook.move(oldEndVnode, parentElm, oldStartVnode.elm);
4588
+ patch(oldEndVnode, newStartVnode);
4589
+ insertNode(newStartVnode.elm, parent, oldStartVnode.elm);
4489
4590
  oldEndVnode = oldCh[--oldEndIdx];
4490
4591
  newStartVnode = newCh[++newStartIdx];
4491
4592
  } else {
@@ -4497,8 +4598,7 @@ function updateDynamicChildren(parentElm, oldCh, newCh) {
4497
4598
 
4498
4599
  if (shared.isUndefined(idxInOld)) {
4499
4600
  // New element
4500
- newStartVnode.hook.create(newStartVnode);
4501
- newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
4601
+ mount(newStartVnode, parent, oldStartVnode.elm);
4502
4602
  newStartVnode = newCh[++newStartIdx];
4503
4603
  } else {
4504
4604
  elmToMove = oldCh[idxInOld];
@@ -4506,10 +4606,9 @@ function updateDynamicChildren(parentElm, oldCh, newCh) {
4506
4606
  if (isVNode(elmToMove)) {
4507
4607
  if (elmToMove.sel !== newStartVnode.sel) {
4508
4608
  // New element
4509
- newStartVnode.hook.create(newStartVnode);
4510
- newStartVnode.hook.insert(newStartVnode, parentElm, oldStartVnode.elm);
4609
+ mount(newStartVnode, parent, oldStartVnode.elm);
4511
4610
  } else {
4512
- patchVnode(elmToMove, newStartVnode); // Delete the old child, but copy the array since it is read-only.
4611
+ patch(elmToMove, newStartVnode); // Delete the old child, but copy the array since it is read-only.
4513
4612
  // The `oldCh` will be GC'ed after `updateDynamicChildren` is complete,
4514
4613
  // so we only care about the `oldCh` object inside this function.
4515
4614
  // To avoid cloning over and over again, we check `clonedOldCh`
@@ -4522,7 +4621,7 @@ function updateDynamicChildren(parentElm, oldCh, newCh) {
4522
4621
 
4523
4622
 
4524
4623
  oldCh[idxInOld] = undefined;
4525
- newStartVnode.hook.move(elmToMove, parentElm, oldStartVnode.elm);
4624
+ insertNode(elmToMove.elm, parent, oldStartVnode.elm);
4526
4625
  }
4527
4626
  }
4528
4627
 
@@ -4543,66 +4642,56 @@ function updateDynamicChildren(parentElm, oldCh, newCh) {
4543
4642
  } while (!isVNode(n) && i < newChEnd);
4544
4643
 
4545
4644
  before = isVNode(n) ? n.elm : null;
4546
- addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx);
4645
+ mountVNodes(newCh, parent, before, newStartIdx, newEndIdx + 1);
4547
4646
  } else {
4548
- removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
4647
+ unmountVNodes(oldCh, parent, true, oldStartIdx, oldEndIdx + 1);
4549
4648
  }
4550
4649
  }
4551
4650
  }
4552
4651
 
4553
- function updateStaticChildren(parentElm, oldCh, newCh) {
4554
- const oldChLength = oldCh.length;
4555
- const newChLength = newCh.length;
4652
+ function updateStaticChildren(c1, c2, parent) {
4653
+ const c1Length = c1.length;
4654
+ const c2Length = c2.length;
4556
4655
 
4557
- if (oldChLength === 0) {
4656
+ if (c1Length === 0) {
4558
4657
  // the old list is empty, we can directly insert anything new
4559
- addVnodes(parentElm, null, newCh, 0, newChLength);
4658
+ mountVNodes(c2, parent, null);
4560
4659
  return;
4561
4660
  }
4562
4661
 
4563
- if (newChLength === 0) {
4662
+ if (c2Length === 0) {
4564
4663
  // the old list is nonempty and the new list is empty so we can directly remove all old nodes
4565
4664
  // this is the case in which the dynamic children of an if-directive should be removed
4566
- removeVnodes(parentElm, oldCh, 0, oldChLength);
4665
+ unmountVNodes(c1, parent, true);
4567
4666
  return;
4568
4667
  } // if the old list is not empty, the new list MUST have the same
4569
4668
  // amount of nodes, that's why we call this static children
4570
4669
 
4571
4670
 
4572
- let referenceElm = null;
4671
+ let anchor = null;
4573
4672
 
4574
- for (let i = newChLength - 1; i >= 0; i -= 1) {
4575
- const vnode = newCh[i];
4576
- const oldVNode = oldCh[i];
4673
+ for (let i = c2Length - 1; i >= 0; i -= 1) {
4674
+ const n1 = c1[i];
4675
+ const n2 = c2[i];
4577
4676
 
4578
- if (vnode !== oldVNode) {
4579
- if (isVNode(oldVNode)) {
4580
- if (isVNode(vnode)) {
4581
- // both vnodes must be equivalent, and se just need to patch them
4582
- patchVnode(oldVNode, vnode);
4583
- referenceElm = vnode.elm;
4677
+ if (n2 !== n1) {
4678
+ if (isVNode(n1)) {
4679
+ if (isVNode(n2)) {
4680
+ // both vnodes are equivalent, and we just need to patch them
4681
+ patch(n1, n2);
4682
+ anchor = n2.elm;
4584
4683
  } else {
4585
4684
  // removing the old vnode since the new one is null
4586
- oldVNode.hook.remove(oldVNode, parentElm);
4685
+ unmount(n1, parent, true);
4587
4686
  }
4588
- } else if (isVNode(vnode)) {
4589
- // this condition is unnecessary
4590
- vnode.hook.create(vnode); // insert the new node one since the old one is null
4591
-
4592
- vnode.hook.insert(vnode, parentElm, referenceElm);
4593
- referenceElm = vnode.elm;
4687
+ } else if (isVNode(n2)) {
4688
+ mount(n2, parent, anchor);
4689
+ anchor = n2.elm;
4594
4690
  }
4595
4691
  }
4596
4692
  }
4597
4693
  }
4598
4694
 
4599
- function patchVnode(oldVnode, vnode) {
4600
- if (oldVnode !== vnode) {
4601
- vnode.elm = oldVnode.elm;
4602
- vnode.hook.update(oldVnode, vnode);
4603
- }
4604
- }
4605
-
4606
4695
  /*
4607
4696
  * Copyright (c) 2018, salesforce.com, inc.
4608
4697
  * All rights reserved.
@@ -4652,7 +4741,6 @@ function h(sel, data, children = EmptyArray) {
4652
4741
  children,
4653
4742
  elm,
4654
4743
  key,
4655
- hook: ElementHook,
4656
4744
  owner: vmBeingRendered
4657
4745
  };
4658
4746
  } // [t]ab[i]ndex function
@@ -4739,7 +4827,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
4739
4827
  const {
4740
4828
  key
4741
4829
  } = data;
4742
- let elm;
4830
+ let elm, aChildren, vm;
4743
4831
  const vnode = {
4744
4832
  type: 3
4745
4833
  /* CustomElement */
@@ -4749,11 +4837,11 @@ function c(sel, Ctor, data, children = EmptyArray) {
4749
4837
  children,
4750
4838
  elm,
4751
4839
  key,
4752
- hook: CustomElementHook,
4753
4840
  ctor: Ctor,
4754
4841
  owner: vmBeingRendered,
4755
- mode: 'open' // TODO [#1294]: this should be defined in Ctor
4756
-
4842
+ mode: 'open',
4843
+ aChildren,
4844
+ vm
4757
4845
  };
4758
4846
  addVNodeToChildLWC(vnode);
4759
4847
  return vnode;
@@ -4883,7 +4971,6 @@ function t(text) {
4883
4971
  text,
4884
4972
  elm,
4885
4973
  key,
4886
- hook: TextHook,
4887
4974
  owner: getVMBeingRendered()
4888
4975
  };
4889
4976
  } // [co]mment node
@@ -4899,7 +4986,6 @@ function co(text) {
4899
4986
  text,
4900
4987
  elm,
4901
4988
  key,
4902
- hook: CommentHook,
4903
4989
  owner: getVMBeingRendered()
4904
4990
  };
4905
4991
  } // [d]ynamic text
@@ -5750,6 +5836,10 @@ const signedTemplateMap = new Map();
5750
5836
  function registerComponent(Ctor, {
5751
5837
  tmpl
5752
5838
  }) {
5839
+ if (process.env.NODE_ENV !== 'production') {
5840
+ checkVersionMismatch(Ctor, 'component');
5841
+ }
5842
+
5753
5843
  signedTemplateMap.set(Ctor, tmpl); // chaining this method as a way to wrap existing assignment of component constructor easily,
5754
5844
  // without too much transformation
5755
5845
 
@@ -5866,7 +5956,7 @@ function invokeServiceHook(vm, cbs) {
5866
5956
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
5867
5957
  */
5868
5958
 
5869
- function hydrate$1(vnode, node) {
5959
+ function hydrate(vnode, node) {
5870
5960
  switch (vnode.type) {
5871
5961
  case 0
5872
5962
  /* Text */
@@ -5898,16 +5988,18 @@ function hydrateText(vnode, node) {
5898
5988
  var _a;
5899
5989
 
5900
5990
  if (process.env.NODE_ENV !== 'production') {
5901
- // eslint-disable-next-line lwc-internal/no-global-node
5902
- validateNodeType(vnode, node, Node.TEXT_NODE);
5991
+ validateNodeType(vnode, node, 3
5992
+ /* TEXT */
5993
+ );
5994
+ const nodeValue = getProperty(node, 'nodeValue');
5903
5995
 
5904
- if (node.nodeValue !== vnode.text && !(node.nodeValue === '\u200D' && vnode.text === '')) {
5996
+ if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
5905
5997
  logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
5906
5998
  }
5907
5999
  } // always set the text value to the one from the vnode.
5908
6000
 
5909
6001
 
5910
- node.nodeValue = (_a = vnode.text) !== null && _a !== void 0 ? _a : null;
6002
+ setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
5911
6003
  vnode.elm = node;
5912
6004
  }
5913
6005
 
@@ -5915,23 +6007,25 @@ function hydrateComment(vnode, node) {
5915
6007
  var _a;
5916
6008
 
5917
6009
  if (process.env.NODE_ENV !== 'production') {
5918
- // eslint-disable-next-line lwc-internal/no-global-node
5919
- validateNodeType(vnode, node, Node.COMMENT_NODE);
6010
+ validateNodeType(vnode, node, 8
6011
+ /* COMMENT */
6012
+ );
5920
6013
 
5921
- if (node.nodeValue !== vnode.text) {
6014
+ if (getProperty(node, 'nodeValue') !== vnode.text) {
5922
6015
  logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
5923
6016
  }
5924
6017
  } // always set the text value to the one from the vnode.
5925
6018
 
5926
6019
 
5927
- node.nodeValue = (_a = vnode.text) !== null && _a !== void 0 ? _a : null;
6020
+ setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
5928
6021
  vnode.elm = node;
5929
6022
  }
5930
6023
 
5931
6024
  function hydrateElement(vnode, node) {
5932
6025
  if (process.env.NODE_ENV !== 'production') {
5933
- // eslint-disable-next-line lwc-internal/no-global-node
5934
- validateNodeType(vnode, node, Node.ELEMENT_NODE);
6026
+ validateNodeType(vnode, node, 1
6027
+ /* ELEMENT */
6028
+ );
5935
6029
  validateElement(vnode, node);
5936
6030
  }
5937
6031
 
@@ -5952,13 +6046,13 @@ function hydrateElement(vnode, node) {
5952
6046
  } = vnode.data;
5953
6047
 
5954
6048
  if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
5955
- if (elm.innerHTML === props.innerHTML) {
6049
+ if (getProperty(elm, 'innerHTML') === props.innerHTML) {
5956
6050
  // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
5957
6051
  vnode.data = Object.assign(Object.assign({}, vnode.data), {
5958
6052
  props: cloneAndOmitKey(props, 'innerHTML')
5959
6053
  });
5960
6054
  } else {
5961
- logWarn(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
6055
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
5962
6056
  }
5963
6057
  }
5964
6058
  }
@@ -5966,19 +6060,19 @@ function hydrateElement(vnode, node) {
5966
6060
  patchElementPropsAndAttrs(vnode);
5967
6061
 
5968
6062
  if (!isDomManual) {
5969
- hydrateChildren(vnode.elm.childNodes, vnode.children, vnode.owner);
6063
+ hydrateChildren(getChildNodes(vnode.elm), vnode.children, vnode.owner);
5970
6064
  }
5971
6065
  }
5972
6066
 
5973
6067
  function hydrateCustomElement(vnode, node) {
5974
6068
  if (process.env.NODE_ENV !== 'production') {
5975
- // eslint-disable-next-line lwc-internal/no-global-node
5976
- validateNodeType(vnode, node, Node.ELEMENT_NODE);
6069
+ validateNodeType(vnode, node, 1
6070
+ /* ELEMENT */
6071
+ );
5977
6072
  validateElement(vnode, node);
5978
6073
  }
5979
6074
 
5980
6075
  const elm = node;
5981
- vnode.elm = elm;
5982
6076
  const {
5983
6077
  sel,
5984
6078
  mode,
@@ -5990,6 +6084,8 @@ function hydrateCustomElement(vnode, node) {
5990
6084
  owner,
5991
6085
  tagName: sel
5992
6086
  });
6087
+ vnode.elm = elm;
6088
+ vnode.vm = vm;
5993
6089
  allocateChildren(vnode, vm);
5994
6090
  patchElementPropsAndAttrs(vnode); // Insert hook section:
5995
6091
 
@@ -6006,7 +6102,7 @@ function hydrateCustomElement(vnode, node) {
6006
6102
  ) {
6007
6103
  // VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
6008
6104
  // Note: for Light DOM, this is handled while hydrating the VM
6009
- hydrateChildren(vnode.elm.childNodes, vnode.children, vm);
6105
+ hydrateChildren(getChildNodes(vnode.elm), vnode.children, vm);
6010
6106
  }
6011
6107
 
6012
6108
  hydrateVM(vm);
@@ -6029,7 +6125,7 @@ function hydrateChildren(elmChildren, children, vm) {
6029
6125
 
6030
6126
  if (!shared.isNull(childVnode)) {
6031
6127
  const childNode = elmChildren[childNodeIndex];
6032
- hydrate$1(childVnode, childNode);
6128
+ hydrate(childVnode, childNode);
6033
6129
  childNodeIndex++;
6034
6130
  }
6035
6131
  }
@@ -6045,15 +6141,15 @@ function throwHydrationError() {
6045
6141
  }
6046
6142
 
6047
6143
  function validateNodeType(vnode, node, nodeType) {
6048
- if (node.nodeType !== nodeType) {
6144
+ if (getProperty(node, 'nodeType') !== nodeType) {
6049
6145
  logError('Hydration mismatch: incorrect node type received', vnode.owner);
6050
6146
  shared.assert.fail('Hydration mismatch: incorrect node type received.');
6051
6147
  }
6052
6148
  }
6053
6149
 
6054
6150
  function validateElement(vnode, elm) {
6055
- if (vnode.sel.toLowerCase() !== elm.tagName.toLowerCase()) {
6056
- logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${elm.tagName.toLowerCase()}".`, vnode.owner);
6151
+ if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
6152
+ logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
6057
6153
  throwHydrationError();
6058
6154
  }
6059
6155
 
@@ -6080,7 +6176,7 @@ function validateAttrs(vnode, elm) {
6080
6176
  const elmAttrValue = getAttribute(elm, attrName);
6081
6177
 
6082
6178
  if (String(attrValue) !== elmAttrValue) {
6083
- logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
6179
+ logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
6084
6180
  nodesAreCompatible = false;
6085
6181
  }
6086
6182
  }
@@ -6098,7 +6194,7 @@ function validateClassAttr(vnode, elm) {
6098
6194
  let nodesAreCompatible = true;
6099
6195
  let vnodeClassName;
6100
6196
 
6101
- if (!shared.isUndefined(className) && String(className) !== elm.className) {
6197
+ if (!shared.isUndefined(className) && String(className) !== getProperty(elm, 'className')) {
6102
6198
  // className is used when class is bound to an expr.
6103
6199
  nodesAreCompatible = false;
6104
6200
  vnodeClassName = className;
@@ -6123,7 +6219,7 @@ function validateClassAttr(vnode, elm) {
6123
6219
  }
6124
6220
 
6125
6221
  if (!nodesAreCompatible) {
6126
- logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${elm.className}"`, vnode.owner);
6222
+ logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${getProperty(elm, 'className')}"`, vnode.owner);
6127
6223
  }
6128
6224
 
6129
6225
  return nodesAreCompatible;
@@ -6170,7 +6266,7 @@ function validateStyleAttr(vnode, elm) {
6170
6266
 
6171
6267
  if (!nodesAreCompatible) {
6172
6268
  // style is used when class is bound to an expr.
6173
- logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
6269
+ logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
6174
6270
  }
6175
6271
 
6176
6272
  return nodesAreCompatible;
@@ -6234,7 +6330,19 @@ function appendVM(vm) {
6234
6330
  rehydrate(vm);
6235
6331
  }
6236
6332
  function hydrateVM(vm) {
6237
- hydrate(vm);
6333
+ if (shared.isTrue(vm.isDirty)) {
6334
+ // manually diffing/patching here.
6335
+ // This routine is:
6336
+ // patchShadowRoot(vm, children);
6337
+ // -> addVnodes.
6338
+ const children = renderComponent(vm);
6339
+ vm.children = children;
6340
+ const vmChildren = vm.renderMode === 0
6341
+ /* Light */
6342
+ ? getChildNodes(vm.elm) : getChildNodes(vm.elm.shadowRoot);
6343
+ hydrateChildren(vmChildren, children, vm);
6344
+ runRenderedCallback(vm);
6345
+ }
6238
6346
  } // just in case the component comes back, with this we guarantee re-rendering it
6239
6347
  // while preventing any attempt to rehydration until after reinsertion.
6240
6348
 
@@ -6384,7 +6492,11 @@ function computeShadowMode(vm) {
6384
6492
  /* Native */
6385
6493
  ;
6386
6494
  } else if (isNativeShadowDefined) {
6387
- if (def.shadowSupportMode === "any"
6495
+ if (features.runtimeFlags.DISABLE_MIXED_SHADOW_MODE) {
6496
+ shadowMode = 1
6497
+ /* Synthetic */
6498
+ ;
6499
+ } else if (def.shadowSupportMode === "any"
6388
6500
  /* Any */
6389
6501
  ) {
6390
6502
  shadowMode = 0
@@ -6462,22 +6574,6 @@ function rehydrate(vm) {
6462
6574
  }
6463
6575
  }
6464
6576
 
6465
- function hydrate(vm) {
6466
- if (shared.isTrue(vm.isDirty)) {
6467
- // manually diffing/patching here.
6468
- // This routine is:
6469
- // patchShadowRoot(vm, children);
6470
- // -> addVnodes.
6471
- const children = renderComponent(vm);
6472
- vm.children = children;
6473
- const vmChildren = vm.renderMode === 0
6474
- /* Light */
6475
- ? vm.elm.childNodes : vm.elm.shadowRoot.childNodes;
6476
- hydrateChildren(vmChildren, children, vm);
6477
- runRenderedCallback(vm);
6478
- }
6479
- }
6480
-
6481
6577
  function patchShadowRoot(vm, newCh) {
6482
6578
  const {
6483
6579
  renderRoot,
@@ -6497,7 +6593,7 @@ function patchShadowRoot(vm, newCh) {
6497
6593
  , vm);
6498
6594
  }, () => {
6499
6595
  // job
6500
- patchChildren(renderRoot, oldCh, newCh);
6596
+ patchChildren(oldCh, newCh, renderRoot);
6501
6597
  }, () => {
6502
6598
  // post
6503
6599
  logOperationEnd(2
@@ -7305,4 +7401,4 @@ exports.swapTemplate = swapTemplate;
7305
7401
  exports.track = track;
7306
7402
  exports.unwrap = unwrap;
7307
7403
  exports.wire = wire;
7308
- /* version: 2.9.0 */
7404
+ /* version: 2.10.0 */