@lwc/engine-core 3.1.3 → 3.2.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.
@@ -20,7 +20,7 @@ export interface LightningElementConstructor {
20
20
  shadowSupportMode?: ShadowSupportMode;
21
21
  stylesheets: TemplateStylesheetFactories;
22
22
  }
23
- type HTMLElementTheGoodParts = Pick<Object, 'toString'> & Pick<HTMLElement, 'accessKey' | 'addEventListener' | 'children' | 'childNodes' | 'classList' | 'dir' | 'dispatchEvent' | 'draggable' | 'firstChild' | 'firstElementChild' | 'getAttribute' | 'getAttributeNS' | 'getBoundingClientRect' | 'getElementsByClassName' | 'getElementsByTagName' | 'hasAttribute' | 'hasAttributeNS' | 'hidden' | 'id' | 'isConnected' | 'lang' | 'lastChild' | 'lastElementChild' | 'ownerDocument' | 'querySelector' | 'querySelectorAll' | 'removeAttribute' | 'removeAttributeNS' | 'removeEventListener' | 'setAttribute' | 'setAttributeNS' | 'spellcheck' | 'tabIndex' | 'tagName' | 'title'>;
23
+ type HTMLElementTheGoodParts = Pick<Object, 'toString'> & Pick<HTMLElement, 'accessKey' | 'addEventListener' | 'attachInternals' | 'children' | 'childNodes' | 'classList' | 'dir' | 'dispatchEvent' | 'draggable' | 'firstChild' | 'firstElementChild' | 'getAttribute' | 'getAttributeNS' | 'getBoundingClientRect' | 'getElementsByClassName' | 'getElementsByTagName' | 'hasAttribute' | 'hasAttributeNS' | 'hidden' | 'id' | 'isConnected' | 'lang' | 'lastChild' | 'lastElementChild' | 'ownerDocument' | 'querySelector' | 'querySelectorAll' | 'removeAttribute' | 'removeAttributeNS' | 'removeEventListener' | 'setAttribute' | 'setAttributeNS' | 'spellcheck' | 'tabIndex' | 'tagName' | 'title'>;
24
24
  type RefNodes = {
25
25
  [name: string]: Element;
26
26
  };
@@ -1,5 +1,5 @@
1
1
  export { getComponentHtmlPrototype } from './def';
2
- export { createVM, connectRootElement, disconnectRootElement, getAssociatedVMIfPresent, } from './vm';
2
+ export { RenderMode, ShadowMode, connectRootElement, createVM, disconnectRootElement, getAssociatedVMIfPresent, computeShadowAndRenderMode, } from './vm';
3
3
  export { createContextProviderWithRegister } from './wiring';
4
4
  export { parseFragment, parseSVGFragment } from './template';
5
5
  export { hydrateRoot } from './hydration';
@@ -44,5 +44,6 @@ export interface RendererAPI {
44
44
  createCustomElement: (tagName: string, upgradeCallback: LifecycleCallback, connectedCallback?: LifecycleCallback, disconnectedCallback?: LifecycleCallback) => E;
45
45
  ownerDocument(elm: E): Document;
46
46
  registerContextConsumer: (element: E, adapterContextToken: string, subscriptionPayload: WireContextSubscriptionPayload) => void;
47
+ attachInternals: (elm: E) => ElementInternals;
47
48
  }
48
49
  export {};
@@ -147,6 +147,10 @@ export declare function createVM<HostNode, HostElement>(elm: HostElement, ctor:
147
147
  tagName: string;
148
148
  hydrated?: boolean;
149
149
  }): VM;
150
+ export declare function computeShadowAndRenderMode(Ctor: LightningElementConstructor, renderer: RendererAPI): {
151
+ renderMode: RenderMode;
152
+ shadowMode: ShadowMode;
153
+ };
150
154
  export declare function associateVM(obj: VMAssociable, vm: VM): void;
151
155
  export declare function getAssociatedVM(obj: VMAssociable): VM;
152
156
  export declare function getAssociatedVMIfPresent(obj: VMAssociable): VM | undefined;
package/dist/index.cjs.js CHANGED
@@ -1458,6 +1458,7 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1458
1458
  logError(`this.${methodOrPropName} should not be called during the construction of the custom element for ${getComponentTag(vm)} because the element is not yet in the DOM or has no children yet.`);
1459
1459
  }
1460
1460
  }
1461
+ const supportsElementInternals = typeof ElementInternals !== 'undefined';
1461
1462
  // @ts-ignore
1462
1463
  LightningElement.prototype = {
1463
1464
  constructor: LightningElement,
@@ -1549,6 +1550,18 @@ LightningElement.prototype = {
1549
1550
  }
1550
1551
  return getBoundingClientRect(elm);
1551
1552
  },
1553
+ attachInternals() {
1554
+ const vm = getAssociatedVM(this);
1555
+ const { elm, renderer: { attachInternals }, } = vm;
1556
+ if (shared.isFalse(supportsElementInternals)) {
1557
+ // Browsers that don't support attachInternals will need to be polyfilled before LWC is loaded.
1558
+ throw new Error('attachInternals API is not supported in this browser environment.');
1559
+ }
1560
+ if (vm.renderMode === 0 /* RenderMode.Light */ || vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1561
+ throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
1562
+ }
1563
+ return attachInternals(elm);
1564
+ },
1552
1565
  get isConnected() {
1553
1566
  const vm = getAssociatedVM(this);
1554
1567
  const { elm, renderer: { isConnected }, } = vm;
@@ -2590,6 +2603,14 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2590
2603
  descriptors.attributeChangedCallback = {
2591
2604
  value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
2592
2605
  };
2606
+ // To avoid leaking private component details, accessing internals from outside a component is not allowed.
2607
+ descriptors.attachInternals = {
2608
+ get() {
2609
+ if (process.env.NODE_ENV !== 'production') {
2610
+ logError('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
2611
+ }
2612
+ },
2613
+ };
2593
2614
  // Specify attributes for which we want to reflect changes back to their corresponding
2594
2615
  // properties via attributeChangedCallback.
2595
2616
  shared.defineProperty(HTMLBridgeElement, 'observedAttributes', {
@@ -5415,8 +5436,8 @@ function removeVM(vm) {
5415
5436
  }
5416
5437
  resetComponentStateWhenRemoved(vm);
5417
5438
  }
5418
- function getNearestShadowAncestor(vm) {
5419
- let ancestor = vm.owner;
5439
+ function getNearestShadowAncestor(owner) {
5440
+ let ancestor = owner;
5420
5441
  while (!shared.isNull(ancestor) && ancestor.renderMode === 0 /* RenderMode.Light */) {
5421
5442
  ancestor = ancestor.owner;
5422
5443
  }
@@ -5472,15 +5493,12 @@ function createVM(elm, ctor, renderer, options) {
5472
5493
  vm.debugInfo = shared.create(null);
5473
5494
  }
5474
5495
  vm.stylesheets = computeStylesheets(vm, def.ctor);
5475
- vm.shadowMode = computeShadowMode(vm, renderer);
5496
+ vm.shadowMode = computeShadowMode(def, vm.owner, renderer);
5476
5497
  vm.tro = getTemplateReactiveObserver(vm);
5477
5498
  if (process.env.NODE_ENV !== 'production') {
5478
5499
  vm.toString = () => {
5479
5500
  return `[object:vm ${def.name} (${vm.idx})]`;
5480
5501
  };
5481
- if (lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5482
- vm.shadowMode = 0 /* ShadowMode.Native */;
5483
- }
5484
5502
  }
5485
5503
  // Create component instance associated to the vm and the element.
5486
5504
  invokeComponentConstructor(vm, def.ctor);
@@ -5543,8 +5561,21 @@ function warnOnStylesheetsMutation(ctor) {
5543
5561
  });
5544
5562
  }
5545
5563
  }
5546
- function computeShadowMode(vm, renderer) {
5547
- const { def } = vm;
5564
+ // Compute the shadowMode/renderMode without creating a VM. This is used in some scenarios like hydration.
5565
+ function computeShadowAndRenderMode(Ctor, renderer) {
5566
+ const def = getComponentInternalDef(Ctor);
5567
+ const { renderMode } = def;
5568
+ // Assume null `owner` - this is what happens in hydration cases anyway
5569
+ const shadowMode = computeShadowMode(def, /* owner */ null, renderer);
5570
+ return { renderMode, shadowMode };
5571
+ }
5572
+ function computeShadowMode(def, owner, renderer) {
5573
+ // Force the shadow mode to always be native. Used for running tests with synthetic shadow patches
5574
+ // on, but components running in actual native shadow mode
5575
+ if (process.env.NODE_ENV !== 'production' &&
5576
+ lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5577
+ return 0 /* ShadowMode.Native */;
5578
+ }
5548
5579
  const { isSyntheticShadowDefined } = renderer;
5549
5580
  let shadowMode;
5550
5581
  if (isSyntheticShadowDefined) {
@@ -5558,7 +5589,7 @@ function computeShadowMode(vm, renderer) {
5558
5589
  shadowMode = 0 /* ShadowMode.Native */;
5559
5590
  }
5560
5591
  else {
5561
- const shadowAncestor = getNearestShadowAncestor(vm);
5592
+ const shadowAncestor = getNearestShadowAncestor(owner);
5562
5593
  if (!shared.isNull(shadowAncestor) && shadowAncestor.shadowMode === 0 /* ShadowMode.Native */) {
5563
5594
  // Transitive support for native Shadow DOM. A component in native mode
5564
5595
  // transitively opts all of its descendants into native.
@@ -6894,6 +6925,7 @@ exports.LightningElement = LightningElement;
6894
6925
  exports.__unstable__ProfilerControl = profilerControl;
6895
6926
  exports.__unstable__ReportingControl = reportingControl;
6896
6927
  exports.api = api$1;
6928
+ exports.computeShadowAndRenderMode = computeShadowAndRenderMode;
6897
6929
  exports.connectRootElement = connectRootElement;
6898
6930
  exports.createContextProviderWithRegister = createContextProviderWithRegister;
6899
6931
  exports.createVM = createVM;
@@ -6921,5 +6953,5 @@ exports.swapTemplate = swapTemplate;
6921
6953
  exports.track = track;
6922
6954
  exports.unwrap = unwrap;
6923
6955
  exports.wire = wire;
6924
- /** version: 3.1.3 */
6956
+ /** version: 3.2.0 */
6925
6957
  //# sourceMappingURL=index.cjs.js.map