@lwc/engine-core 4.0.0-alpha.0 → 4.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.
package/dist/index.cjs.js CHANGED
@@ -6,7 +6,6 @@
6
6
  Object.defineProperty(exports, '__esModule', { value: true });
7
7
 
8
8
  var shared = require('@lwc/shared');
9
- var ariaReflection = require('@lwc/aria-reflection');
10
9
  var features = require('@lwc/features');
11
10
 
12
11
  /*
@@ -392,20 +391,6 @@ function flattenStylesheets(stylesheets) {
392
391
  }
393
392
  return list;
394
393
  }
395
- // Set a ref (lwc:ref) on a VM, from a template API
396
- function setRefVNode(vm, ref, vnode) {
397
- if (process.env.NODE_ENV !== 'production' && shared.isUndefined(vm.refVNodes)) {
398
- throw new Error('refVNodes must be defined when setting a ref');
399
- }
400
- // If this method is called, then vm.refVNodes is set as the template has refs.
401
- // If not, then something went wrong and we threw an error above.
402
- const refVNodes = vm.refVNodes;
403
- // In cases of conflict (two elements with the same ref), prefer, the last one,
404
- // in depth-first traversal order.
405
- if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
406
- refVNodes[ref] = vnode;
407
- }
408
- }
409
394
  // Throw an error if we're running in prod mode. Ensures code is truly removed from prod mode.
410
395
  function assertNotProd() {
411
396
  /* istanbul ignore if */
@@ -433,6 +418,45 @@ var _a, _b;
433
418
  const instrumentDef = (_a = shared.globalThis.__lwc_instrument_cmp_def) !== null && _a !== void 0 ? _a : shared.noop;
434
419
  const instrumentInstance = (_b = shared.globalThis.__lwc_instrument_cmp_instance) !== null && _b !== void 0 ? _b : shared.noop;
435
420
 
421
+ /*
422
+ * Copyright (c) 2023, salesforce.com, inc.
423
+ * All rights reserved.
424
+ * SPDX-License-Identifier: MIT
425
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
426
+ */
427
+ // Apply ARIA string reflection behavior to a prototype.
428
+ // This is deliberately kept separate from @lwc/aria-reflection. @lwc/aria-reflection is a global polyfill that is
429
+ // needed for backwards compatibility in LEX, whereas `applyAriaReflection` is designed to only apply to our own
430
+ // LightningElement/BaseBridgeElement prototypes.
431
+ function applyAriaReflection(prototype) {
432
+ for (const propName of shared.keys(shared.AriaPropNameToAttrNameMap)) {
433
+ const attrName = shared.AriaPropNameToAttrNameMap[propName];
434
+ if (shared.isUndefined(shared.getOwnPropertyDescriptor(prototype, propName))) {
435
+ // Note that we need to call this.{get,set,has,remove}Attribute rather than dereferencing
436
+ // from Element.prototype, because these methods are overridden in LightningElement.
437
+ shared.defineProperty(prototype, propName, {
438
+ get() {
439
+ return this.getAttribute(attrName);
440
+ },
441
+ set(newValue) {
442
+ // TODO [#3284]: there is disagreement between browsers and the spec on how to treat undefined
443
+ // Our historical behavior is to only treat null as removing the attribute
444
+ // See also https://github.com/w3c/aria/issues/1858
445
+ if (shared.isNull(newValue)) {
446
+ this.removeAttribute(attrName);
447
+ }
448
+ else {
449
+ this.setAttribute(attrName, newValue);
450
+ }
451
+ },
452
+ // configurable and enumerable to allow it to be overridden – this mimics Safari's/Chrome's behavior
453
+ configurable: true,
454
+ enumerable: true,
455
+ });
456
+ }
457
+ }
458
+ }
459
+
436
460
  /*
437
461
  * Copyright (c) 2018, salesforce.com, inc.
438
462
  * All rights reserved.
@@ -523,8 +547,8 @@ function lockDomMutation() {
523
547
  assertNotProd(); // this method should never leak to prod
524
548
  isDomMutationAllowed = false;
525
549
  }
526
- function logMissingPortalError(name, type) {
527
- return logError(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
550
+ function logMissingPortalWarn(name, type) {
551
+ return logWarn(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
528
552
  }
529
553
  function patchElementWithRestrictions(elm, options) {
530
554
  assertNotProd(); // this method should never leak to prod
@@ -549,14 +573,14 @@ function patchElementWithRestrictions(elm, options) {
549
573
  shared.assign(descriptors, {
550
574
  appendChild: generateDataDescriptor({
551
575
  value(aChild) {
552
- logMissingPortalError('appendChild', 'method');
576
+ logMissingPortalWarn('appendChild', 'method');
553
577
  return appendChild.call(this, aChild);
554
578
  },
555
579
  }),
556
580
  insertBefore: generateDataDescriptor({
557
581
  value(newNode, referenceNode) {
558
582
  if (!isDomMutationAllowed) {
559
- logMissingPortalError('insertBefore', 'method');
583
+ logMissingPortalWarn('insertBefore', 'method');
560
584
  }
561
585
  return insertBefore.call(this, newNode, referenceNode);
562
586
  },
@@ -564,14 +588,14 @@ function patchElementWithRestrictions(elm, options) {
564
588
  removeChild: generateDataDescriptor({
565
589
  value(aChild) {
566
590
  if (!isDomMutationAllowed) {
567
- logMissingPortalError('removeChild', 'method');
591
+ logMissingPortalWarn('removeChild', 'method');
568
592
  }
569
593
  return removeChild.call(this, aChild);
570
594
  },
571
595
  }),
572
596
  replaceChild: generateDataDescriptor({
573
597
  value(newChild, oldChild) {
574
- logMissingPortalError('replaceChild', 'method');
598
+ logMissingPortalWarn('replaceChild', 'method');
575
599
  return replaceChild.call(this, newChild, oldChild);
576
600
  },
577
601
  }),
@@ -581,7 +605,7 @@ function patchElementWithRestrictions(elm, options) {
581
605
  },
582
606
  set(value) {
583
607
  if (!isDomMutationAllowed) {
584
- logMissingPortalError('nodeValue', 'property');
608
+ logMissingPortalWarn('nodeValue', 'property');
585
609
  }
586
610
  originalNodeValueDescriptor.set.call(this, value);
587
611
  },
@@ -591,7 +615,7 @@ function patchElementWithRestrictions(elm, options) {
591
615
  return originalTextContentDescriptor.get.call(this);
592
616
  },
593
617
  set(value) {
594
- logMissingPortalError('textContent', 'property');
618
+ logMissingPortalWarn('textContent', 'property');
595
619
  originalTextContentDescriptor.set.call(this, value);
596
620
  },
597
621
  }),
@@ -600,7 +624,7 @@ function patchElementWithRestrictions(elm, options) {
600
624
  return originalInnerHTMLDescriptor.get.call(this);
601
625
  },
602
626
  set(value) {
603
- logMissingPortalError('innerHTML', 'property');
627
+ logMissingPortalWarn('innerHTML', 'property');
604
628
  return originalInnerHTMLDescriptor.set.call(this, value);
605
629
  },
606
630
  }),
@@ -1458,6 +1482,79 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1458
1482
  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
1483
  }
1460
1484
  }
1485
+ // List of properties on ElementInternals that are formAssociated can be found in the spec:
1486
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements
1487
+ const formAssociatedProps = new Set([
1488
+ 'setFormValue',
1489
+ 'form',
1490
+ 'setValidity',
1491
+ 'willValidate',
1492
+ 'validity',
1493
+ 'validationMessage',
1494
+ 'checkValidity',
1495
+ 'reportValidity',
1496
+ 'labels',
1497
+ ]);
1498
+ // Verify that access to a form-associated property of the ElementInternals proxy has formAssociated set in the LWC.
1499
+ function verifyPropForFormAssociation(propertyKey, isFormAssociated) {
1500
+ if (shared.isString(propertyKey) && formAssociatedProps.has(propertyKey) && !isFormAssociated) {
1501
+ //Note this error message mirrors Chrome and Firefox error messages, in Safari the error is slightly different.
1502
+ throw new DOMException(`Failed to execute '${propertyKey}' on 'ElementInternals': The target element is not a form-associated custom element.`);
1503
+ }
1504
+ }
1505
+ const elementInternalsAccessorAllowList = new Set(['shadowRoot', 'role', ...formAssociatedProps]);
1506
+ // Prevent access to properties not defined in the HTML spec in case browsers decide to
1507
+ // provide new APIs that provide access to form associated properties.
1508
+ // This can be removed along with UpgradeableConstructor.
1509
+ function isAllowedElementInternalAccessor(propertyKey) {
1510
+ let isAllowedAccessor = false;
1511
+ // As of this writing all ElementInternal property keys as described in the spec are implemented with strings
1512
+ // in Chrome, Firefox, and Safari
1513
+ if (shared.isString(propertyKey)) {
1514
+ // Allow list is based on HTML spec:
1515
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#the-elementinternals-interface
1516
+ isAllowedAccessor =
1517
+ elementInternalsAccessorAllowList.has(propertyKey) || /^aria/.test(propertyKey);
1518
+ if (!isAllowedAccessor && process.env.NODE_ENV !== 'production') {
1519
+ logWarn('Only properties defined in the ElementInternals HTML spec are available.');
1520
+ }
1521
+ }
1522
+ return isAllowedAccessor;
1523
+ }
1524
+ // Wrap all ElementInternal objects in a proxy to prevent form association when `formAssociated` is not set on an LWC.
1525
+ // This is needed because the 1UpgradeableConstructor1 always sets `formAssociated=true`, which means all
1526
+ // ElementInternal objects will have form-associated properties set when an LWC is placed in a form.
1527
+ // We are doing this to guard against customers taking a dependency on form elements being associated to ElementInternals
1528
+ // when 'formAssociated' has not been set on the LWC.
1529
+ function createElementInternalsProxy(elementInternals, isFormAssociated) {
1530
+ const elementInternalsProxy = new Proxy(elementInternals, {
1531
+ set(target, propertyKey, newValue) {
1532
+ if (isAllowedElementInternalAccessor(propertyKey)) {
1533
+ // Verify that formAssociated is set for form associated properties
1534
+ verifyPropForFormAssociation(propertyKey, isFormAssociated);
1535
+ return Reflect.set(target, propertyKey, newValue);
1536
+ }
1537
+ // As of this writing ElementInternals do not have non-string properties that can be set.
1538
+ return false;
1539
+ },
1540
+ get(target, propertyKey) {
1541
+ if (
1542
+ // Pass through Object.prototype methods such as toString()
1543
+ shared.hasOwnProperty.call(Object.prototype, propertyKey) ||
1544
+ // As of this writing, ElementInternals only uses Symbol.toStringTag which is called
1545
+ // on Object.hasOwnProperty invocations
1546
+ Symbol.for('Symbol.toStringTag') === propertyKey ||
1547
+ // ElementInternals allow listed properties
1548
+ isAllowedElementInternalAccessor(propertyKey)) {
1549
+ // Verify that formAssociated is set for form associated properties
1550
+ verifyPropForFormAssociation(propertyKey, isFormAssociated);
1551
+ const propertyValue = Reflect.get(target, propertyKey);
1552
+ return shared.isFunction(propertyValue) ? propertyValue.bind(target) : propertyValue;
1553
+ }
1554
+ },
1555
+ });
1556
+ return elementInternalsProxy;
1557
+ }
1461
1558
  // @ts-ignore
1462
1559
  LightningElement.prototype = {
1463
1560
  constructor: LightningElement,
@@ -1549,6 +1646,16 @@ LightningElement.prototype = {
1549
1646
  }
1550
1647
  return getBoundingClientRect(elm);
1551
1648
  },
1649
+ attachInternals() {
1650
+ const vm = getAssociatedVM(this);
1651
+ const { elm, def: { formAssociated }, renderer: { attachInternals }, } = vm;
1652
+ if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1653
+ throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
1654
+ }
1655
+ const internals = attachInternals(elm);
1656
+ // #TODO[2970]: remove proxy once `UpgradeableConstructor` has been removed
1657
+ return createElementInternalsProxy(internals, Boolean(formAssociated));
1658
+ },
1552
1659
  get isConnected() {
1553
1660
  const vm = getAssociatedVM(this);
1554
1661
  const { elm, renderer: { isConnected }, } = vm;
@@ -1737,7 +1844,7 @@ shared.defineProperties(LightningElement.prototype, lightningBasedDescriptors);
1737
1844
  // Apply ARIA reflection to LightningElement.prototype, on both the browser and server.
1738
1845
  // This allows `this.aria*` property accessors to work from inside a component, and to reflect `aria-*` attrs.
1739
1846
  // Note this works regardless of whether the global ARIA reflection polyfill is applied or not.
1740
- ariaReflection.applyAriaReflection(LightningElement.prototype);
1847
+ applyAriaReflection(LightningElement.prototype);
1741
1848
  shared.defineProperty(LightningElement, 'CustomElementConstructor', {
1742
1849
  get() {
1743
1850
  // If required, a runtime-specific implementation must be defined.
@@ -2549,7 +2656,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
2549
2656
  this[propName] = newValue;
2550
2657
  };
2551
2658
  }
2552
- function HTMLBridgeElementFactory(SuperClass, props, methods) {
2659
+ function createAccessorThatWarns(propName) {
2660
+ let prop;
2661
+ return {
2662
+ get() {
2663
+ logWarn(`The property "${propName}" is not publicly accessible. Add the @api annotation to the property declaration or getter/setter in the component to make it accessible.`);
2664
+ return prop;
2665
+ },
2666
+ set(value) {
2667
+ logWarn(`The property "${propName}" is not publicly accessible. Add the @api annotation to the property declaration or getter/setter in the component to make it accessible.`);
2668
+ prop = value;
2669
+ },
2670
+ enumerable: true,
2671
+ configurable: true,
2672
+ };
2673
+ }
2674
+ function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto, hasCustomSuperClass) {
2553
2675
  const HTMLBridgeElement = class extends SuperClass {
2554
2676
  };
2555
2677
  // generating the hash table for attributes to avoid duplicate fields and facilitate validation
@@ -2558,9 +2680,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2558
2680
  const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
2559
2681
  const { observedAttributes: superObservedAttributes = [] } = SuperClass;
2560
2682
  const descriptors = shared.create(null);
2683
+ // present a hint message so that developers are aware that they have not decorated property with @api
2684
+ if (process.env.NODE_ENV !== 'production') {
2685
+ // TODO [#3761]: enable for components that don't extend from LightningElement
2686
+ if (!shared.isUndefined(proto) && !shared.isNull(proto) && !hasCustomSuperClass) {
2687
+ const nonPublicPropertiesToWarnOn = new Set([
2688
+ // getters, setters, and methods
2689
+ ...shared.keys(shared.getOwnPropertyDescriptors(proto)),
2690
+ // class properties
2691
+ ...observedFields,
2692
+ ]
2693
+ // we don't want to override HTMLElement props because these are meaningful in other ways,
2694
+ // and can break tooling that expects it to be iterable or defined, e.g. Jest:
2695
+ // https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
2696
+ // It also doesn't make sense to override e.g. "constructor".
2697
+ .filter((propName) => !(propName in HTMLElementPrototype)));
2698
+ for (const propName of nonPublicPropertiesToWarnOn) {
2699
+ if (shared.ArrayIndexOf.call(publicProperties, propName) === -1) {
2700
+ descriptors[propName] = createAccessorThatWarns(propName);
2701
+ }
2702
+ }
2703
+ }
2704
+ }
2561
2705
  // expose getters and setters for each public props on the new Element Bridge
2562
- for (let i = 0, len = props.length; i < len; i += 1) {
2563
- const propName = props[i];
2706
+ for (let i = 0, len = publicProperties.length; i < len; i += 1) {
2707
+ const propName = publicProperties[i];
2564
2708
  attributeToPropMap[shared.htmlPropertyToAttribute(propName)] = propName;
2565
2709
  descriptors[propName] = {
2566
2710
  get: createGetter(propName),
@@ -2585,6 +2729,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2585
2729
  descriptors.attributeChangedCallback = {
2586
2730
  value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
2587
2731
  };
2732
+ // To avoid leaking private component details, accessing internals from outside a component is not allowed.
2733
+ descriptors.attachInternals = {
2734
+ set() {
2735
+ if (process.env.NODE_ENV !== 'production') {
2736
+ logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
2737
+ }
2738
+ },
2739
+ get() {
2740
+ if (process.env.NODE_ENV !== 'production') {
2741
+ logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
2742
+ }
2743
+ },
2744
+ };
2745
+ descriptors.formAssociated = {
2746
+ set() {
2747
+ if (process.env.NODE_ENV !== 'production') {
2748
+ logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
2749
+ }
2750
+ },
2751
+ get() {
2752
+ if (process.env.NODE_ENV !== 'production') {
2753
+ logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
2754
+ }
2755
+ },
2756
+ };
2588
2757
  // Specify attributes for which we want to reflect changes back to their corresponding
2589
2758
  // properties via attributeChangedCallback.
2590
2759
  shared.defineProperty(HTMLBridgeElement, 'observedAttributes', {
@@ -2595,7 +2764,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2595
2764
  shared.defineProperties(HTMLBridgeElement.prototype, descriptors);
2596
2765
  return HTMLBridgeElement;
2597
2766
  }
2598
- const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), []);
2767
+ const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, shared.getOwnPropertyNames(HTMLElementOriginalDescriptors), [], [], null, false);
2599
2768
  if (process.env.IS_BROWSER) {
2600
2769
  // This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
2601
2770
  // so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
@@ -2608,7 +2777,7 @@ if (process.env.IS_BROWSER) {
2608
2777
  //
2609
2778
  // Also note that we apply this to BaseBridgeElement.prototype to avoid excessively redefining property
2610
2779
  // accessors inside the HTMLBridgeElementFactory.
2611
- ariaReflection.applyAriaReflection(BaseBridgeElement.prototype);
2780
+ applyAriaReflection(BaseBridgeElement.prototype);
2612
2781
  }
2613
2782
  shared.freeze(BaseBridgeElement);
2614
2783
  shared.seal(BaseBridgeElement.prototype);
@@ -2893,7 +3062,7 @@ function getCtorProto(Ctor) {
2893
3062
  return proto;
2894
3063
  }
2895
3064
  function createComponentDef(Ctor) {
2896
- const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode } = Ctor;
3065
+ const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
2897
3066
  if (process.env.NODE_ENV !== 'production') {
2898
3067
  const ctorName = Ctor.name;
2899
3068
  // Removing the following assert until https://bugs.webkit.org/show_bug.cgi?id=190140 is fixed.
@@ -2905,7 +3074,8 @@ function createComponentDef(Ctor) {
2905
3074
  }
2906
3075
  if (!shared.isUndefined(ctorShadowSupportMode) &&
2907
3076
  ctorShadowSupportMode !== "any" /* ShadowSupportMode.Any */ &&
2908
- ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */) {
3077
+ ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */ &&
3078
+ ctorShadowSupportMode !== "native" /* ShadowSupportMode.Native */) {
2909
3079
  logError(`Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
2910
3080
  }
2911
3081
  if (!shared.isUndefined(ctorRenderMode) &&
@@ -2917,10 +3087,11 @@ function createComponentDef(Ctor) {
2917
3087
  const decoratorsMeta = getDecoratorsMeta(Ctor);
2918
3088
  const { apiFields, apiFieldsConfig, apiMethods, wiredFields, wiredMethods, observedFields } = decoratorsMeta;
2919
3089
  const proto = Ctor.prototype;
2920
- let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
3090
+ let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, formAssociatedCallback, formResetCallback, formDisabledCallback, formStateRestoreCallback, render, } = proto;
2921
3091
  const superProto = getCtorProto(Ctor);
2922
- const superDef = superProto !== LightningElement ? getComponentInternalDef(superProto) : lightingElementDef;
2923
- const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods));
3092
+ const hasCustomSuperClass = superProto !== LightningElement;
3093
+ const superDef = hasCustomSuperClass ? getComponentInternalDef(superProto) : lightingElementDef;
3094
+ const bridge = HTMLBridgeElementFactory(superDef.bridge, shared.keys(apiFields), shared.keys(apiMethods), shared.keys(observedFields), proto, hasCustomSuperClass);
2924
3095
  const props = shared.assign(shared.create(null), superDef.props, apiFields);
2925
3096
  const propsConfig = shared.assign(shared.create(null), superDef.propsConfig, apiFieldsConfig);
2926
3097
  const methods = shared.assign(shared.create(null), superDef.methods, apiMethods);
@@ -2929,6 +3100,10 @@ function createComponentDef(Ctor) {
2929
3100
  disconnectedCallback = disconnectedCallback || superDef.disconnectedCallback;
2930
3101
  renderedCallback = renderedCallback || superDef.renderedCallback;
2931
3102
  errorCallback = errorCallback || superDef.errorCallback;
3103
+ formAssociatedCallback = formAssociatedCallback || superDef.formAssociatedCallback;
3104
+ formResetCallback = formResetCallback || superDef.formResetCallback;
3105
+ formDisabledCallback = formDisabledCallback || superDef.formDisabledCallback;
3106
+ formStateRestoreCallback = formStateRestoreCallback || superDef.formStateRestoreCallback;
2932
3107
  render = render || superDef.render;
2933
3108
  let shadowSupportMode = superDef.shadowSupportMode;
2934
3109
  if (!shared.isUndefined(ctorShadowSupportMode)) {
@@ -2938,6 +3113,10 @@ function createComponentDef(Ctor) {
2938
3113
  if (!shared.isUndefined(ctorRenderMode)) {
2939
3114
  renderMode = ctorRenderMode === 'light' ? 0 /* RenderMode.Light */ : 1 /* RenderMode.Shadow */;
2940
3115
  }
3116
+ let formAssociated = superDef.formAssociated;
3117
+ if (!shared.isUndefined(ctorFormAssociated)) {
3118
+ formAssociated = ctorFormAssociated;
3119
+ }
2941
3120
  const template = getComponentRegisteredTemplate(Ctor) || superDef.template;
2942
3121
  const name = Ctor.name || superDef.name;
2943
3122
  // installing observed fields into the prototype.
@@ -2953,10 +3132,15 @@ function createComponentDef(Ctor) {
2953
3132
  template,
2954
3133
  renderMode,
2955
3134
  shadowSupportMode,
3135
+ formAssociated,
2956
3136
  connectedCallback,
2957
3137
  disconnectedCallback,
2958
- renderedCallback,
2959
3138
  errorCallback,
3139
+ formAssociatedCallback,
3140
+ formDisabledCallback,
3141
+ formResetCallback,
3142
+ formStateRestoreCallback,
3143
+ renderedCallback,
2960
3144
  render,
2961
3145
  };
2962
3146
  // This is a no-op unless Lightning DevTools are enabled.
@@ -3033,6 +3217,7 @@ const lightingElementDef = {
3033
3217
  methods: EmptyObject,
3034
3218
  renderMode: 1 /* RenderMode.Shadow */,
3035
3219
  shadowSupportMode: "reset" /* ShadowSupportMode.Default */,
3220
+ formAssociated: undefined,
3036
3221
  wire: EmptyObject,
3037
3222
  bridge: BaseBridgeElement,
3038
3223
  template: defaultEmptyTemplate,
@@ -3089,9 +3274,11 @@ function createInlineStyleVNode(content) {
3089
3274
  },
3090
3275
  }, [api.t(content)]);
3091
3276
  }
3092
- function updateStylesheetToken(vm, template) {
3277
+ // TODO [#3733]: remove support for legacy scope tokens
3278
+ function updateStylesheetToken(vm, template, legacy) {
3093
3279
  const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
3094
- const { stylesheets: newStylesheets, stylesheetToken: newStylesheetToken } = template;
3280
+ const { stylesheets: newStylesheets } = template;
3281
+ const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
3095
3282
  const { stylesheets: newVmStylesheets } = vm;
3096
3283
  const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
3097
3284
  const { hasScopedStyles } = context;
@@ -3099,7 +3286,19 @@ function updateStylesheetToken(vm, template) {
3099
3286
  let newHasTokenInClass;
3100
3287
  let newHasTokenInAttribute;
3101
3288
  // Reset the styling token applied to the host element.
3102
- const { stylesheetToken: oldToken, hasTokenInClass: oldHasTokenInClass, hasTokenInAttribute: oldHasTokenInAttribute, } = context;
3289
+ let oldToken;
3290
+ let oldHasTokenInClass;
3291
+ let oldHasTokenInAttribute;
3292
+ if (legacy) {
3293
+ oldToken = context.legacyStylesheetToken;
3294
+ oldHasTokenInClass = context.hasLegacyTokenInClass;
3295
+ oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
3296
+ }
3297
+ else {
3298
+ oldToken = context.stylesheetToken;
3299
+ oldHasTokenInClass = context.hasTokenInClass;
3300
+ oldHasTokenInAttribute = context.hasTokenInAttribute;
3301
+ }
3103
3302
  if (!shared.isUndefined(oldToken)) {
3104
3303
  if (oldHasTokenInClass) {
3105
3304
  getClassList(elm).remove(makeHostToken(oldToken));
@@ -3127,9 +3326,16 @@ function updateStylesheetToken(vm, template) {
3127
3326
  }
3128
3327
  }
3129
3328
  // Update the styling tokens present on the context object.
3130
- context.stylesheetToken = newToken;
3131
- context.hasTokenInClass = newHasTokenInClass;
3132
- context.hasTokenInAttribute = newHasTokenInAttribute;
3329
+ if (legacy) {
3330
+ context.legacyStylesheetToken = newToken;
3331
+ context.hasLegacyTokenInClass = newHasTokenInClass;
3332
+ context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
3333
+ }
3334
+ else {
3335
+ context.stylesheetToken = newToken;
3336
+ context.hasTokenInClass = newHasTokenInClass;
3337
+ context.hasTokenInAttribute = newHasTokenInAttribute;
3338
+ }
3133
3339
  }
3134
3340
  function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
3135
3341
  const content = [];
@@ -3217,9 +3423,12 @@ function getNearestShadowComponent(vm) {
3217
3423
  * this returns the unique token for that scoped stylesheet. Otherwise
3218
3424
  * it returns null.
3219
3425
  */
3220
- function getScopeTokenClass(owner) {
3426
+ // TODO [#3733]: remove support for legacy scope tokens
3427
+ function getScopeTokenClass(owner, legacy) {
3221
3428
  const { cmpTemplate, context } = owner;
3222
- return (context.hasScopedStyles && (cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) || null;
3429
+ return ((context.hasScopedStyles &&
3430
+ (legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
3431
+ null);
3223
3432
  }
3224
3433
  /**
3225
3434
  * This function returns the host style token for a custom element if it
@@ -3353,28 +3562,20 @@ function isLiveBindingProp(sel, key) {
3353
3562
  return sel === 'input' && (key === 'value' || key === 'checked');
3354
3563
  }
3355
3564
  function patchProps(oldVnode, vnode, renderer) {
3356
- let { props } = vnode.data;
3357
- const { spread } = vnode.data;
3358
- if (shared.isUndefined(props) && shared.isUndefined(spread)) {
3565
+ const { props } = vnode.data;
3566
+ if (shared.isUndefined(props)) {
3359
3567
  return;
3360
3568
  }
3361
3569
  let oldProps;
3362
3570
  if (!shared.isNull(oldVnode)) {
3363
3571
  oldProps = oldVnode.data.props;
3364
- const oldSpread = oldVnode.data.spread;
3365
3572
  // Props may be the same due to the static content optimization, so we can skip diffing
3366
- if (oldProps === props && oldSpread === spread) {
3573
+ if (oldProps === props) {
3367
3574
  return;
3368
3575
  }
3369
3576
  if (shared.isUndefined(oldProps)) {
3370
3577
  oldProps = EmptyObject;
3371
3578
  }
3372
- if (!shared.isUndefined(oldSpread)) {
3373
- oldProps = shared.assign({}, oldProps, oldSpread);
3374
- }
3375
- }
3376
- if (!shared.isUndefined(spread)) {
3377
- props = shared.assign({}, props, spread);
3378
3579
  }
3379
3580
  const isFirstPatch = shared.isNull(oldVnode);
3380
3581
  const { elm, sel } = vnode;
@@ -3548,6 +3749,113 @@ function applyStaticStyleAttribute(vnode, renderer) {
3548
3749
  }
3549
3750
  }
3550
3751
 
3752
+ /*
3753
+ * Copyright (c) 2023, salesforce.com, inc.
3754
+ * All rights reserved.
3755
+ * SPDX-License-Identifier: MIT
3756
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3757
+ */
3758
+ // Set a ref (lwc:ref) on a VM, from a template API
3759
+ function applyRefs(vnode, owner) {
3760
+ const { data } = vnode;
3761
+ const { ref } = data;
3762
+ if (shared.isUndefined(ref)) {
3763
+ return;
3764
+ }
3765
+ if (process.env.NODE_ENV !== 'production' && shared.isUndefined(owner.refVNodes)) {
3766
+ throw new Error('refVNodes must be defined when setting a ref');
3767
+ }
3768
+ // If this method is called, then vm.refVNodes is set as the template has refs.
3769
+ // If not, then something went wrong and we threw an error above.
3770
+ const refVNodes = owner.refVNodes;
3771
+ // In cases of conflict (two elements with the same ref), prefer the last one,
3772
+ // in depth-first traversal order. This happens automatically due to how we render
3773
+ refVNodes[ref] = vnode;
3774
+ }
3775
+
3776
+ /*
3777
+ * Copyright (c) 2023, salesforce.com, inc.
3778
+ * All rights reserved.
3779
+ * SPDX-License-Identifier: MIT
3780
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3781
+ */
3782
+ function traverseAndSetElements(root, parts, renderer) {
3783
+ const numParts = parts.length;
3784
+ // Optimization given that, in most cases, there will be one part, and it's just the root
3785
+ if (numParts === 1) {
3786
+ const firstPart = parts[0];
3787
+ if (firstPart.partId === 0) {
3788
+ // 0 means the root node
3789
+ firstPart.elm = root;
3790
+ return;
3791
+ }
3792
+ }
3793
+ const partIdsToParts = new Map();
3794
+ for (const staticPart of parts) {
3795
+ partIdsToParts.set(staticPart.partId, staticPart);
3796
+ }
3797
+ let numFoundParts = 0;
3798
+ const { previousSibling, getLastChild } = renderer;
3799
+ const stack = [root];
3800
+ let partId = -1;
3801
+ // Depth-first traversal. We assign a partId to each element, which is an integer based on traversal order.
3802
+ while (stack.length > 0) {
3803
+ const elm = shared.ArrayShift.call(stack);
3804
+ partId++;
3805
+ const part = partIdsToParts.get(partId);
3806
+ if (!shared.isUndefined(part)) {
3807
+ part.elm = elm;
3808
+ if (++numFoundParts === numParts) {
3809
+ return; // perf optimization - stop traversing once we've found everything we need
3810
+ }
3811
+ }
3812
+ // For depth-first traversal, prepend to the stack in reverse order
3813
+ // Note that we traverse using `*Child`/`*Sibling` rather than `children` because the browser uses a linked
3814
+ // list under the hood to represent the DOM tree, so it's faster to do this than to create an underlying array
3815
+ // by calling `children`.
3816
+ let child = getLastChild(elm);
3817
+ while (!shared.isNull(child)) {
3818
+ shared.ArrayUnshift.call(stack, child);
3819
+ child = previousSibling(child);
3820
+ }
3821
+ }
3822
+ if (process.env.NODE_ENV !== 'production') {
3823
+ shared.assert.isTrue(numFoundParts === numParts, `Should have found all parts by now. Found ${numFoundParts}, needed ${numParts}.`);
3824
+ }
3825
+ }
3826
+ /**
3827
+ * Given an array of static parts, do all the mounting required for these parts.
3828
+ *
3829
+ * @param root - the root element
3830
+ * @param vnode - the parent VStatic
3831
+ * @param renderer - the renderer to use
3832
+ * @param mount - true this is a first (mount) render as opposed to a subsequent (patch) render
3833
+ */
3834
+ function applyStaticParts(root, vnode, renderer, mount) {
3835
+ // On the server, we don't support ref (because it relies on renderedCallback), nor do we
3836
+ // support event listeners (no interactivity), so traversing parts makes no sense
3837
+ if (!process.env.IS_BROWSER) {
3838
+ return;
3839
+ }
3840
+ const { parts, owner } = vnode;
3841
+ if (shared.isUndefined(parts)) {
3842
+ return;
3843
+ }
3844
+ // This adds `part.elm` to each `part`. We have to do this on every mount/patch because the `parts`
3845
+ // array is recreated from scratch every time, so each `part.elm` is now undefined.
3846
+ // TODO [#3800]: avoid calling traverseAndSetElements on every re-render
3847
+ traverseAndSetElements(root, parts, renderer);
3848
+ // Currently only event listeners and refs are supported for static vnodes
3849
+ for (const part of parts) {
3850
+ if (mount) {
3851
+ // Event listeners only need to be applied once when mounting
3852
+ applyEventListeners(part, renderer);
3853
+ }
3854
+ // Refs must be updated after every render due to refVNodes getting reset before every render
3855
+ applyRefs(part, owner);
3856
+ }
3857
+ }
3858
+
3551
3859
  /*
3552
3860
  * Copyright (c) 2018, salesforce.com, inc.
3553
3861
  * All rights reserved.
@@ -3590,7 +3898,7 @@ function patch(n1, n2, parent, renderer) {
3590
3898
  patchComment(n1, n2, renderer);
3591
3899
  break;
3592
3900
  case 4 /* VNodeType.Static */:
3593
- n2.elm = n1.elm;
3901
+ patchStatic(n1, n2, renderer);
3594
3902
  break;
3595
3903
  case 5 /* VNodeType.Fragment */:
3596
3904
  patchFragment(n1, n2, parent, renderer);
@@ -3684,13 +3992,18 @@ function mountElement(vnode, parent, anchor, renderer) {
3684
3992
  applyStyleScoping(elm, owner, renderer);
3685
3993
  applyDomManual(elm, vnode);
3686
3994
  applyElementRestrictions(elm, vnode);
3687
- patchElementPropsAndAttrs$1(null, vnode, renderer);
3995
+ patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
3688
3996
  insertNode(elm, parent, anchor, renderer);
3689
3997
  mountVNodes(vnode.children, elm, renderer, null);
3690
3998
  }
3999
+ function patchStatic(n1, n2, renderer) {
4000
+ const elm = (n2.elm = n1.elm);
4001
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
4002
+ applyStaticParts(elm, n2, renderer, false);
4003
+ }
3691
4004
  function patchElement(n1, n2, renderer) {
3692
4005
  const elm = (n2.elm = n1.elm);
3693
- patchElementPropsAndAttrs$1(n1, n2, renderer);
4006
+ patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
3694
4007
  patchChildren(n1.children, n2.children, elm, renderer);
3695
4008
  }
3696
4009
  function mountStatic(vnode, parent, anchor, renderer) {
@@ -3707,8 +4020,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
3707
4020
  }
3708
4021
  }
3709
4022
  insertNode(elm, parent, anchor, renderer);
3710
- // Event listeners are only applied once when mounting, so they are allowed for static vnodes
3711
- applyEventListeners(vnode, renderer);
4023
+ applyStaticParts(elm, vnode, renderer, true);
3712
4024
  }
3713
4025
  function mountCustomElement(vnode, parent, anchor, renderer) {
3714
4026
  const { sel, owner } = vnode;
@@ -3724,22 +4036,38 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3724
4036
  // the custom element from the registry is expecting an upgrade callback
3725
4037
  vm = createViewModelHook(elm, vnode, renderer);
3726
4038
  };
3727
- const connectedCallback = (elm) => {
3728
- if (shouldUseNativeCustomElementLifecycle(vm)) {
4039
+ let connectedCallback;
4040
+ let disconnectedCallback;
4041
+ let formAssociatedCallback;
4042
+ let formDisabledCallback;
4043
+ let formResetCallback;
4044
+ let formStateRestoreCallback;
4045
+ if (lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
4046
+ connectedCallback = (elm) => {
3729
4047
  connectRootElement(elm);
3730
- }
3731
- };
3732
- const disconnectedCallback = (elm) => {
3733
- if (shouldUseNativeCustomElementLifecycle(vm)) {
4048
+ };
4049
+ disconnectedCallback = (elm) => {
3734
4050
  disconnectRootElement(elm);
3735
- }
3736
- };
4051
+ };
4052
+ formAssociatedCallback = (elm) => {
4053
+ runFormAssociatedCallback(elm);
4054
+ };
4055
+ formDisabledCallback = (elm) => {
4056
+ runFormDisabledCallback(elm);
4057
+ };
4058
+ formResetCallback = (elm) => {
4059
+ runFormResetCallback(elm);
4060
+ };
4061
+ formStateRestoreCallback = (elm) => {
4062
+ runFormStateRestoreCallback(elm);
4063
+ };
4064
+ }
3737
4065
  // Should never get a tag with upper case letter at this point; the compiler
3738
4066
  // should produce only tags with lowercase letters. However, the Java
3739
4067
  // compiler may generate tagnames with uppercase letters so - for backwards
3740
4068
  // compatibility, we lower case the tagname here.
3741
4069
  const normalizedTagname = sel.toLowerCase();
3742
- const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback);
4070
+ const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback, formAssociatedCallback, formDisabledCallback, formResetCallback, formStateRestoreCallback);
3743
4071
  vnode.elm = elm;
3744
4072
  vnode.vm = vm;
3745
4073
  linkNodeToShadow(elm, owner, renderer);
@@ -3747,11 +4075,11 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3747
4075
  if (vm) {
3748
4076
  allocateChildren(vnode, vm);
3749
4077
  }
3750
- patchElementPropsAndAttrs$1(null, vnode, renderer);
4078
+ patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
3751
4079
  insertNode(elm, parent, anchor, renderer);
3752
4080
  if (vm) {
3753
4081
  if (process.env.IS_BROWSER) {
3754
- if (!shouldUseNativeCustomElementLifecycle(vm)) {
4082
+ if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3755
4083
  if (process.env.NODE_ENV !== 'production') {
3756
4084
  // With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
3757
4085
  // noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
@@ -3784,7 +4112,7 @@ function patchCustomElement(n1, n2, parent, renderer) {
3784
4112
  // Otherwise patch the existing component with new props/attrs/etc.
3785
4113
  const elm = (n2.elm = n1.elm);
3786
4114
  const vm = (n2.vm = n1.vm);
3787
- patchElementPropsAndAttrs$1(n1, n2, renderer);
4115
+ patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
3788
4116
  if (!shared.isUndefined(vm)) {
3789
4117
  // in fallback mode, the allocation will always set children to
3790
4118
  // empty and delegate the real allocation to the slot elements
@@ -3931,7 +4259,7 @@ function removeNode(node, parent, renderer) {
3931
4259
  lockDomMutation();
3932
4260
  }
3933
4261
  }
3934
- function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
4262
+ function patchElementPropsAndAttrsAndRefs$1(oldVnode, vnode, renderer) {
3935
4263
  if (shared.isNull(oldVnode)) {
3936
4264
  applyEventListeners(vnode, renderer);
3937
4265
  applyStaticClassAttribute(vnode, renderer);
@@ -3943,20 +4271,39 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3943
4271
  patchStyleAttribute(oldVnode, vnode, renderer);
3944
4272
  patchAttributes(oldVnode, vnode, renderer);
3945
4273
  patchProps(oldVnode, vnode, renderer);
4274
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
4275
+ applyRefs(vnode, vnode.owner);
3946
4276
  }
3947
4277
  function applyStyleScoping(elm, owner, renderer) {
4278
+ const { getClassList } = renderer;
3948
4279
  // Set the class name for `*.scoped.css` style scoping.
3949
- const scopeToken = getScopeTokenClass(owner);
4280
+ const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
3950
4281
  if (!shared.isNull(scopeToken)) {
3951
- const { getClassList } = renderer;
3952
4282
  // TODO [#2762]: this dot notation with add is probably problematic
3953
4283
  // probably we should have a renderer api for just the add operation
3954
4284
  getClassList(elm).add(scopeToken);
3955
4285
  }
4286
+ // TODO [#3733]: remove support for legacy scope tokens
4287
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4288
+ const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
4289
+ if (!shared.isNull(legacyScopeToken)) {
4290
+ // TODO [#2762]: this dot notation with add is probably problematic
4291
+ // probably we should have a renderer api for just the add operation
4292
+ getClassList(elm).add(legacyScopeToken);
4293
+ }
4294
+ }
3956
4295
  // Set property element for synthetic shadow DOM style scoping.
3957
4296
  const { stylesheetToken: syntheticToken } = owner.context;
3958
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && !shared.isUndefined(syntheticToken)) {
3959
- elm.$shadowToken$ = syntheticToken;
4297
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
4298
+ if (!shared.isUndefined(syntheticToken)) {
4299
+ elm.$shadowToken$ = syntheticToken;
4300
+ }
4301
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4302
+ const legacyToken = owner.context.legacyStylesheetToken;
4303
+ if (!shared.isUndefined(legacyToken)) {
4304
+ elm.$legacyShadowToken$ = legacyToken;
4305
+ }
4306
+ }
3960
4307
  }
3961
4308
  }
3962
4309
  function applyDomManual(elm, vnode) {
@@ -4316,14 +4663,6 @@ function updateStaticChildren(c1, c2, parent, renderer) {
4316
4663
  }
4317
4664
  }
4318
4665
  }
4319
- function shouldUseNativeCustomElementLifecycle(vm) {
4320
- if (lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
4321
- // temporary "kill switch"
4322
- return false;
4323
- }
4324
- const apiVersion = getComponentAPIVersion(vm.component.constructor);
4325
- return shared.isAPIFeatureEnabled(5 /* APIFeature.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE */, apiVersion);
4326
- }
4327
4666
 
4328
4667
  /*
4329
4668
  * Copyright (c) 2018, salesforce.com, inc.
@@ -4335,6 +4674,14 @@ const SymbolIterator = Symbol.iterator;
4335
4674
  function addVNodeToChildLWC(vnode) {
4336
4675
  shared.ArrayPush.call(getVMBeingRendered().velements, vnode);
4337
4676
  }
4677
+ // [s]tatic [p]art
4678
+ function sp(partId, data) {
4679
+ return {
4680
+ partId,
4681
+ data,
4682
+ elm: undefined, // elm is defined later
4683
+ };
4684
+ }
4338
4685
  // [s]coped [s]lot [f]actory
4339
4686
  function ssf(slotName, factory) {
4340
4687
  return {
@@ -4348,7 +4695,7 @@ function ssf(slotName, factory) {
4348
4695
  };
4349
4696
  }
4350
4697
  // [st]atic node
4351
- function st(fragment, key, data) {
4698
+ function st(fragment, key, parts) {
4352
4699
  const owner = getVMBeingRendered();
4353
4700
  const vnode = {
4354
4701
  type: 4 /* VNodeType.Static */,
@@ -4357,12 +4704,8 @@ function st(fragment, key, data) {
4357
4704
  elm: undefined,
4358
4705
  fragment,
4359
4706
  owner,
4360
- data,
4707
+ parts,
4361
4708
  };
4362
- const ref = data === null || data === void 0 ? void 0 : data.ref;
4363
- if (!shared.isUndefined(ref)) {
4364
- setRefVNode(owner, ref, vnode);
4365
- }
4366
4709
  return vnode;
4367
4710
  }
4368
4711
  // [fr]agment node
@@ -4404,7 +4747,7 @@ function h(sel, data, children = EmptyArray) {
4404
4747
  }
4405
4748
  });
4406
4749
  }
4407
- const { key, ref } = data;
4750
+ const { key } = data;
4408
4751
  const vnode = {
4409
4752
  type: 2 /* VNodeType.Element */,
4410
4753
  sel,
@@ -4414,9 +4757,6 @@ function h(sel, data, children = EmptyArray) {
4414
4757
  key,
4415
4758
  owner: vmBeingRendered,
4416
4759
  };
4417
- if (!shared.isUndefined(ref)) {
4418
- setRefVNode(vmBeingRendered, ref, vnode);
4419
- }
4420
4760
  return vnode;
4421
4761
  }
4422
4762
  // [t]ab[i]ndex function
@@ -4531,7 +4871,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
4531
4871
  });
4532
4872
  }
4533
4873
  }
4534
- const { key, ref } = data;
4874
+ const { key } = data;
4535
4875
  let elm, aChildren, vm;
4536
4876
  const vnode = {
4537
4877
  type: 3 /* VNodeType.CustomElement */,
@@ -4547,9 +4887,6 @@ function c(sel, Ctor, data, children = EmptyArray) {
4547
4887
  vm,
4548
4888
  };
4549
4889
  addVNodeToChildLWC(vnode);
4550
- if (!shared.isUndefined(ref)) {
4551
- setRefVNode(vmBeingRendered, ref, vnode);
4552
- }
4553
4890
  return vnode;
4554
4891
  }
4555
4892
  // [i]terable node
@@ -4840,6 +5177,7 @@ const api = shared.freeze({
4840
5177
  shc,
4841
5178
  ssf,
4842
5179
  ddc,
5180
+ sp,
4843
5181
  });
4844
5182
 
4845
5183
  /*
@@ -4997,9 +5335,10 @@ function buildParseFragmentFn(createFragmentFn) {
4997
5335
  return (strings, ...keys) => {
4998
5336
  const cache = shared.create(null);
4999
5337
  return function () {
5000
- const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
5338
+ const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
5001
5339
  const hasStyleToken = !shared.isUndefined(stylesheetToken);
5002
5340
  const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
5341
+ const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
5003
5342
  let cacheKey = 0;
5004
5343
  if (hasStyleToken && hasScopedStyles) {
5005
5344
  cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
@@ -5007,12 +5346,19 @@ function buildParseFragmentFn(createFragmentFn) {
5007
5346
  if (hasStyleToken && isSyntheticShadow) {
5008
5347
  cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
5009
5348
  }
5349
+ if (hasLegacyToken) {
5350
+ // This isn't strictly required for prod, but it's required for our karma tests
5351
+ // since the lwcRuntimeFlag may change over time
5352
+ cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
5353
+ }
5010
5354
  if (!shared.isUndefined(cache[cacheKey])) {
5011
5355
  return cache[cacheKey];
5012
5356
  }
5013
- const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetToken : '';
5014
- const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetToken}"` : '';
5015
- const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetToken : '';
5357
+ // If legacy stylesheet tokens are required, then add them to the rendered string
5358
+ const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
5359
+ const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
5360
+ const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
5361
+ const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
5016
5362
  let htmlFragment = '';
5017
5363
  for (let i = 0, n = keys.length; i < n; i++) {
5018
5364
  switch (keys[i]) {
@@ -5088,7 +5434,10 @@ function evaluateTemplate(vm, html) {
5088
5434
  // Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
5089
5435
  context.hasScopedStyles = computeHasScopedStyles(html, vm);
5090
5436
  // Update the scoping token on the host element.
5091
- updateStylesheetToken(vm, html);
5437
+ updateStylesheetToken(vm, html, /* legacy */ false);
5438
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
5439
+ updateStylesheetToken(vm, html, /* legacy */ true);
5440
+ }
5092
5441
  // Evaluate, create stylesheet and cache the produced VNode for future
5093
5442
  // re-rendering.
5094
5443
  const stylesheetsContent = getStylesheetsContent(vm, html);
@@ -5103,8 +5452,6 @@ function evaluateTemplate(vm, html) {
5103
5452
  // add the VM to the list of host VMs that can be re-rendered if html is swapped
5104
5453
  setActiveVM(vm);
5105
5454
  }
5106
- // reset the refs; they will be set during the tmpl() instantiation
5107
- vm.refVNodes = html.hasRefs ? shared.create(null) : null;
5108
5455
  // right before producing the vnodes, we clear up all internal references
5109
5456
  // to custom elements from the template.
5110
5457
  vm.velements = [];
@@ -5274,8 +5621,9 @@ function getComponentAPIVersion(Ctor) {
5274
5621
  const metadata = registeredComponentMap.get(Ctor);
5275
5622
  const apiVersion = metadata === null || metadata === void 0 ? void 0 : metadata.apiVersion;
5276
5623
  if (shared.isUndefined(apiVersion)) {
5277
- // This should only occur in two places: 1) our Karma tests, with unregistered components, and
5278
- // 2) the ACT compiler. To be safe, return the lowest possible API version.
5624
+ // This should only occur in our Karma tests; in practice every component
5625
+ // is registered, and so this code path should not get hit. But to be safe,
5626
+ // return the lowest possible version.
5279
5627
  return shared.LOWEST_API_VERSION;
5280
5628
  }
5281
5629
  return apiVersion;
@@ -5323,44 +5671,6 @@ function getWrappedComponentsListener(vm, listener) {
5323
5671
  return wrappedListener;
5324
5672
  }
5325
5673
 
5326
- /*
5327
- * Copyright (c) 2018, salesforce.com, inc.
5328
- * All rights reserved.
5329
- * SPDX-License-Identifier: MIT
5330
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
5331
- */
5332
- const Services = shared.create(null);
5333
- const hooks = ['rendered', 'connected', 'disconnected'];
5334
- /**
5335
- * EXPERIMENTAL: This function allows for the registration of "services"
5336
- * in LWC by exposing hooks into the component life-cycle. This API is
5337
- * subject to change or being removed.
5338
- */
5339
- function register(service) {
5340
- if (process.env.NODE_ENV !== 'production') {
5341
- shared.assert.isTrue(shared.isObject(service), `Invalid service declaration, ${service}: service must be an object`);
5342
- }
5343
- for (let i = 0; i < hooks.length; ++i) {
5344
- const hookName = hooks[i];
5345
- if (hookName in service) {
5346
- let l = Services[hookName];
5347
- if (shared.isUndefined(l)) {
5348
- Services[hookName] = l = [];
5349
- }
5350
- shared.ArrayPush.call(l, service[hookName]);
5351
- }
5352
- }
5353
- }
5354
- function invokeServiceHook(vm, cbs) {
5355
- if (process.env.NODE_ENV !== 'production') {
5356
- shared.assert.isTrue(shared.isArray(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`);
5357
- }
5358
- const { component, def, context } = vm;
5359
- for (let i = 0, len = cbs.length; i < len; ++i) {
5360
- cbs[i].call(undefined, component, {}, def, context);
5361
- }
5362
- }
5363
-
5364
5674
  /*
5365
5675
  * Copyright (c) 2023, Salesforce.com, inc.
5366
5676
  * All rights reserved.
@@ -5419,12 +5729,18 @@ function resetComponentStateWhenRemoved(vm) {
5419
5729
  // old vnode.children is removed from the DOM.
5420
5730
  function removeVM(vm) {
5421
5731
  if (process.env.NODE_ENV !== 'production') {
5422
- shared.assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
5732
+ if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
5733
+ // With native lifecycle, we cannot be certain that connectedCallback was called before a component
5734
+ // was removed from the VDOM. If the component is disconnected, then connectedCallback will not fire
5735
+ // in native mode, although it will fire in synthetic mode due to appendChild triggering it.
5736
+ // See: W-14037619 for details
5737
+ shared.assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
5738
+ }
5423
5739
  }
5424
5740
  resetComponentStateWhenRemoved(vm);
5425
5741
  }
5426
- function getNearestShadowAncestor(vm) {
5427
- let ancestor = vm.owner;
5742
+ function getNearestShadowAncestor(owner) {
5743
+ let ancestor = owner;
5428
5744
  while (!shared.isNull(ancestor) && ancestor.renderMode === 0 /* RenderMode.Light */) {
5429
5745
  ancestor = ancestor.owner;
5430
5746
  }
@@ -5458,6 +5774,9 @@ function createVM(elm, ctor, renderer, options) {
5458
5774
  stylesheetToken: undefined,
5459
5775
  hasTokenInClass: undefined,
5460
5776
  hasTokenInAttribute: undefined,
5777
+ legacyStylesheetToken: undefined,
5778
+ hasLegacyTokenInClass: undefined,
5779
+ hasLegacyTokenInAttribute: undefined,
5461
5780
  hasScopedStyles: undefined,
5462
5781
  styleVNodes: null,
5463
5782
  tplCache: EmptyObject,
@@ -5482,15 +5801,12 @@ function createVM(elm, ctor, renderer, options) {
5482
5801
  vm.debugInfo = shared.create(null);
5483
5802
  }
5484
5803
  vm.stylesheets = computeStylesheets(vm, def.ctor);
5485
- vm.shadowMode = computeShadowMode(vm, renderer);
5804
+ vm.shadowMode = computeShadowMode(def, vm.owner, renderer);
5486
5805
  vm.tro = getTemplateReactiveObserver(vm);
5487
5806
  if (process.env.NODE_ENV !== 'production') {
5488
5807
  vm.toString = () => {
5489
5808
  return `[object:vm ${def.name} (${vm.idx})]`;
5490
5809
  };
5491
- if (lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5492
- vm.shadowMode = 0 /* ShadowMode.Native */;
5493
- }
5494
5810
  }
5495
5811
  // Create component instance associated to the vm and the element.
5496
5812
  invokeComponentConstructor(vm, def.ctor);
@@ -5553,8 +5869,21 @@ function warnOnStylesheetsMutation(ctor) {
5553
5869
  });
5554
5870
  }
5555
5871
  }
5556
- function computeShadowMode(vm, renderer) {
5557
- const { def } = vm;
5872
+ // Compute the shadowMode/renderMode without creating a VM. This is used in some scenarios like hydration.
5873
+ function computeShadowAndRenderMode(Ctor, renderer) {
5874
+ const def = getComponentInternalDef(Ctor);
5875
+ const { renderMode } = def;
5876
+ // Assume null `owner` - this is what happens in hydration cases anyway
5877
+ const shadowMode = computeShadowMode(def, /* owner */ null, renderer);
5878
+ return { renderMode, shadowMode };
5879
+ }
5880
+ function computeShadowMode(def, owner, renderer) {
5881
+ // Force the shadow mode to always be native. Used for running tests with synthetic shadow patches
5882
+ // on, but components running in actual native shadow mode
5883
+ if (process.env.NODE_ENV !== 'production' &&
5884
+ lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5885
+ return 0 /* ShadowMode.Native */;
5886
+ }
5558
5887
  const { isSyntheticShadowDefined } = renderer;
5559
5888
  let shadowMode;
5560
5889
  if (isSyntheticShadowDefined) {
@@ -5563,12 +5892,14 @@ function computeShadowMode(vm, renderer) {
5563
5892
  // everything defaults to native when the synthetic shadow polyfill is unavailable.
5564
5893
  shadowMode = 0 /* ShadowMode.Native */;
5565
5894
  }
5566
- else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE) {
5567
- if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */) {
5895
+ else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE ||
5896
+ def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
5897
+ if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */ ||
5898
+ def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
5568
5899
  shadowMode = 0 /* ShadowMode.Native */;
5569
5900
  }
5570
5901
  else {
5571
- const shadowAncestor = getNearestShadowAncestor(vm);
5902
+ const shadowAncestor = getNearestShadowAncestor(owner);
5572
5903
  if (!shared.isNull(shadowAncestor) && shadowAncestor.shadowMode === 0 /* ShadowMode.Native */) {
5573
5904
  // Transitive support for native Shadow DOM. A component in native mode
5574
5905
  // transitively opts all of its descendants into native.
@@ -5623,6 +5954,8 @@ function rehydrate(vm) {
5623
5954
  }
5624
5955
  function patchShadowRoot(vm, newCh) {
5625
5956
  const { renderRoot, children: oldCh, renderer } = vm;
5957
+ // reset the refs; they will be set during `patchChildren`
5958
+ resetRefVNodes(vm);
5626
5959
  // caching the new children collection
5627
5960
  vm.children = newCh;
5628
5961
  if (newCh.length > 0 || oldCh.length > 0) {
@@ -5654,10 +5987,6 @@ function runRenderedCallback(vm) {
5654
5987
  if (!process.env.IS_BROWSER) {
5655
5988
  return;
5656
5989
  }
5657
- const { rendered } = Services;
5658
- if (rendered) {
5659
- invokeServiceHook(vm, rendered);
5660
- }
5661
5990
  if (!shared.isUndefined(renderedCallback)) {
5662
5991
  logOperationStart(4 /* OperationId.RenderedCallback */, vm);
5663
5992
  invokeComponentCallback(vm, renderedCallback);
@@ -5700,11 +6029,6 @@ function runConnectedCallback(vm) {
5700
6029
  return; // nothing to do since it was already connected
5701
6030
  }
5702
6031
  vm.state = 1 /* VMState.connected */;
5703
- // reporting connection
5704
- const { connected } = Services;
5705
- if (connected) {
5706
- invokeServiceHook(vm, connected);
5707
- }
5708
6032
  if (hasWireAdapters(vm)) {
5709
6033
  connectWireAdapters(vm);
5710
6034
  }
@@ -5730,11 +6054,6 @@ function runDisconnectedCallback(vm) {
5730
6054
  vm.isDirty = true;
5731
6055
  }
5732
6056
  vm.state = 2 /* VMState.disconnected */;
5733
- // reporting disconnection
5734
- const { disconnected } = Services;
5735
- if (disconnected) {
5736
- invokeServiceHook(vm, disconnected);
5737
- }
5738
6057
  if (hasWireAdapters(vm)) {
5739
6058
  disconnectWireAdapters(vm);
5740
6059
  }
@@ -5859,7 +6178,12 @@ function runWithBoundaryProtection(vm, owner, pre, job, post) {
5859
6178
  if (!shared.isUndefined(error)) {
5860
6179
  addErrorComponentStack(vm, error);
5861
6180
  const errorBoundaryVm = shared.isNull(owner) ? undefined : getErrorBoundaryVM(owner);
5862
- if (shared.isUndefined(errorBoundaryVm)) {
6181
+ // Error boundaries are not in effect when server-side rendering. `errorCallback`
6182
+ // is intended to allow recovery from errors - changing the state of a component
6183
+ // and instigating a re-render. That is at odds with the single-pass, synchronous
6184
+ // nature of SSR. For that reason, all errors bubble up to the `renderComponent`
6185
+ // call site.
6186
+ if (!process.env.IS_BROWSER || shared.isUndefined(errorBoundaryVm)) {
5863
6187
  throw error; // eslint-disable-line no-unsafe-finally
5864
6188
  }
5865
6189
  resetComponentRoot(vm); // remove offenders
@@ -5887,6 +6211,52 @@ function forceRehydration(vm) {
5887
6211
  scheduleRehydration(vm);
5888
6212
  }
5889
6213
  }
6214
+ function runFormAssociatedCustomElementCallback(vm, faceCb) {
6215
+ const { renderMode, shadowMode, def: { formAssociated }, } = vm;
6216
+ // Technically the UpgradableConstructor always sets `static formAssociated = true` but silently fail here to match browser behavior.
6217
+ if (shared.isUndefined(formAssociated) || shared.isFalse(formAssociated)) {
6218
+ if (process.env.NODE_ENV !== 'production') {
6219
+ logWarn(`Form associated lifecycle methods must have the 'static formAssociated' value set in the component's prototype chain.`);
6220
+ }
6221
+ return;
6222
+ }
6223
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
6224
+ throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
6225
+ }
6226
+ invokeComponentCallback(vm, faceCb);
6227
+ }
6228
+ function runFormAssociatedCallback(elm) {
6229
+ const vm = getAssociatedVM(elm);
6230
+ const { formAssociatedCallback } = vm.def;
6231
+ if (!shared.isUndefined(formAssociatedCallback)) {
6232
+ runFormAssociatedCustomElementCallback(vm, formAssociatedCallback);
6233
+ }
6234
+ }
6235
+ function runFormDisabledCallback(elm) {
6236
+ const vm = getAssociatedVM(elm);
6237
+ const { formDisabledCallback } = vm.def;
6238
+ if (!shared.isUndefined(formDisabledCallback)) {
6239
+ runFormAssociatedCustomElementCallback(vm, formDisabledCallback);
6240
+ }
6241
+ }
6242
+ function runFormResetCallback(elm) {
6243
+ const vm = getAssociatedVM(elm);
6244
+ const { formResetCallback } = vm.def;
6245
+ if (!shared.isUndefined(formResetCallback)) {
6246
+ runFormAssociatedCustomElementCallback(vm, formResetCallback);
6247
+ }
6248
+ }
6249
+ function runFormStateRestoreCallback(elm) {
6250
+ const vm = getAssociatedVM(elm);
6251
+ const { formStateRestoreCallback } = vm.def;
6252
+ if (!shared.isUndefined(formStateRestoreCallback)) {
6253
+ runFormAssociatedCustomElementCallback(vm, formStateRestoreCallback);
6254
+ }
6255
+ }
6256
+ function resetRefVNodes(vm) {
6257
+ const { cmpTemplate } = vm;
6258
+ vm.refVNodes = !shared.isNull(cmpTemplate) && cmpTemplate.hasRefs ? shared.create(null) : null;
6259
+ }
5890
6260
 
5891
6261
  /*
5892
6262
  * Copyright (c) 2018, salesforce.com, inc.
@@ -6061,6 +6431,12 @@ const NON_STANDARD_ARIA_PROPS = [
6061
6431
  'ariaLabelledBy',
6062
6432
  'ariaOwns',
6063
6433
  ];
6434
+ function isGlobalAriaPolyfillLoaded() {
6435
+ // Sniff for the legacy polyfill being loaded. The reason this works is because ariaActiveDescendant is a
6436
+ // non-standard ARIA property reflection that is only supported in our legacy polyfill. See
6437
+ // @lwc/aria-reflection/README.md for details.
6438
+ return !shared.isUndefined(shared.getOwnPropertyDescriptor(Element.prototype, 'ariaActiveDescendant'));
6439
+ }
6064
6440
  function findVM(elm) {
6065
6441
  // If it's a shadow DOM component, then it has a host
6066
6442
  const { host } = elm.getRootNode();
@@ -6120,6 +6496,9 @@ function enableDetection() {
6120
6496
  }
6121
6497
  // @ts-ignore
6122
6498
  const { get, set } = descriptor;
6499
+ // It's important for this defineProperty call to happen _after_ ARIA accessors are applied to the
6500
+ // BaseBridgeElement and LightningElement prototypes. Otherwise, we will log/report for access of non-standard
6501
+ // props on these prototypes, which we actually don't want. We only care about access on generic HTMLElements.
6123
6502
  shared.defineProperty(prototype, prop, {
6124
6503
  get() {
6125
6504
  checkAndReportViolation(this, prop, false, undefined);
@@ -6135,16 +6514,14 @@ function enableDetection() {
6135
6514
  }
6136
6515
  }
6137
6516
  // No point in running this code if we're not in a browser, or if the global polyfill is not loaded
6138
- if (process.env.IS_BROWSER) {
6139
- if (lwcRuntimeFlags.ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL) {
6140
- // Always run detection in dev mode, so we can at least print to the console
6141
- if (process.env.NODE_ENV !== 'production') {
6142
- enableDetection();
6143
- }
6144
- else {
6145
- // In prod mode, only enable detection if reporting is enabled
6146
- onReportingEnabled(enableDetection);
6147
- }
6517
+ if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
6518
+ // Always run detection in dev mode, so we can at least print to the console
6519
+ if (process.env.NODE_ENV !== 'production') {
6520
+ enableDetection();
6521
+ }
6522
+ else {
6523
+ // In prod mode, only enable detection if reporting is enabled
6524
+ onReportingEnabled(enableDetection);
6148
6525
  }
6149
6526
  }
6150
6527
 
@@ -6167,6 +6544,8 @@ function hydrateRoot(vm) {
6167
6544
  function hydrateVM(vm) {
6168
6545
  const children = renderComponent(vm);
6169
6546
  vm.children = children;
6547
+ // reset the refs; they will be set during `hydrateChildren`
6548
+ resetRefVNodes(vm);
6170
6549
  const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
6171
6550
  hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
6172
6551
  runRenderedCallback(vm);
@@ -6275,7 +6654,7 @@ function hydrateStaticElement(elm, vnode, renderer) {
6275
6654
  return handleMismatch(elm, vnode, renderer);
6276
6655
  }
6277
6656
  vnode.elm = elm;
6278
- applyEventListeners(vnode, renderer);
6657
+ applyStaticParts(elm, vnode, renderer, true);
6279
6658
  return elm;
6280
6659
  }
6281
6660
  function hydrateFragment(elm, vnode, renderer) {
@@ -6309,7 +6688,7 @@ function hydrateElement(elm, vnode, renderer) {
6309
6688
  }
6310
6689
  }
6311
6690
  }
6312
- patchElementPropsAndAttrs(vnode, renderer);
6691
+ patchElementPropsAndAttrsAndRefs(vnode, renderer);
6313
6692
  if (!isDomManual) {
6314
6693
  const { getFirstChild } = renderer;
6315
6694
  hydrateChildren(getFirstChild(elm), vnode.children, elm, owner);
@@ -6333,6 +6712,8 @@ function hydrateCustomElement(elm, vnode, renderer) {
6333
6712
  return handleMismatch(elm, vnode, renderer);
6334
6713
  }
6335
6714
  const { sel, mode, ctor, owner } = vnode;
6715
+ const { defineCustomElement, getTagName } = renderer;
6716
+ defineCustomElement(shared.StringToLowerCase.call(getTagName(elm)));
6336
6717
  const vm = createVM(elm, ctor, renderer, {
6337
6718
  mode,
6338
6719
  owner,
@@ -6342,7 +6723,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
6342
6723
  vnode.elm = elm;
6343
6724
  vnode.vm = vm;
6344
6725
  allocateChildren(vnode, vm);
6345
- patchElementPropsAndAttrs(vnode, renderer);
6726
+ patchElementPropsAndAttrsAndRefs(vnode, renderer);
6346
6727
  // Insert hook section:
6347
6728
  if (process.env.NODE_ENV !== 'production') {
6348
6729
  shared.assert.isTrue(vm.state === 0 /* VMState.created */, `${vm} cannot be recycled.`);
@@ -6407,9 +6788,11 @@ function handleMismatch(node, vnode, renderer) {
6407
6788
  removeNode(node, parentNode, renderer);
6408
6789
  return vnode.elm;
6409
6790
  }
6410
- function patchElementPropsAndAttrs(vnode, renderer) {
6791
+ function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
6411
6792
  applyEventListeners(vnode, renderer);
6412
6793
  patchProps(null, vnode, renderer);
6794
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
6795
+ applyRefs(vnode, vnode.owner);
6413
6796
  }
6414
6797
  function hasCorrectNodeType(vnode, node, nodeType, renderer) {
6415
6798
  const { getProperty } = renderer;
@@ -6477,7 +6860,8 @@ function validateClassAttr(vnode, elm, renderer) {
6477
6860
  const { data, owner } = vnode;
6478
6861
  let { className, classMap } = data;
6479
6862
  const { getProperty, getClassList, getAttribute } = renderer;
6480
- const scopedToken = getScopeTokenClass(owner);
6863
+ // we don't care about legacy for hydration. it's a new use case
6864
+ const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
6481
6865
  const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
6482
6866
  // Classnames for scoped CSS are added directly to the DOM during rendering,
6483
6867
  // or to the VDOM on the server in the case of SSR. As such, these classnames
@@ -6792,7 +7176,7 @@ function trackMutations(tmpl) {
6792
7176
  }
6793
7177
  function addLegacyStylesheetTokensShim(tmpl) {
6794
7178
  // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6795
- // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
7179
+ // is accessing the old internal API (backwards compat). Details: W-14210169
6796
7180
  shared.defineProperty(tmpl, 'stylesheetTokens', {
6797
7181
  enumerable: true,
6798
7182
  configurable: true,
@@ -6898,6 +7282,7 @@ exports.LightningElement = LightningElement;
6898
7282
  exports.__unstable__ProfilerControl = profilerControl;
6899
7283
  exports.__unstable__ReportingControl = reportingControl;
6900
7284
  exports.api = api$1;
7285
+ exports.computeShadowAndRenderMode = computeShadowAndRenderMode;
6901
7286
  exports.connectRootElement = connectRootElement;
6902
7287
  exports.createContextProviderWithRegister = createContextProviderWithRegister;
6903
7288
  exports.createVM = createVM;
@@ -6913,10 +7298,13 @@ exports.isComponentConstructor = isComponentConstructor;
6913
7298
  exports.parseFragment = parseFragment;
6914
7299
  exports.parseSVGFragment = parseSVGFragment;
6915
7300
  exports.readonly = readonly;
6916
- exports.register = register;
6917
7301
  exports.registerComponent = registerComponent;
6918
7302
  exports.registerDecorators = registerDecorators;
6919
7303
  exports.registerTemplate = registerTemplate;
7304
+ exports.runFormAssociatedCallback = runFormAssociatedCallback;
7305
+ exports.runFormDisabledCallback = runFormDisabledCallback;
7306
+ exports.runFormResetCallback = runFormResetCallback;
7307
+ exports.runFormStateRestoreCallback = runFormStateRestoreCallback;
6920
7308
  exports.sanitizeAttribute = sanitizeAttribute;
6921
7309
  exports.setHooks = setHooks;
6922
7310
  exports.swapComponent = swapComponent;
@@ -6925,5 +7313,5 @@ exports.swapTemplate = swapTemplate;
6925
7313
  exports.track = track;
6926
7314
  exports.unwrap = unwrap;
6927
7315
  exports.wire = wire;
6928
- /** version: 4.0.0-alpha.0 */
7316
+ /** version: 4.0.0 */
6929
7317
  //# sourceMappingURL=index.cjs.js.map