@lwc/engine-core 5.3.0 → 6.0.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.
@@ -1,3 +1,4 @@
1
1
  import { RendererAPI } from '../renderer';
2
- import { VBaseElement } from '../vnodes';
2
+ import { VBaseElement, VStatic } from '../vnodes';
3
3
  export declare function patchAttributes(oldVnode: VBaseElement | null, vnode: VBaseElement, renderer: RendererAPI): void;
4
+ export declare function patchSlotAssignment(oldVnode: VBaseElement | VStatic | null, vnode: VBaseElement | VStatic, renderer: RendererAPI): void;
@@ -42,7 +42,7 @@ export interface RendererAPI {
42
42
  isConnected: (node: N) => boolean;
43
43
  insertStylesheet: (content: string, target?: ShadowRoot) => void;
44
44
  assertInstanceOfHTMLElement: (elm: any, msg: string) => void;
45
- createCustomElement: (tagName: string, upgradeCallback: LifecycleCallback) => E;
45
+ createCustomElement: (tagName: string, upgradeCallback: LifecycleCallback, useNativeLifecycle: boolean) => E;
46
46
  defineCustomElement: (tagName: string) => void;
47
47
  ownerDocument(elm: E): Document;
48
48
  registerContextConsumer: (element: E, adapterContextToken: string, subscriptionPayload: WireContextSubscriptionPayload) => void;
@@ -1,4 +1,3 @@
1
- import { LightningElement } from './base-lightning-element';
2
1
  export declare function unlockDomMutation(): void;
3
2
  export declare function lockDomMutation(): void;
4
3
  export declare function patchElementWithRestrictions(elm: Element, options: {
@@ -8,4 +7,3 @@ export declare function patchElementWithRestrictions(elm: Element, options: {
8
7
  }): void;
9
8
  export declare function patchShadowRootWithRestrictions(sr: ShadowRoot): void;
10
9
  export declare function patchCustomElementWithRestrictions(elm: HTMLElement): void;
11
- export declare function patchLightningElementPrototypeWithRestrictions(proto: typeof LightningElement.prototype): void;
@@ -1,10 +1,12 @@
1
1
  import { StylesheetFactory, TemplateStylesheetFactories } from './stylesheet';
2
+ import { LightningElementConstructor } from './base-lightning-element';
2
3
  type Callback = () => void;
3
4
  export declare const SPACE_CHAR = 32;
4
5
  export declare const EmptyObject: any;
5
6
  export declare const EmptyArray: never[];
6
7
  export declare function addCallbackToNextTick(callback: Callback): void;
7
8
  export declare function guid(): string;
9
+ export declare function shouldUseNativeCustomElementLifecycle(ctor: LightningElementConstructor): boolean;
8
10
  export declare function parseStyleText(cssText: string): {
9
11
  [name: string]: string;
10
12
  };
@@ -40,6 +40,7 @@ export interface VStatic extends BaseVNode {
40
40
  readonly fragment: Element;
41
41
  readonly parts: VStaticPart[] | undefined;
42
42
  elm: Element | undefined;
43
+ slotAssignment: string | undefined;
43
44
  }
44
45
  export interface VFragment extends BaseVNode, BaseVParent {
45
46
  sel: undefined;
@@ -65,6 +66,7 @@ export interface VBaseElement extends BaseVNode, BaseVParent {
65
66
  data: VElementData;
66
67
  elm: Element | undefined;
67
68
  key: Key;
69
+ slotAssignment: string | undefined;
68
70
  }
69
71
  export interface VElement extends VBaseElement {
70
72
  type: VNodeType.Element;
@@ -93,9 +95,11 @@ export interface VElementData extends VNodeData {
93
95
  readonly external?: boolean;
94
96
  readonly ref?: string;
95
97
  readonly slotData?: any;
98
+ readonly slotAssignment?: string;
96
99
  }
97
100
  export declare function isVBaseElement(vnode: VNode): vnode is VElement | VCustomElement;
98
101
  export declare function isSameVnode(vnode1: VNode, vnode2: VNode): boolean;
99
102
  export declare function isVCustomElement(vnode: VNode | VBaseElement): vnode is VCustomElement;
100
103
  export declare function isVFragment(vnode: VNode): vnode is VFragment;
101
104
  export declare function isVScopedSlotFragment(vnode: VNode): vnode is VScopedSlotFragment;
105
+ export declare function isVStatic(vnode: VNode): vnode is VStatic;
package/dist/index.cjs.js CHANGED
@@ -358,6 +358,14 @@ function guid() {
358
358
  }
359
359
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
360
360
  }
361
+ function shouldUseNativeCustomElementLifecycle(ctor) {
362
+ if (lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
363
+ // temporary "kill switch"
364
+ return false;
365
+ }
366
+ const apiVersion = getComponentAPIVersion(ctor);
367
+ return shared.isAPIFeatureEnabled(7 /* APIFeature.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE */, apiVersion);
368
+ }
361
369
  // Borrowed from Vue template compiler.
362
370
  // https://github.com/vuejs/vue/blob/531371b818b0e31a989a06df43789728f23dc4e8/src/platforms/web/util/style.js#L5-L16
363
371
  const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
@@ -726,28 +734,6 @@ function getCustomElementRestrictionsDescriptors(elm) {
726
734
  }),
727
735
  };
728
736
  }
729
- function getLightningElementPrototypeRestrictionsDescriptors(proto) {
730
- assertNotProd(); // this method should never leak to prod
731
- const originalDispatchEvent = proto.dispatchEvent;
732
- return {
733
- dispatchEvent: generateDataDescriptor({
734
- value(event) {
735
- const vm = getAssociatedVM(this);
736
- if (!shared.isNull(event) && shared.isObject(event)) {
737
- const { type } = event;
738
- if (!/^[a-z][a-z0-9_]*$/.test(type)) {
739
- logError(`Invalid event type "${type}" dispatched in element ${getComponentTag(vm)}.` +
740
- ` Event name must start with a lowercase letter and followed only lowercase` +
741
- ` letters, numbers, and underscores`, vm);
742
- }
743
- }
744
- // Typescript does not like it when you treat the `arguments` object as an array
745
- // @ts-ignore type-mismatch
746
- return originalDispatchEvent.apply(this, arguments);
747
- },
748
- }),
749
- };
750
- }
751
737
  // This routine will prevent access to certain properties on a shadow root instance to guarantee
752
738
  // that all components will work fine in IE11 and other browsers without shadow dom support.
753
739
  function patchShadowRootWithRestrictions(sr) {
@@ -758,9 +744,6 @@ function patchCustomElementWithRestrictions(elm) {
758
744
  const elmProto = shared.getPrototypeOf(elm);
759
745
  shared.setPrototypeOf(elm, shared.create(elmProto, restrictionsDescriptors));
760
746
  }
761
- function patchLightningElementPrototypeWithRestrictions(proto) {
762
- shared.defineProperties(proto, getLightningElementPrototypeRestrictionsDescriptors(proto));
763
- }
764
747
 
765
748
  function updateComponentValue(vm, key, newValue) {
766
749
  const { cmpFields } = vm;
@@ -1944,9 +1927,6 @@ shared.defineProperty(LightningElement, 'CustomElementConstructor', {
1944
1927
  },
1945
1928
  configurable: true,
1946
1929
  });
1947
- if (process.env.NODE_ENV !== 'production') {
1948
- patchLightningElementPrototypeWithRestrictions(LightningElement.prototype);
1949
- }
1950
1930
 
1951
1931
  function createObservedFieldPropertyDescriptor(key) {
1952
1932
  return {
@@ -3595,6 +3575,9 @@ function isVFragment(vnode) {
3595
3575
  function isVScopedSlotFragment(vnode) {
3596
3576
  return vnode.type === 6 /* VNodeType.ScopedSlotFragment */;
3597
3577
  }
3578
+ function isVStatic(vnode) {
3579
+ return vnode.type === 4 /* VNodeType.Static */;
3580
+ }
3598
3581
 
3599
3582
  /*
3600
3583
  * Copyright (c) 2018, salesforce.com, inc.
@@ -3643,6 +3626,20 @@ function patchAttributes(oldVnode, vnode, renderer) {
3643
3626
  }
3644
3627
  }
3645
3628
  }
3629
+ function patchSlotAssignment(oldVnode, vnode, renderer) {
3630
+ const { slotAssignment } = vnode;
3631
+ if ((oldVnode === null || oldVnode === void 0 ? void 0 : oldVnode.slotAssignment) === slotAssignment) {
3632
+ return;
3633
+ }
3634
+ const { elm } = vnode;
3635
+ const { setAttribute, removeAttribute } = renderer;
3636
+ if (shared.isUndefined(slotAssignment) || shared.isNull(slotAssignment)) {
3637
+ removeAttribute(elm, 'slot');
3638
+ }
3639
+ else {
3640
+ setAttribute(elm, 'slot', slotAssignment);
3641
+ }
3642
+ }
3646
3643
 
3647
3644
  /*
3648
3645
  * Copyright (c) 2018, salesforce.com, inc.
@@ -4092,6 +4089,8 @@ function mountElement(vnode, parent, anchor, renderer) {
4092
4089
  }
4093
4090
  function patchStatic(n1, n2, renderer) {
4094
4091
  const elm = (n2.elm = n1.elm);
4092
+ // slotAssignments can only apply to the top level element, never to a static part.
4093
+ patchSlotAssignment(n1, n2, renderer);
4095
4094
  // The `refs` object is blown away in every re-render, so we always need to re-apply them
4096
4095
  applyStaticParts(elm, n2, renderer, false);
4097
4096
  }
@@ -4113,11 +4112,13 @@ function mountStatic(vnode, parent, anchor, renderer) {
4113
4112
  elm[shared.KEY__SHADOW_STATIC] = true;
4114
4113
  }
4115
4114
  }
4115
+ // slotAssignments can only apply to the top level element, never to a static part.
4116
+ patchSlotAssignment(null, vnode, renderer);
4116
4117
  insertNode(elm, parent, anchor, renderer);
4117
4118
  applyStaticParts(elm, vnode, renderer, true);
4118
4119
  }
4119
4120
  function mountCustomElement(vnode, parent, anchor, renderer) {
4120
- const { sel, owner } = vnode;
4121
+ const { sel, owner, ctor } = vnode;
4121
4122
  const { createCustomElement } = renderer;
4122
4123
  /**
4123
4124
  * Note: if the upgradable constructor does not expect, or throw when we new it
@@ -4135,7 +4136,8 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
4135
4136
  // compiler may generate tagnames with uppercase letters so - for backwards
4136
4137
  // compatibility, we lower case the tagname here.
4137
4138
  const normalizedTagname = sel.toLowerCase();
4138
- const elm = createCustomElement(normalizedTagname, upgradeCallback);
4139
+ const useNativeLifecycle = shouldUseNativeCustomElementLifecycle(ctor);
4140
+ const elm = createCustomElement(normalizedTagname, upgradeCallback, useNativeLifecycle);
4139
4141
  vnode.elm = elm;
4140
4142
  vnode.vm = vm;
4141
4143
  linkNodeToShadow(elm, owner, renderer);
@@ -4147,7 +4149,7 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
4147
4149
  insertNode(elm, parent, anchor, renderer);
4148
4150
  if (vm) {
4149
4151
  if (process.env.IS_BROWSER) {
4150
- if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
4152
+ if (!useNativeLifecycle) {
4151
4153
  if (process.env.NODE_ENV !== 'production') {
4152
4154
  // With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
4153
4155
  // noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
@@ -4338,6 +4340,7 @@ function patchElementPropsAndAttrsAndRefs$1(oldVnode, vnode, renderer) {
4338
4340
  patchStyleAttribute(oldVnode, vnode, renderer);
4339
4341
  patchAttributes(oldVnode, vnode, renderer);
4340
4342
  patchProps(oldVnode, vnode, renderer);
4343
+ patchSlotAssignment(oldVnode, vnode, renderer);
4341
4344
  // The `refs` object is blown away in every re-render, so we always need to re-apply them
4342
4345
  applyRefs(vnode, vnode.owner);
4343
4346
  }
@@ -4491,7 +4494,7 @@ function createViewModelHook(elm, vnode, renderer) {
4491
4494
  return vm;
4492
4495
  }
4493
4496
  function allocateInSlot(vm, children, owner) {
4494
- var _a, _b;
4497
+ var _a;
4495
4498
  const { cmpSlots: { slotAssignments: oldSlotsMapping }, } = vm;
4496
4499
  const cmpSlotsMapping = shared.create(null);
4497
4500
  // Collect all slots into cmpSlotsMapping
@@ -4501,8 +4504,8 @@ function allocateInSlot(vm, children, owner) {
4501
4504
  continue;
4502
4505
  }
4503
4506
  let slotName = '';
4504
- if (isVBaseElement(vnode)) {
4505
- slotName = (_b = (_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : '';
4507
+ if (isVBaseElement(vnode) || isVStatic(vnode)) {
4508
+ slotName = (_a = vnode.slotAssignment) !== null && _a !== void 0 ? _a : '';
4506
4509
  }
4507
4510
  else if (isVScopedSlotFragment(vnode)) {
4508
4511
  slotName = vnode.slotName;
@@ -4772,6 +4775,7 @@ function st(fragment, key, parts) {
4772
4775
  fragment,
4773
4776
  owner,
4774
4777
  parts,
4778
+ slotAssignment: undefined,
4775
4779
  };
4776
4780
  return vnode;
4777
4781
  }
@@ -4816,7 +4820,7 @@ function h(sel, data, children = EmptyArray) {
4816
4820
  }
4817
4821
  });
4818
4822
  }
4819
- const { key } = data;
4823
+ const { key, slotAssignment } = data;
4820
4824
  const vnode = {
4821
4825
  type: 2 /* VNodeType.Element */,
4822
4826
  sel,
@@ -4825,6 +4829,7 @@ function h(sel, data, children = EmptyArray) {
4825
4829
  elm: undefined,
4826
4830
  key,
4827
4831
  owner: vmBeingRendered,
4832
+ slotAssignment,
4828
4833
  };
4829
4834
  return vnode;
4830
4835
  }
@@ -4849,6 +4854,8 @@ function s(slotName, data, children, slotset) {
4849
4854
  shared.assert.isTrue(shared.isObject(data), `s() 2nd argument data must be an object.`);
4850
4855
  shared.assert.isTrue(shared.isArray(children), `h() 3rd argument children must be an array.`);
4851
4856
  }
4857
+ const vmBeingRendered = getVMBeingRendered();
4858
+ const { renderMode, apiVersion } = vmBeingRendered;
4852
4859
  if (!shared.isUndefined(slotset) &&
4853
4860
  !shared.isUndefined(slotset.slotAssignments) &&
4854
4861
  !shared.isUndefined(slotset.slotAssignments[slotName]) &&
@@ -4871,7 +4878,6 @@ function s(slotName, data, children, slotset) {
4871
4878
  }
4872
4879
  // If the passed slot content is factory, evaluate it and add the produced vnodes
4873
4880
  if (assignedNodeIsScopedSlot) {
4874
- const vmBeingRenderedInception = getVMBeingRendered();
4875
4881
  // Evaluate in the scope of the slot content's owner
4876
4882
  // if a slotset is provided, there will always be an owner. The only case where owner is
4877
4883
  // undefined is for root components, but root components cannot accept slotted content
@@ -4885,20 +4891,33 @@ function s(slotName, data, children, slotset) {
4885
4891
  });
4886
4892
  }
4887
4893
  finally {
4888
- setVMBeingRendered(vmBeingRenderedInception);
4894
+ setVMBeingRendered(vmBeingRendered);
4889
4895
  }
4890
4896
  }
4891
4897
  else {
4898
+ // This block is for standard slots (non-scoped slots)
4899
+ let clonedVNode;
4900
+ if (renderMode === 0 /* RenderMode.Light */ &&
4901
+ shared.isAPIFeatureEnabled(6 /* APIFeature.USE_LIGHT_DOM_SLOT_FORWARDING */, apiVersion) &&
4902
+ (isVBaseElement(vnode) || isVStatic(vnode)) &&
4903
+ // We only need to copy the vnodes when the slot assignment changes, copying every time causes issues with
4904
+ // disconnected/connected callback firing.
4905
+ vnode.slotAssignment !== data.slotAssignment) {
4906
+ // When the light DOM slot assignment (slot attribute) changes we can't use the same reference
4907
+ // to the vnode because the current way the diffing algo works, it will replace the original reference
4908
+ // to the host element with a new one. This means the new element will be mounted and immediately unmounted.
4909
+ // Creating a copy of the vnode to preserve a reference to the previous host element.
4910
+ clonedVNode = Object.assign(Object.assign({}, vnode), { slotAssignment: data.slotAssignment });
4911
+ }
4892
4912
  // If the slot content is standard type, the content is static, no additional
4893
4913
  // processing needed on the vnode
4894
- shared.ArrayPush.call(newChildren, vnode);
4914
+ shared.ArrayPush.call(newChildren, clonedVNode !== null && clonedVNode !== void 0 ? clonedVNode : vnode);
4895
4915
  }
4896
4916
  }
4897
4917
  }
4898
4918
  children = newChildren;
4899
4919
  }
4900
- const vmBeingRendered = getVMBeingRendered();
4901
- const { renderMode, shadowMode, apiVersion } = vmBeingRendered;
4920
+ const { shadowMode } = vmBeingRendered;
4902
4921
  if (renderMode === 0 /* RenderMode.Light */) {
4903
4922
  // light DOM slots - backwards-compatible behavior uses flattening, new behavior uses fragments
4904
4923
  if (shared.isAPIFeatureEnabled(2 /* APIFeature.USE_FRAGMENTS_FOR_LIGHT_DOM_SLOTS */, apiVersion)) {
@@ -4940,7 +4959,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
4940
4959
  });
4941
4960
  }
4942
4961
  }
4943
- const { key } = data;
4962
+ const { key, slotAssignment } = data;
4944
4963
  let elm, aChildren, vm;
4945
4964
  const vnode = {
4946
4965
  type: 3 /* VNodeType.CustomElement */,
@@ -4949,6 +4968,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
4949
4968
  children,
4950
4969
  elm,
4951
4970
  key,
4971
+ slotAssignment,
4952
4972
  ctor: Ctor,
4953
4973
  owner: vmBeingRendered,
4954
4974
  mode: 'open', // TODO [#1294]: this should be defined in Ctor
@@ -5798,7 +5818,7 @@ function resetComponentStateWhenRemoved(vm) {
5798
5818
  // old vnode.children is removed from the DOM.
5799
5819
  function removeVM(vm) {
5800
5820
  if (process.env.NODE_ENV !== 'production') {
5801
- if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
5821
+ if (!shouldUseNativeCustomElementLifecycle(vm.component.constructor)) {
5802
5822
  // With native lifecycle, we cannot be certain that connectedCallback was called before a component
5803
5823
  // was removed from the VDOM. If the component is disconnected, then connectedCallback will not fire
5804
5824
  // in native mode, although it will fire in synthetic mode due to appendChild triggering it.
@@ -6126,7 +6146,7 @@ function runConnectedCallback(vm) {
6126
6146
  // This test only makes sense in the browser, with synthetic lifecycle, and when reporting is enabled or
6127
6147
  // we're in dev mode. This is to detect a particular issue with synthetic lifecycle.
6128
6148
  if (process.env.IS_BROWSER &&
6129
- !lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE &&
6149
+ !shouldUseNativeCustomElementLifecycle(vm.component.constructor) &&
6130
6150
  (process.env.NODE_ENV !== 'production' || isReportingEnabled())) {
6131
6151
  if (!vm.renderer.isConnected(vm.elm)) {
6132
6152
  if (process.env.NODE_ENV !== 'production') {
@@ -7430,5 +7450,5 @@ exports.swapTemplate = swapTemplate;
7430
7450
  exports.track = track;
7431
7451
  exports.unwrap = unwrap;
7432
7452
  exports.wire = wire;
7433
- /** version: 5.3.0 */
7453
+ /** version: 6.0.0 */
7434
7454
  //# sourceMappingURL=index.cjs.js.map