@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.js CHANGED
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Copyright (C) 2023 salesforce.com, inc.
3
3
  */
4
- import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isArray as isArray$1, isFunction as isFunction$1, keys, hasOwnProperty as hasOwnProperty$1, globalThis as globalThis$1, forEach, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, assign, isObject, freeze, KEY__SYNTHETIC_MODE, assert, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, getOwnPropertyNames as getOwnPropertyNames$1, htmlPropertyToAttribute, ArraySlice, ArrayMap, KEY__SCOPED_CSS, kebabCaseToCamelCase, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, ArrayPop, isAPIFeatureEnabled, isNumber, StringReplace, ArrayUnshift, LOWEST_API_VERSION, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, ID_REFERENCING_ATTRIBUTES_SET, KEY__SHADOW_TOKEN, ArrayFilter, StringSplit, arrayEvery, ArrayIncludes, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift } from '@lwc/shared';
5
- import { applyAriaReflection } from '@lwc/aria-reflection';
4
+ import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, ArrayIndexOf, ArraySplice, create, seal, isArray as isArray$1, isFunction as isFunction$1, keys, hasOwnProperty as hasOwnProperty$1, globalThis as globalThis$1, AriaPropNameToAttrNameMap, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, forEach, getPropertyDescriptor, defineProperties, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, assign, isObject, freeze, KEY__SYNTHETIC_MODE, isString, assert, toString as toString$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, getOwnPropertyNames as getOwnPropertyNames$1, getOwnPropertyDescriptors, htmlPropertyToAttribute, ArraySlice, ArrayMap, KEY__SCOPED_CSS, kebabCaseToCamelCase, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, StringSlice, ArrayShift, ArrayUnshift, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, ArrayPop, isAPIFeatureEnabled, isNumber, StringReplace, LOWEST_API_VERSION, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, ID_REFERENCING_ATTRIBUTES_SET, KEY__SHADOW_TOKEN, ArrayFilter, StringSplit, arrayEvery, ArrayIncludes, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse } from '@lwc/shared';
6
5
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
7
6
 
8
7
  /*
@@ -388,20 +387,6 @@ function flattenStylesheets(stylesheets) {
388
387
  }
389
388
  return list;
390
389
  }
391
- // Set a ref (lwc:ref) on a VM, from a template API
392
- function setRefVNode(vm, ref, vnode) {
393
- if (process.env.NODE_ENV !== 'production' && isUndefined$1(vm.refVNodes)) {
394
- throw new Error('refVNodes must be defined when setting a ref');
395
- }
396
- // If this method is called, then vm.refVNodes is set as the template has refs.
397
- // If not, then something went wrong and we threw an error above.
398
- const refVNodes = vm.refVNodes;
399
- // In cases of conflict (two elements with the same ref), prefer, the last one,
400
- // in depth-first traversal order.
401
- if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
402
- refVNodes[ref] = vnode;
403
- }
404
- }
405
390
  // Throw an error if we're running in prod mode. Ensures code is truly removed from prod mode.
406
391
  function assertNotProd() {
407
392
  /* istanbul ignore if */
@@ -429,6 +414,45 @@ var _a, _b;
429
414
  const instrumentDef = (_a = globalThis$1.__lwc_instrument_cmp_def) !== null && _a !== void 0 ? _a : noop;
430
415
  const instrumentInstance = (_b = globalThis$1.__lwc_instrument_cmp_instance) !== null && _b !== void 0 ? _b : noop;
431
416
 
417
+ /*
418
+ * Copyright (c) 2023, salesforce.com, inc.
419
+ * All rights reserved.
420
+ * SPDX-License-Identifier: MIT
421
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
422
+ */
423
+ // Apply ARIA string reflection behavior to a prototype.
424
+ // This is deliberately kept separate from @lwc/aria-reflection. @lwc/aria-reflection is a global polyfill that is
425
+ // needed for backwards compatibility in LEX, whereas `applyAriaReflection` is designed to only apply to our own
426
+ // LightningElement/BaseBridgeElement prototypes.
427
+ function applyAriaReflection(prototype) {
428
+ for (const propName of keys(AriaPropNameToAttrNameMap)) {
429
+ const attrName = AriaPropNameToAttrNameMap[propName];
430
+ if (isUndefined$1(getOwnPropertyDescriptor$1(prototype, propName))) {
431
+ // Note that we need to call this.{get,set,has,remove}Attribute rather than dereferencing
432
+ // from Element.prototype, because these methods are overridden in LightningElement.
433
+ defineProperty(prototype, propName, {
434
+ get() {
435
+ return this.getAttribute(attrName);
436
+ },
437
+ set(newValue) {
438
+ // TODO [#3284]: there is disagreement between browsers and the spec on how to treat undefined
439
+ // Our historical behavior is to only treat null as removing the attribute
440
+ // See also https://github.com/w3c/aria/issues/1858
441
+ if (isNull(newValue)) {
442
+ this.removeAttribute(attrName);
443
+ }
444
+ else {
445
+ this.setAttribute(attrName, newValue);
446
+ }
447
+ },
448
+ // configurable and enumerable to allow it to be overridden – this mimics Safari's/Chrome's behavior
449
+ configurable: true,
450
+ enumerable: true,
451
+ });
452
+ }
453
+ }
454
+ }
455
+
432
456
  /*
433
457
  * Copyright (c) 2018, salesforce.com, inc.
434
458
  * All rights reserved.
@@ -519,8 +543,8 @@ function lockDomMutation() {
519
543
  assertNotProd(); // this method should never leak to prod
520
544
  isDomMutationAllowed = false;
521
545
  }
522
- function logMissingPortalError(name, type) {
523
- return logError(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
546
+ function logMissingPortalWarn(name, type) {
547
+ return logWarn(`The \`${name}\` ${type} is available only on elements that use the \`lwc:dom="manual"\` directive.`);
524
548
  }
525
549
  function patchElementWithRestrictions(elm, options) {
526
550
  assertNotProd(); // this method should never leak to prod
@@ -545,14 +569,14 @@ function patchElementWithRestrictions(elm, options) {
545
569
  assign(descriptors, {
546
570
  appendChild: generateDataDescriptor({
547
571
  value(aChild) {
548
- logMissingPortalError('appendChild', 'method');
572
+ logMissingPortalWarn('appendChild', 'method');
549
573
  return appendChild.call(this, aChild);
550
574
  },
551
575
  }),
552
576
  insertBefore: generateDataDescriptor({
553
577
  value(newNode, referenceNode) {
554
578
  if (!isDomMutationAllowed) {
555
- logMissingPortalError('insertBefore', 'method');
579
+ logMissingPortalWarn('insertBefore', 'method');
556
580
  }
557
581
  return insertBefore.call(this, newNode, referenceNode);
558
582
  },
@@ -560,14 +584,14 @@ function patchElementWithRestrictions(elm, options) {
560
584
  removeChild: generateDataDescriptor({
561
585
  value(aChild) {
562
586
  if (!isDomMutationAllowed) {
563
- logMissingPortalError('removeChild', 'method');
587
+ logMissingPortalWarn('removeChild', 'method');
564
588
  }
565
589
  return removeChild.call(this, aChild);
566
590
  },
567
591
  }),
568
592
  replaceChild: generateDataDescriptor({
569
593
  value(newChild, oldChild) {
570
- logMissingPortalError('replaceChild', 'method');
594
+ logMissingPortalWarn('replaceChild', 'method');
571
595
  return replaceChild.call(this, newChild, oldChild);
572
596
  },
573
597
  }),
@@ -577,7 +601,7 @@ function patchElementWithRestrictions(elm, options) {
577
601
  },
578
602
  set(value) {
579
603
  if (!isDomMutationAllowed) {
580
- logMissingPortalError('nodeValue', 'property');
604
+ logMissingPortalWarn('nodeValue', 'property');
581
605
  }
582
606
  originalNodeValueDescriptor.set.call(this, value);
583
607
  },
@@ -587,7 +611,7 @@ function patchElementWithRestrictions(elm, options) {
587
611
  return originalTextContentDescriptor.get.call(this);
588
612
  },
589
613
  set(value) {
590
- logMissingPortalError('textContent', 'property');
614
+ logMissingPortalWarn('textContent', 'property');
591
615
  originalTextContentDescriptor.set.call(this, value);
592
616
  },
593
617
  }),
@@ -596,7 +620,7 @@ function patchElementWithRestrictions(elm, options) {
596
620
  return originalInnerHTMLDescriptor.get.call(this);
597
621
  },
598
622
  set(value) {
599
- logMissingPortalError('innerHTML', 'property');
623
+ logMissingPortalWarn('innerHTML', 'property');
600
624
  return originalInnerHTMLDescriptor.set.call(this, value);
601
625
  },
602
626
  }),
@@ -1454,6 +1478,79 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1454
1478
  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.`);
1455
1479
  }
1456
1480
  }
1481
+ // List of properties on ElementInternals that are formAssociated can be found in the spec:
1482
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements
1483
+ const formAssociatedProps = new Set([
1484
+ 'setFormValue',
1485
+ 'form',
1486
+ 'setValidity',
1487
+ 'willValidate',
1488
+ 'validity',
1489
+ 'validationMessage',
1490
+ 'checkValidity',
1491
+ 'reportValidity',
1492
+ 'labels',
1493
+ ]);
1494
+ // Verify that access to a form-associated property of the ElementInternals proxy has formAssociated set in the LWC.
1495
+ function verifyPropForFormAssociation(propertyKey, isFormAssociated) {
1496
+ if (isString(propertyKey) && formAssociatedProps.has(propertyKey) && !isFormAssociated) {
1497
+ //Note this error message mirrors Chrome and Firefox error messages, in Safari the error is slightly different.
1498
+ throw new DOMException(`Failed to execute '${propertyKey}' on 'ElementInternals': The target element is not a form-associated custom element.`);
1499
+ }
1500
+ }
1501
+ const elementInternalsAccessorAllowList = new Set(['shadowRoot', 'role', ...formAssociatedProps]);
1502
+ // Prevent access to properties not defined in the HTML spec in case browsers decide to
1503
+ // provide new APIs that provide access to form associated properties.
1504
+ // This can be removed along with UpgradeableConstructor.
1505
+ function isAllowedElementInternalAccessor(propertyKey) {
1506
+ let isAllowedAccessor = false;
1507
+ // As of this writing all ElementInternal property keys as described in the spec are implemented with strings
1508
+ // in Chrome, Firefox, and Safari
1509
+ if (isString(propertyKey)) {
1510
+ // Allow list is based on HTML spec:
1511
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#the-elementinternals-interface
1512
+ isAllowedAccessor =
1513
+ elementInternalsAccessorAllowList.has(propertyKey) || /^aria/.test(propertyKey);
1514
+ if (!isAllowedAccessor && process.env.NODE_ENV !== 'production') {
1515
+ logWarn('Only properties defined in the ElementInternals HTML spec are available.');
1516
+ }
1517
+ }
1518
+ return isAllowedAccessor;
1519
+ }
1520
+ // Wrap all ElementInternal objects in a proxy to prevent form association when `formAssociated` is not set on an LWC.
1521
+ // This is needed because the 1UpgradeableConstructor1 always sets `formAssociated=true`, which means all
1522
+ // ElementInternal objects will have form-associated properties set when an LWC is placed in a form.
1523
+ // We are doing this to guard against customers taking a dependency on form elements being associated to ElementInternals
1524
+ // when 'formAssociated' has not been set on the LWC.
1525
+ function createElementInternalsProxy(elementInternals, isFormAssociated) {
1526
+ const elementInternalsProxy = new Proxy(elementInternals, {
1527
+ set(target, propertyKey, newValue) {
1528
+ if (isAllowedElementInternalAccessor(propertyKey)) {
1529
+ // Verify that formAssociated is set for form associated properties
1530
+ verifyPropForFormAssociation(propertyKey, isFormAssociated);
1531
+ return Reflect.set(target, propertyKey, newValue);
1532
+ }
1533
+ // As of this writing ElementInternals do not have non-string properties that can be set.
1534
+ return false;
1535
+ },
1536
+ get(target, propertyKey) {
1537
+ if (
1538
+ // Pass through Object.prototype methods such as toString()
1539
+ hasOwnProperty$1.call(Object.prototype, propertyKey) ||
1540
+ // As of this writing, ElementInternals only uses Symbol.toStringTag which is called
1541
+ // on Object.hasOwnProperty invocations
1542
+ Symbol.for('Symbol.toStringTag') === propertyKey ||
1543
+ // ElementInternals allow listed properties
1544
+ isAllowedElementInternalAccessor(propertyKey)) {
1545
+ // Verify that formAssociated is set for form associated properties
1546
+ verifyPropForFormAssociation(propertyKey, isFormAssociated);
1547
+ const propertyValue = Reflect.get(target, propertyKey);
1548
+ return isFunction$1(propertyValue) ? propertyValue.bind(target) : propertyValue;
1549
+ }
1550
+ },
1551
+ });
1552
+ return elementInternalsProxy;
1553
+ }
1457
1554
  // @ts-ignore
1458
1555
  LightningElement.prototype = {
1459
1556
  constructor: LightningElement,
@@ -1545,6 +1642,16 @@ LightningElement.prototype = {
1545
1642
  }
1546
1643
  return getBoundingClientRect(elm);
1547
1644
  },
1645
+ attachInternals() {
1646
+ const vm = getAssociatedVM(this);
1647
+ const { elm, def: { formAssociated }, renderer: { attachInternals }, } = vm;
1648
+ if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1649
+ throw new Error('attachInternals API is not supported in light DOM or synthetic shadow.');
1650
+ }
1651
+ const internals = attachInternals(elm);
1652
+ // #TODO[2970]: remove proxy once `UpgradeableConstructor` has been removed
1653
+ return createElementInternalsProxy(internals, Boolean(formAssociated));
1654
+ },
1548
1655
  get isConnected() {
1549
1656
  const vm = getAssociatedVM(this);
1550
1657
  const { elm, renderer: { isConnected }, } = vm;
@@ -2545,7 +2652,22 @@ function createAttributeChangedCallback(attributeToPropMap, superAttributeChange
2545
2652
  this[propName] = newValue;
2546
2653
  };
2547
2654
  }
2548
- function HTMLBridgeElementFactory(SuperClass, props, methods) {
2655
+ function createAccessorThatWarns(propName) {
2656
+ let prop;
2657
+ return {
2658
+ get() {
2659
+ 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.`);
2660
+ return prop;
2661
+ },
2662
+ set(value) {
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
+ prop = value;
2665
+ },
2666
+ enumerable: true,
2667
+ configurable: true,
2668
+ };
2669
+ }
2670
+ function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observedFields, proto, hasCustomSuperClass) {
2549
2671
  const HTMLBridgeElement = class extends SuperClass {
2550
2672
  };
2551
2673
  // generating the hash table for attributes to avoid duplicate fields and facilitate validation
@@ -2554,9 +2676,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2554
2676
  const { attributeChangedCallback: superAttributeChangedCallback } = SuperClass.prototype;
2555
2677
  const { observedAttributes: superObservedAttributes = [] } = SuperClass;
2556
2678
  const descriptors = create(null);
2679
+ // present a hint message so that developers are aware that they have not decorated property with @api
2680
+ if (process.env.NODE_ENV !== 'production') {
2681
+ // TODO [#3761]: enable for components that don't extend from LightningElement
2682
+ if (!isUndefined$1(proto) && !isNull(proto) && !hasCustomSuperClass) {
2683
+ const nonPublicPropertiesToWarnOn = new Set([
2684
+ // getters, setters, and methods
2685
+ ...keys(getOwnPropertyDescriptors(proto)),
2686
+ // class properties
2687
+ ...observedFields,
2688
+ ]
2689
+ // we don't want to override HTMLElement props because these are meaningful in other ways,
2690
+ // and can break tooling that expects it to be iterable or defined, e.g. Jest:
2691
+ // https://github.com/jestjs/jest/blob/b4c9587/packages/pretty-format/src/plugins/DOMElement.ts#L95
2692
+ // It also doesn't make sense to override e.g. "constructor".
2693
+ .filter((propName) => !(propName in HTMLElementPrototype)));
2694
+ for (const propName of nonPublicPropertiesToWarnOn) {
2695
+ if (ArrayIndexOf.call(publicProperties, propName) === -1) {
2696
+ descriptors[propName] = createAccessorThatWarns(propName);
2697
+ }
2698
+ }
2699
+ }
2700
+ }
2557
2701
  // expose getters and setters for each public props on the new Element Bridge
2558
- for (let i = 0, len = props.length; i < len; i += 1) {
2559
- const propName = props[i];
2702
+ for (let i = 0, len = publicProperties.length; i < len; i += 1) {
2703
+ const propName = publicProperties[i];
2560
2704
  attributeToPropMap[htmlPropertyToAttribute(propName)] = propName;
2561
2705
  descriptors[propName] = {
2562
2706
  get: createGetter(propName),
@@ -2581,6 +2725,31 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2581
2725
  descriptors.attributeChangedCallback = {
2582
2726
  value: createAttributeChangedCallback(attributeToPropMap, superAttributeChangedCallback),
2583
2727
  };
2728
+ // To avoid leaking private component details, accessing internals from outside a component is not allowed.
2729
+ descriptors.attachInternals = {
2730
+ set() {
2731
+ if (process.env.NODE_ENV !== 'production') {
2732
+ logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
2733
+ }
2734
+ },
2735
+ get() {
2736
+ if (process.env.NODE_ENV !== 'production') {
2737
+ logWarn('attachInternals cannot be accessed outside of a component. Use this.attachInternals instead.');
2738
+ }
2739
+ },
2740
+ };
2741
+ descriptors.formAssociated = {
2742
+ set() {
2743
+ if (process.env.NODE_ENV !== 'production') {
2744
+ logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
2745
+ }
2746
+ },
2747
+ get() {
2748
+ if (process.env.NODE_ENV !== 'production') {
2749
+ logWarn('formAssociated cannot be accessed outside of a component. Set the value within the component class.');
2750
+ }
2751
+ },
2752
+ };
2584
2753
  // Specify attributes for which we want to reflect changes back to their corresponding
2585
2754
  // properties via attributeChangedCallback.
2586
2755
  defineProperty(HTMLBridgeElement, 'observedAttributes', {
@@ -2591,7 +2760,7 @@ function HTMLBridgeElementFactory(SuperClass, props, methods) {
2591
2760
  defineProperties(HTMLBridgeElement.prototype, descriptors);
2592
2761
  return HTMLBridgeElement;
2593
2762
  }
2594
- const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), []);
2763
+ const BaseBridgeElement = HTMLBridgeElementFactory(HTMLElementConstructor, getOwnPropertyNames$1(HTMLElementOriginalDescriptors), [], [], null, false);
2595
2764
  if (process.env.IS_BROWSER) {
2596
2765
  // This ARIA reflection only really makes sense in the browser. On the server, there is no `renderedCallback()`,
2597
2766
  // so you cannot do e.g. `this.template.querySelector('x-child').ariaBusy = 'true'`. So we don't need to expose
@@ -2889,7 +3058,7 @@ function getCtorProto(Ctor) {
2889
3058
  return proto;
2890
3059
  }
2891
3060
  function createComponentDef(Ctor) {
2892
- const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode } = Ctor;
3061
+ const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
2893
3062
  if (process.env.NODE_ENV !== 'production') {
2894
3063
  const ctorName = Ctor.name;
2895
3064
  // Removing the following assert until https://bugs.webkit.org/show_bug.cgi?id=190140 is fixed.
@@ -2901,7 +3070,8 @@ function createComponentDef(Ctor) {
2901
3070
  }
2902
3071
  if (!isUndefined$1(ctorShadowSupportMode) &&
2903
3072
  ctorShadowSupportMode !== "any" /* ShadowSupportMode.Any */ &&
2904
- ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */) {
3073
+ ctorShadowSupportMode !== "reset" /* ShadowSupportMode.Default */ &&
3074
+ ctorShadowSupportMode !== "native" /* ShadowSupportMode.Native */) {
2905
3075
  logError(`Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
2906
3076
  }
2907
3077
  if (!isUndefined$1(ctorRenderMode) &&
@@ -2913,10 +3083,11 @@ function createComponentDef(Ctor) {
2913
3083
  const decoratorsMeta = getDecoratorsMeta(Ctor);
2914
3084
  const { apiFields, apiFieldsConfig, apiMethods, wiredFields, wiredMethods, observedFields } = decoratorsMeta;
2915
3085
  const proto = Ctor.prototype;
2916
- let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, render } = proto;
3086
+ let { connectedCallback, disconnectedCallback, renderedCallback, errorCallback, formAssociatedCallback, formResetCallback, formDisabledCallback, formStateRestoreCallback, render, } = proto;
2917
3087
  const superProto = getCtorProto(Ctor);
2918
- const superDef = superProto !== LightningElement ? getComponentInternalDef(superProto) : lightingElementDef;
2919
- const bridge = HTMLBridgeElementFactory(superDef.bridge, keys(apiFields), keys(apiMethods));
3088
+ const hasCustomSuperClass = superProto !== LightningElement;
3089
+ const superDef = hasCustomSuperClass ? getComponentInternalDef(superProto) : lightingElementDef;
3090
+ const bridge = HTMLBridgeElementFactory(superDef.bridge, keys(apiFields), keys(apiMethods), keys(observedFields), proto, hasCustomSuperClass);
2920
3091
  const props = assign(create(null), superDef.props, apiFields);
2921
3092
  const propsConfig = assign(create(null), superDef.propsConfig, apiFieldsConfig);
2922
3093
  const methods = assign(create(null), superDef.methods, apiMethods);
@@ -2925,6 +3096,10 @@ function createComponentDef(Ctor) {
2925
3096
  disconnectedCallback = disconnectedCallback || superDef.disconnectedCallback;
2926
3097
  renderedCallback = renderedCallback || superDef.renderedCallback;
2927
3098
  errorCallback = errorCallback || superDef.errorCallback;
3099
+ formAssociatedCallback = formAssociatedCallback || superDef.formAssociatedCallback;
3100
+ formResetCallback = formResetCallback || superDef.formResetCallback;
3101
+ formDisabledCallback = formDisabledCallback || superDef.formDisabledCallback;
3102
+ formStateRestoreCallback = formStateRestoreCallback || superDef.formStateRestoreCallback;
2928
3103
  render = render || superDef.render;
2929
3104
  let shadowSupportMode = superDef.shadowSupportMode;
2930
3105
  if (!isUndefined$1(ctorShadowSupportMode)) {
@@ -2934,6 +3109,10 @@ function createComponentDef(Ctor) {
2934
3109
  if (!isUndefined$1(ctorRenderMode)) {
2935
3110
  renderMode = ctorRenderMode === 'light' ? 0 /* RenderMode.Light */ : 1 /* RenderMode.Shadow */;
2936
3111
  }
3112
+ let formAssociated = superDef.formAssociated;
3113
+ if (!isUndefined$1(ctorFormAssociated)) {
3114
+ formAssociated = ctorFormAssociated;
3115
+ }
2937
3116
  const template = getComponentRegisteredTemplate(Ctor) || superDef.template;
2938
3117
  const name = Ctor.name || superDef.name;
2939
3118
  // installing observed fields into the prototype.
@@ -2949,10 +3128,15 @@ function createComponentDef(Ctor) {
2949
3128
  template,
2950
3129
  renderMode,
2951
3130
  shadowSupportMode,
3131
+ formAssociated,
2952
3132
  connectedCallback,
2953
3133
  disconnectedCallback,
2954
- renderedCallback,
2955
3134
  errorCallback,
3135
+ formAssociatedCallback,
3136
+ formDisabledCallback,
3137
+ formResetCallback,
3138
+ formStateRestoreCallback,
3139
+ renderedCallback,
2956
3140
  render,
2957
3141
  };
2958
3142
  // This is a no-op unless Lightning DevTools are enabled.
@@ -3029,6 +3213,7 @@ const lightingElementDef = {
3029
3213
  methods: EmptyObject,
3030
3214
  renderMode: 1 /* RenderMode.Shadow */,
3031
3215
  shadowSupportMode: "reset" /* ShadowSupportMode.Default */,
3216
+ formAssociated: undefined,
3032
3217
  wire: EmptyObject,
3033
3218
  bridge: BaseBridgeElement,
3034
3219
  template: defaultEmptyTemplate,
@@ -3085,9 +3270,11 @@ function createInlineStyleVNode(content) {
3085
3270
  },
3086
3271
  }, [api.t(content)]);
3087
3272
  }
3088
- function updateStylesheetToken(vm, template) {
3273
+ // TODO [#3733]: remove support for legacy scope tokens
3274
+ function updateStylesheetToken(vm, template, legacy) {
3089
3275
  const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
3090
- const { stylesheets: newStylesheets, stylesheetToken: newStylesheetToken } = template;
3276
+ const { stylesheets: newStylesheets } = template;
3277
+ const newStylesheetToken = legacy ? template.legacyStylesheetToken : template.stylesheetToken;
3091
3278
  const { stylesheets: newVmStylesheets } = vm;
3092
3279
  const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
3093
3280
  const { hasScopedStyles } = context;
@@ -3095,7 +3282,19 @@ function updateStylesheetToken(vm, template) {
3095
3282
  let newHasTokenInClass;
3096
3283
  let newHasTokenInAttribute;
3097
3284
  // Reset the styling token applied to the host element.
3098
- const { stylesheetToken: oldToken, hasTokenInClass: oldHasTokenInClass, hasTokenInAttribute: oldHasTokenInAttribute, } = context;
3285
+ let oldToken;
3286
+ let oldHasTokenInClass;
3287
+ let oldHasTokenInAttribute;
3288
+ if (legacy) {
3289
+ oldToken = context.legacyStylesheetToken;
3290
+ oldHasTokenInClass = context.hasLegacyTokenInClass;
3291
+ oldHasTokenInAttribute = context.hasLegacyTokenInAttribute;
3292
+ }
3293
+ else {
3294
+ oldToken = context.stylesheetToken;
3295
+ oldHasTokenInClass = context.hasTokenInClass;
3296
+ oldHasTokenInAttribute = context.hasTokenInAttribute;
3297
+ }
3099
3298
  if (!isUndefined$1(oldToken)) {
3100
3299
  if (oldHasTokenInClass) {
3101
3300
  getClassList(elm).remove(makeHostToken(oldToken));
@@ -3123,9 +3322,16 @@ function updateStylesheetToken(vm, template) {
3123
3322
  }
3124
3323
  }
3125
3324
  // Update the styling tokens present on the context object.
3126
- context.stylesheetToken = newToken;
3127
- context.hasTokenInClass = newHasTokenInClass;
3128
- context.hasTokenInAttribute = newHasTokenInAttribute;
3325
+ if (legacy) {
3326
+ context.legacyStylesheetToken = newToken;
3327
+ context.hasLegacyTokenInClass = newHasTokenInClass;
3328
+ context.hasLegacyTokenInAttribute = newHasTokenInAttribute;
3329
+ }
3330
+ else {
3331
+ context.stylesheetToken = newToken;
3332
+ context.hasTokenInClass = newHasTokenInClass;
3333
+ context.hasTokenInAttribute = newHasTokenInAttribute;
3334
+ }
3129
3335
  }
3130
3336
  function evaluateStylesheetsContent(stylesheets, stylesheetToken, vm) {
3131
3337
  const content = [];
@@ -3213,9 +3419,12 @@ function getNearestShadowComponent(vm) {
3213
3419
  * this returns the unique token for that scoped stylesheet. Otherwise
3214
3420
  * it returns null.
3215
3421
  */
3216
- function getScopeTokenClass(owner) {
3422
+ // TODO [#3733]: remove support for legacy scope tokens
3423
+ function getScopeTokenClass(owner, legacy) {
3217
3424
  const { cmpTemplate, context } = owner;
3218
- return (context.hasScopedStyles && (cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) || null;
3425
+ return ((context.hasScopedStyles &&
3426
+ (legacy ? cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.legacyStylesheetToken : cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken)) ||
3427
+ null);
3219
3428
  }
3220
3429
  /**
3221
3430
  * This function returns the host style token for a custom element if it
@@ -3349,28 +3558,20 @@ function isLiveBindingProp(sel, key) {
3349
3558
  return sel === 'input' && (key === 'value' || key === 'checked');
3350
3559
  }
3351
3560
  function patchProps(oldVnode, vnode, renderer) {
3352
- let { props } = vnode.data;
3353
- const { spread } = vnode.data;
3354
- if (isUndefined$1(props) && isUndefined$1(spread)) {
3561
+ const { props } = vnode.data;
3562
+ if (isUndefined$1(props)) {
3355
3563
  return;
3356
3564
  }
3357
3565
  let oldProps;
3358
3566
  if (!isNull(oldVnode)) {
3359
3567
  oldProps = oldVnode.data.props;
3360
- const oldSpread = oldVnode.data.spread;
3361
3568
  // Props may be the same due to the static content optimization, so we can skip diffing
3362
- if (oldProps === props && oldSpread === spread) {
3569
+ if (oldProps === props) {
3363
3570
  return;
3364
3571
  }
3365
3572
  if (isUndefined$1(oldProps)) {
3366
3573
  oldProps = EmptyObject;
3367
3574
  }
3368
- if (!isUndefined$1(oldSpread)) {
3369
- oldProps = assign({}, oldProps, oldSpread);
3370
- }
3371
- }
3372
- if (!isUndefined$1(spread)) {
3373
- props = assign({}, props, spread);
3374
3575
  }
3375
3576
  const isFirstPatch = isNull(oldVnode);
3376
3577
  const { elm, sel } = vnode;
@@ -3544,6 +3745,113 @@ function applyStaticStyleAttribute(vnode, renderer) {
3544
3745
  }
3545
3746
  }
3546
3747
 
3748
+ /*
3749
+ * Copyright (c) 2023, salesforce.com, inc.
3750
+ * All rights reserved.
3751
+ * SPDX-License-Identifier: MIT
3752
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3753
+ */
3754
+ // Set a ref (lwc:ref) on a VM, from a template API
3755
+ function applyRefs(vnode, owner) {
3756
+ const { data } = vnode;
3757
+ const { ref } = data;
3758
+ if (isUndefined$1(ref)) {
3759
+ return;
3760
+ }
3761
+ if (process.env.NODE_ENV !== 'production' && isUndefined$1(owner.refVNodes)) {
3762
+ throw new Error('refVNodes must be defined when setting a ref');
3763
+ }
3764
+ // If this method is called, then vm.refVNodes is set as the template has refs.
3765
+ // If not, then something went wrong and we threw an error above.
3766
+ const refVNodes = owner.refVNodes;
3767
+ // In cases of conflict (two elements with the same ref), prefer the last one,
3768
+ // in depth-first traversal order. This happens automatically due to how we render
3769
+ refVNodes[ref] = vnode;
3770
+ }
3771
+
3772
+ /*
3773
+ * Copyright (c) 2023, salesforce.com, inc.
3774
+ * All rights reserved.
3775
+ * SPDX-License-Identifier: MIT
3776
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3777
+ */
3778
+ function traverseAndSetElements(root, parts, renderer) {
3779
+ const numParts = parts.length;
3780
+ // Optimization given that, in most cases, there will be one part, and it's just the root
3781
+ if (numParts === 1) {
3782
+ const firstPart = parts[0];
3783
+ if (firstPart.partId === 0) {
3784
+ // 0 means the root node
3785
+ firstPart.elm = root;
3786
+ return;
3787
+ }
3788
+ }
3789
+ const partIdsToParts = new Map();
3790
+ for (const staticPart of parts) {
3791
+ partIdsToParts.set(staticPart.partId, staticPart);
3792
+ }
3793
+ let numFoundParts = 0;
3794
+ const { previousSibling, getLastChild } = renderer;
3795
+ const stack = [root];
3796
+ let partId = -1;
3797
+ // Depth-first traversal. We assign a partId to each element, which is an integer based on traversal order.
3798
+ while (stack.length > 0) {
3799
+ const elm = ArrayShift.call(stack);
3800
+ partId++;
3801
+ const part = partIdsToParts.get(partId);
3802
+ if (!isUndefined$1(part)) {
3803
+ part.elm = elm;
3804
+ if (++numFoundParts === numParts) {
3805
+ return; // perf optimization - stop traversing once we've found everything we need
3806
+ }
3807
+ }
3808
+ // For depth-first traversal, prepend to the stack in reverse order
3809
+ // Note that we traverse using `*Child`/`*Sibling` rather than `children` because the browser uses a linked
3810
+ // list under the hood to represent the DOM tree, so it's faster to do this than to create an underlying array
3811
+ // by calling `children`.
3812
+ let child = getLastChild(elm);
3813
+ while (!isNull(child)) {
3814
+ ArrayUnshift.call(stack, child);
3815
+ child = previousSibling(child);
3816
+ }
3817
+ }
3818
+ if (process.env.NODE_ENV !== 'production') {
3819
+ assert.isTrue(numFoundParts === numParts, `Should have found all parts by now. Found ${numFoundParts}, needed ${numParts}.`);
3820
+ }
3821
+ }
3822
+ /**
3823
+ * Given an array of static parts, do all the mounting required for these parts.
3824
+ *
3825
+ * @param root - the root element
3826
+ * @param vnode - the parent VStatic
3827
+ * @param renderer - the renderer to use
3828
+ * @param mount - true this is a first (mount) render as opposed to a subsequent (patch) render
3829
+ */
3830
+ function applyStaticParts(root, vnode, renderer, mount) {
3831
+ // On the server, we don't support ref (because it relies on renderedCallback), nor do we
3832
+ // support event listeners (no interactivity), so traversing parts makes no sense
3833
+ if (!process.env.IS_BROWSER) {
3834
+ return;
3835
+ }
3836
+ const { parts, owner } = vnode;
3837
+ if (isUndefined$1(parts)) {
3838
+ return;
3839
+ }
3840
+ // This adds `part.elm` to each `part`. We have to do this on every mount/patch because the `parts`
3841
+ // array is recreated from scratch every time, so each `part.elm` is now undefined.
3842
+ // TODO [#3800]: avoid calling traverseAndSetElements on every re-render
3843
+ traverseAndSetElements(root, parts, renderer);
3844
+ // Currently only event listeners and refs are supported for static vnodes
3845
+ for (const part of parts) {
3846
+ if (mount) {
3847
+ // Event listeners only need to be applied once when mounting
3848
+ applyEventListeners(part, renderer);
3849
+ }
3850
+ // Refs must be updated after every render due to refVNodes getting reset before every render
3851
+ applyRefs(part, owner);
3852
+ }
3853
+ }
3854
+
3547
3855
  /*
3548
3856
  * Copyright (c) 2018, salesforce.com, inc.
3549
3857
  * All rights reserved.
@@ -3586,7 +3894,7 @@ function patch(n1, n2, parent, renderer) {
3586
3894
  patchComment(n1, n2, renderer);
3587
3895
  break;
3588
3896
  case 4 /* VNodeType.Static */:
3589
- n2.elm = n1.elm;
3897
+ patchStatic(n1, n2, renderer);
3590
3898
  break;
3591
3899
  case 5 /* VNodeType.Fragment */:
3592
3900
  patchFragment(n1, n2, parent, renderer);
@@ -3680,13 +3988,18 @@ function mountElement(vnode, parent, anchor, renderer) {
3680
3988
  applyStyleScoping(elm, owner, renderer);
3681
3989
  applyDomManual(elm, vnode);
3682
3990
  applyElementRestrictions(elm, vnode);
3683
- patchElementPropsAndAttrs$1(null, vnode, renderer);
3991
+ patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
3684
3992
  insertNode(elm, parent, anchor, renderer);
3685
3993
  mountVNodes(vnode.children, elm, renderer, null);
3686
3994
  }
3995
+ function patchStatic(n1, n2, renderer) {
3996
+ const elm = (n2.elm = n1.elm);
3997
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
3998
+ applyStaticParts(elm, n2, renderer, false);
3999
+ }
3687
4000
  function patchElement(n1, n2, renderer) {
3688
4001
  const elm = (n2.elm = n1.elm);
3689
- patchElementPropsAndAttrs$1(n1, n2, renderer);
4002
+ patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
3690
4003
  patchChildren(n1.children, n2.children, elm, renderer);
3691
4004
  }
3692
4005
  function mountStatic(vnode, parent, anchor, renderer) {
@@ -3703,8 +4016,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
3703
4016
  }
3704
4017
  }
3705
4018
  insertNode(elm, parent, anchor, renderer);
3706
- // Event listeners are only applied once when mounting, so they are allowed for static vnodes
3707
- applyEventListeners(vnode, renderer);
4019
+ applyStaticParts(elm, vnode, renderer, true);
3708
4020
  }
3709
4021
  function mountCustomElement(vnode, parent, anchor, renderer) {
3710
4022
  const { sel, owner } = vnode;
@@ -3720,22 +4032,38 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3720
4032
  // the custom element from the registry is expecting an upgrade callback
3721
4033
  vm = createViewModelHook(elm, vnode, renderer);
3722
4034
  };
3723
- const connectedCallback = (elm) => {
3724
- if (shouldUseNativeCustomElementLifecycle(vm)) {
4035
+ let connectedCallback;
4036
+ let disconnectedCallback;
4037
+ let formAssociatedCallback;
4038
+ let formDisabledCallback;
4039
+ let formResetCallback;
4040
+ let formStateRestoreCallback;
4041
+ if (lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
4042
+ connectedCallback = (elm) => {
3725
4043
  connectRootElement(elm);
3726
- }
3727
- };
3728
- const disconnectedCallback = (elm) => {
3729
- if (shouldUseNativeCustomElementLifecycle(vm)) {
4044
+ };
4045
+ disconnectedCallback = (elm) => {
3730
4046
  disconnectRootElement(elm);
3731
- }
3732
- };
4047
+ };
4048
+ formAssociatedCallback = (elm) => {
4049
+ runFormAssociatedCallback(elm);
4050
+ };
4051
+ formDisabledCallback = (elm) => {
4052
+ runFormDisabledCallback(elm);
4053
+ };
4054
+ formResetCallback = (elm) => {
4055
+ runFormResetCallback(elm);
4056
+ };
4057
+ formStateRestoreCallback = (elm) => {
4058
+ runFormStateRestoreCallback(elm);
4059
+ };
4060
+ }
3733
4061
  // Should never get a tag with upper case letter at this point; the compiler
3734
4062
  // should produce only tags with lowercase letters. However, the Java
3735
4063
  // compiler may generate tagnames with uppercase letters so - for backwards
3736
4064
  // compatibility, we lower case the tagname here.
3737
4065
  const normalizedTagname = sel.toLowerCase();
3738
- const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback);
4066
+ const elm = createCustomElement(normalizedTagname, upgradeCallback, connectedCallback, disconnectedCallback, formAssociatedCallback, formDisabledCallback, formResetCallback, formStateRestoreCallback);
3739
4067
  vnode.elm = elm;
3740
4068
  vnode.vm = vm;
3741
4069
  linkNodeToShadow(elm, owner, renderer);
@@ -3743,11 +4071,11 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3743
4071
  if (vm) {
3744
4072
  allocateChildren(vnode, vm);
3745
4073
  }
3746
- patchElementPropsAndAttrs$1(null, vnode, renderer);
4074
+ patchElementPropsAndAttrsAndRefs$1(null, vnode, renderer);
3747
4075
  insertNode(elm, parent, anchor, renderer);
3748
4076
  if (vm) {
3749
4077
  if (process.env.IS_BROWSER) {
3750
- if (!shouldUseNativeCustomElementLifecycle(vm)) {
4078
+ if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
3751
4079
  if (process.env.NODE_ENV !== 'production') {
3752
4080
  // With synthetic lifecycle callbacks, it's possible for elements to be removed without the engine
3753
4081
  // noticing it (e.g. `appendChild` the same host element twice). This test ensures we don't regress.
@@ -3780,7 +4108,7 @@ function patchCustomElement(n1, n2, parent, renderer) {
3780
4108
  // Otherwise patch the existing component with new props/attrs/etc.
3781
4109
  const elm = (n2.elm = n1.elm);
3782
4110
  const vm = (n2.vm = n1.vm);
3783
- patchElementPropsAndAttrs$1(n1, n2, renderer);
4111
+ patchElementPropsAndAttrsAndRefs$1(n1, n2, renderer);
3784
4112
  if (!isUndefined$1(vm)) {
3785
4113
  // in fallback mode, the allocation will always set children to
3786
4114
  // empty and delegate the real allocation to the slot elements
@@ -3927,7 +4255,7 @@ function removeNode(node, parent, renderer) {
3927
4255
  lockDomMutation();
3928
4256
  }
3929
4257
  }
3930
- function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
4258
+ function patchElementPropsAndAttrsAndRefs$1(oldVnode, vnode, renderer) {
3931
4259
  if (isNull(oldVnode)) {
3932
4260
  applyEventListeners(vnode, renderer);
3933
4261
  applyStaticClassAttribute(vnode, renderer);
@@ -3939,20 +4267,39 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3939
4267
  patchStyleAttribute(oldVnode, vnode, renderer);
3940
4268
  patchAttributes(oldVnode, vnode, renderer);
3941
4269
  patchProps(oldVnode, vnode, renderer);
4270
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
4271
+ applyRefs(vnode, vnode.owner);
3942
4272
  }
3943
4273
  function applyStyleScoping(elm, owner, renderer) {
4274
+ const { getClassList } = renderer;
3944
4275
  // Set the class name for `*.scoped.css` style scoping.
3945
- const scopeToken = getScopeTokenClass(owner);
4276
+ const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
3946
4277
  if (!isNull(scopeToken)) {
3947
- const { getClassList } = renderer;
3948
4278
  // TODO [#2762]: this dot notation with add is probably problematic
3949
4279
  // probably we should have a renderer api for just the add operation
3950
4280
  getClassList(elm).add(scopeToken);
3951
4281
  }
4282
+ // TODO [#3733]: remove support for legacy scope tokens
4283
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4284
+ const legacyScopeToken = getScopeTokenClass(owner, /* legacy */ true);
4285
+ if (!isNull(legacyScopeToken)) {
4286
+ // TODO [#2762]: this dot notation with add is probably problematic
4287
+ // probably we should have a renderer api for just the add operation
4288
+ getClassList(elm).add(legacyScopeToken);
4289
+ }
4290
+ }
3952
4291
  // Set property element for synthetic shadow DOM style scoping.
3953
4292
  const { stylesheetToken: syntheticToken } = owner.context;
3954
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && !isUndefined$1(syntheticToken)) {
3955
- elm.$shadowToken$ = syntheticToken;
4293
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
4294
+ if (!isUndefined$1(syntheticToken)) {
4295
+ elm.$shadowToken$ = syntheticToken;
4296
+ }
4297
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4298
+ const legacyToken = owner.context.legacyStylesheetToken;
4299
+ if (!isUndefined$1(legacyToken)) {
4300
+ elm.$legacyShadowToken$ = legacyToken;
4301
+ }
4302
+ }
3956
4303
  }
3957
4304
  }
3958
4305
  function applyDomManual(elm, vnode) {
@@ -4312,14 +4659,6 @@ function updateStaticChildren(c1, c2, parent, renderer) {
4312
4659
  }
4313
4660
  }
4314
4661
  }
4315
- function shouldUseNativeCustomElementLifecycle(vm) {
4316
- if (lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
4317
- // temporary "kill switch"
4318
- return false;
4319
- }
4320
- const apiVersion = getComponentAPIVersion(vm.component.constructor);
4321
- return isAPIFeatureEnabled(5 /* APIFeature.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE */, apiVersion);
4322
- }
4323
4662
 
4324
4663
  /*
4325
4664
  * Copyright (c) 2018, salesforce.com, inc.
@@ -4331,6 +4670,14 @@ const SymbolIterator = Symbol.iterator;
4331
4670
  function addVNodeToChildLWC(vnode) {
4332
4671
  ArrayPush$1.call(getVMBeingRendered().velements, vnode);
4333
4672
  }
4673
+ // [s]tatic [p]art
4674
+ function sp(partId, data) {
4675
+ return {
4676
+ partId,
4677
+ data,
4678
+ elm: undefined, // elm is defined later
4679
+ };
4680
+ }
4334
4681
  // [s]coped [s]lot [f]actory
4335
4682
  function ssf(slotName, factory) {
4336
4683
  return {
@@ -4344,7 +4691,7 @@ function ssf(slotName, factory) {
4344
4691
  };
4345
4692
  }
4346
4693
  // [st]atic node
4347
- function st(fragment, key, data) {
4694
+ function st(fragment, key, parts) {
4348
4695
  const owner = getVMBeingRendered();
4349
4696
  const vnode = {
4350
4697
  type: 4 /* VNodeType.Static */,
@@ -4353,12 +4700,8 @@ function st(fragment, key, data) {
4353
4700
  elm: undefined,
4354
4701
  fragment,
4355
4702
  owner,
4356
- data,
4703
+ parts,
4357
4704
  };
4358
- const ref = data === null || data === void 0 ? void 0 : data.ref;
4359
- if (!isUndefined$1(ref)) {
4360
- setRefVNode(owner, ref, vnode);
4361
- }
4362
4705
  return vnode;
4363
4706
  }
4364
4707
  // [fr]agment node
@@ -4400,7 +4743,7 @@ function h(sel, data, children = EmptyArray) {
4400
4743
  }
4401
4744
  });
4402
4745
  }
4403
- const { key, ref } = data;
4746
+ const { key } = data;
4404
4747
  const vnode = {
4405
4748
  type: 2 /* VNodeType.Element */,
4406
4749
  sel,
@@ -4410,9 +4753,6 @@ function h(sel, data, children = EmptyArray) {
4410
4753
  key,
4411
4754
  owner: vmBeingRendered,
4412
4755
  };
4413
- if (!isUndefined$1(ref)) {
4414
- setRefVNode(vmBeingRendered, ref, vnode);
4415
- }
4416
4756
  return vnode;
4417
4757
  }
4418
4758
  // [t]ab[i]ndex function
@@ -4527,7 +4867,7 @@ function c(sel, Ctor, data, children = EmptyArray) {
4527
4867
  });
4528
4868
  }
4529
4869
  }
4530
- const { key, ref } = data;
4870
+ const { key } = data;
4531
4871
  let elm, aChildren, vm;
4532
4872
  const vnode = {
4533
4873
  type: 3 /* VNodeType.CustomElement */,
@@ -4543,9 +4883,6 @@ function c(sel, Ctor, data, children = EmptyArray) {
4543
4883
  vm,
4544
4884
  };
4545
4885
  addVNodeToChildLWC(vnode);
4546
- if (!isUndefined$1(ref)) {
4547
- setRefVNode(vmBeingRendered, ref, vnode);
4548
- }
4549
4886
  return vnode;
4550
4887
  }
4551
4888
  // [i]terable node
@@ -4836,6 +5173,7 @@ const api = freeze({
4836
5173
  shc,
4837
5174
  ssf,
4838
5175
  ddc,
5176
+ sp,
4839
5177
  });
4840
5178
 
4841
5179
  /*
@@ -4993,9 +5331,10 @@ function buildParseFragmentFn(createFragmentFn) {
4993
5331
  return (strings, ...keys) => {
4994
5332
  const cache = create(null);
4995
5333
  return function () {
4996
- const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
5334
+ const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
4997
5335
  const hasStyleToken = !isUndefined$1(stylesheetToken);
4998
5336
  const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
5337
+ const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !isUndefined$1(legacyStylesheetToken);
4999
5338
  let cacheKey = 0;
5000
5339
  if (hasStyleToken && hasScopedStyles) {
5001
5340
  cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
@@ -5003,12 +5342,19 @@ function buildParseFragmentFn(createFragmentFn) {
5003
5342
  if (hasStyleToken && isSyntheticShadow) {
5004
5343
  cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
5005
5344
  }
5345
+ if (hasLegacyToken) {
5346
+ // This isn't strictly required for prod, but it's required for our karma tests
5347
+ // since the lwcRuntimeFlag may change over time
5348
+ cacheKey |= 4 /* FragmentCache.HAS_LEGACY_SCOPE_TOKEN */;
5349
+ }
5006
5350
  if (!isUndefined$1(cache[cacheKey])) {
5007
5351
  return cache[cacheKey];
5008
5352
  }
5009
- const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetToken : '';
5010
- const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetToken}"` : '';
5011
- const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetToken : '';
5353
+ // If legacy stylesheet tokens are required, then add them to the rendered string
5354
+ const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
5355
+ const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
5356
+ const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetTokenToRender}"` : '';
5357
+ const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetTokenToRender : '';
5012
5358
  let htmlFragment = '';
5013
5359
  for (let i = 0, n = keys.length; i < n; i++) {
5014
5360
  switch (keys[i]) {
@@ -5084,7 +5430,10 @@ function evaluateTemplate(vm, html) {
5084
5430
  // Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
5085
5431
  context.hasScopedStyles = computeHasScopedStyles(html, vm);
5086
5432
  // Update the scoping token on the host element.
5087
- updateStylesheetToken(vm, html);
5433
+ updateStylesheetToken(vm, html, /* legacy */ false);
5434
+ if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
5435
+ updateStylesheetToken(vm, html, /* legacy */ true);
5436
+ }
5088
5437
  // Evaluate, create stylesheet and cache the produced VNode for future
5089
5438
  // re-rendering.
5090
5439
  const stylesheetsContent = getStylesheetsContent(vm, html);
@@ -5099,8 +5448,6 @@ function evaluateTemplate(vm, html) {
5099
5448
  // add the VM to the list of host VMs that can be re-rendered if html is swapped
5100
5449
  setActiveVM(vm);
5101
5450
  }
5102
- // reset the refs; they will be set during the tmpl() instantiation
5103
- vm.refVNodes = html.hasRefs ? create(null) : null;
5104
5451
  // right before producing the vnodes, we clear up all internal references
5105
5452
  // to custom elements from the template.
5106
5453
  vm.velements = [];
@@ -5270,8 +5617,9 @@ function getComponentAPIVersion(Ctor) {
5270
5617
  const metadata = registeredComponentMap.get(Ctor);
5271
5618
  const apiVersion = metadata === null || metadata === void 0 ? void 0 : metadata.apiVersion;
5272
5619
  if (isUndefined$1(apiVersion)) {
5273
- // This should only occur in two places: 1) our Karma tests, with unregistered components, and
5274
- // 2) the ACT compiler. To be safe, return the lowest possible API version.
5620
+ // This should only occur in our Karma tests; in practice every component
5621
+ // is registered, and so this code path should not get hit. But to be safe,
5622
+ // return the lowest possible version.
5275
5623
  return LOWEST_API_VERSION;
5276
5624
  }
5277
5625
  return apiVersion;
@@ -5319,44 +5667,6 @@ function getWrappedComponentsListener(vm, listener) {
5319
5667
  return wrappedListener;
5320
5668
  }
5321
5669
 
5322
- /*
5323
- * Copyright (c) 2018, salesforce.com, inc.
5324
- * All rights reserved.
5325
- * SPDX-License-Identifier: MIT
5326
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
5327
- */
5328
- const Services = create(null);
5329
- const hooks = ['rendered', 'connected', 'disconnected'];
5330
- /**
5331
- * EXPERIMENTAL: This function allows for the registration of "services"
5332
- * in LWC by exposing hooks into the component life-cycle. This API is
5333
- * subject to change or being removed.
5334
- */
5335
- function register(service) {
5336
- if (process.env.NODE_ENV !== 'production') {
5337
- assert.isTrue(isObject(service), `Invalid service declaration, ${service}: service must be an object`);
5338
- }
5339
- for (let i = 0; i < hooks.length; ++i) {
5340
- const hookName = hooks[i];
5341
- if (hookName in service) {
5342
- let l = Services[hookName];
5343
- if (isUndefined$1(l)) {
5344
- Services[hookName] = l = [];
5345
- }
5346
- ArrayPush$1.call(l, service[hookName]);
5347
- }
5348
- }
5349
- }
5350
- function invokeServiceHook(vm, cbs) {
5351
- if (process.env.NODE_ENV !== 'production') {
5352
- assert.isTrue(isArray$1(cbs) && cbs.length > 0, `Optimize invokeServiceHook() to be invoked only when needed`);
5353
- }
5354
- const { component, def, context } = vm;
5355
- for (let i = 0, len = cbs.length; i < len; ++i) {
5356
- cbs[i].call(undefined, component, {}, def, context);
5357
- }
5358
- }
5359
-
5360
5670
  /*
5361
5671
  * Copyright (c) 2023, Salesforce.com, inc.
5362
5672
  * All rights reserved.
@@ -5415,12 +5725,18 @@ function resetComponentStateWhenRemoved(vm) {
5415
5725
  // old vnode.children is removed from the DOM.
5416
5726
  function removeVM(vm) {
5417
5727
  if (process.env.NODE_ENV !== 'production') {
5418
- assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
5728
+ if (!lwcRuntimeFlags.ENABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE) {
5729
+ // With native lifecycle, we cannot be certain that connectedCallback was called before a component
5730
+ // was removed from the VDOM. If the component is disconnected, then connectedCallback will not fire
5731
+ // in native mode, although it will fire in synthetic mode due to appendChild triggering it.
5732
+ // See: W-14037619 for details
5733
+ assert.isTrue(vm.state === 1 /* VMState.connected */ || vm.state === 2 /* VMState.disconnected */, `${vm} must have been connected.`);
5734
+ }
5419
5735
  }
5420
5736
  resetComponentStateWhenRemoved(vm);
5421
5737
  }
5422
- function getNearestShadowAncestor(vm) {
5423
- let ancestor = vm.owner;
5738
+ function getNearestShadowAncestor(owner) {
5739
+ let ancestor = owner;
5424
5740
  while (!isNull(ancestor) && ancestor.renderMode === 0 /* RenderMode.Light */) {
5425
5741
  ancestor = ancestor.owner;
5426
5742
  }
@@ -5454,6 +5770,9 @@ function createVM(elm, ctor, renderer, options) {
5454
5770
  stylesheetToken: undefined,
5455
5771
  hasTokenInClass: undefined,
5456
5772
  hasTokenInAttribute: undefined,
5773
+ legacyStylesheetToken: undefined,
5774
+ hasLegacyTokenInClass: undefined,
5775
+ hasLegacyTokenInAttribute: undefined,
5457
5776
  hasScopedStyles: undefined,
5458
5777
  styleVNodes: null,
5459
5778
  tplCache: EmptyObject,
@@ -5478,15 +5797,12 @@ function createVM(elm, ctor, renderer, options) {
5478
5797
  vm.debugInfo = create(null);
5479
5798
  }
5480
5799
  vm.stylesheets = computeStylesheets(vm, def.ctor);
5481
- vm.shadowMode = computeShadowMode(vm, renderer);
5800
+ vm.shadowMode = computeShadowMode(def, vm.owner, renderer);
5482
5801
  vm.tro = getTemplateReactiveObserver(vm);
5483
5802
  if (process.env.NODE_ENV !== 'production') {
5484
5803
  vm.toString = () => {
5485
5804
  return `[object:vm ${def.name} (${vm.idx})]`;
5486
5805
  };
5487
- if (lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5488
- vm.shadowMode = 0 /* ShadowMode.Native */;
5489
- }
5490
5806
  }
5491
5807
  // Create component instance associated to the vm and the element.
5492
5808
  invokeComponentConstructor(vm, def.ctor);
@@ -5549,8 +5865,21 @@ function warnOnStylesheetsMutation(ctor) {
5549
5865
  });
5550
5866
  }
5551
5867
  }
5552
- function computeShadowMode(vm, renderer) {
5553
- const { def } = vm;
5868
+ // Compute the shadowMode/renderMode without creating a VM. This is used in some scenarios like hydration.
5869
+ function computeShadowAndRenderMode(Ctor, renderer) {
5870
+ const def = getComponentInternalDef(Ctor);
5871
+ const { renderMode } = def;
5872
+ // Assume null `owner` - this is what happens in hydration cases anyway
5873
+ const shadowMode = computeShadowMode(def, /* owner */ null, renderer);
5874
+ return { renderMode, shadowMode };
5875
+ }
5876
+ function computeShadowMode(def, owner, renderer) {
5877
+ // Force the shadow mode to always be native. Used for running tests with synthetic shadow patches
5878
+ // on, but components running in actual native shadow mode
5879
+ if (process.env.NODE_ENV !== 'production' &&
5880
+ lwcRuntimeFlags.ENABLE_FORCE_NATIVE_SHADOW_MODE_FOR_TEST) {
5881
+ return 0 /* ShadowMode.Native */;
5882
+ }
5554
5883
  const { isSyntheticShadowDefined } = renderer;
5555
5884
  let shadowMode;
5556
5885
  if (isSyntheticShadowDefined) {
@@ -5559,12 +5888,14 @@ function computeShadowMode(vm, renderer) {
5559
5888
  // everything defaults to native when the synthetic shadow polyfill is unavailable.
5560
5889
  shadowMode = 0 /* ShadowMode.Native */;
5561
5890
  }
5562
- else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE) {
5563
- if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */) {
5891
+ else if (lwcRuntimeFlags.ENABLE_MIXED_SHADOW_MODE ||
5892
+ def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
5893
+ if (def.shadowSupportMode === "any" /* ShadowSupportMode.Any */ ||
5894
+ def.shadowSupportMode === "native" /* ShadowSupportMode.Native */) {
5564
5895
  shadowMode = 0 /* ShadowMode.Native */;
5565
5896
  }
5566
5897
  else {
5567
- const shadowAncestor = getNearestShadowAncestor(vm);
5898
+ const shadowAncestor = getNearestShadowAncestor(owner);
5568
5899
  if (!isNull(shadowAncestor) && shadowAncestor.shadowMode === 0 /* ShadowMode.Native */) {
5569
5900
  // Transitive support for native Shadow DOM. A component in native mode
5570
5901
  // transitively opts all of its descendants into native.
@@ -5619,6 +5950,8 @@ function rehydrate(vm) {
5619
5950
  }
5620
5951
  function patchShadowRoot(vm, newCh) {
5621
5952
  const { renderRoot, children: oldCh, renderer } = vm;
5953
+ // reset the refs; they will be set during `patchChildren`
5954
+ resetRefVNodes(vm);
5622
5955
  // caching the new children collection
5623
5956
  vm.children = newCh;
5624
5957
  if (newCh.length > 0 || oldCh.length > 0) {
@@ -5650,10 +5983,6 @@ function runRenderedCallback(vm) {
5650
5983
  if (!process.env.IS_BROWSER) {
5651
5984
  return;
5652
5985
  }
5653
- const { rendered } = Services;
5654
- if (rendered) {
5655
- invokeServiceHook(vm, rendered);
5656
- }
5657
5986
  if (!isUndefined$1(renderedCallback)) {
5658
5987
  logOperationStart(4 /* OperationId.RenderedCallback */, vm);
5659
5988
  invokeComponentCallback(vm, renderedCallback);
@@ -5696,11 +6025,6 @@ function runConnectedCallback(vm) {
5696
6025
  return; // nothing to do since it was already connected
5697
6026
  }
5698
6027
  vm.state = 1 /* VMState.connected */;
5699
- // reporting connection
5700
- const { connected } = Services;
5701
- if (connected) {
5702
- invokeServiceHook(vm, connected);
5703
- }
5704
6028
  if (hasWireAdapters(vm)) {
5705
6029
  connectWireAdapters(vm);
5706
6030
  }
@@ -5726,11 +6050,6 @@ function runDisconnectedCallback(vm) {
5726
6050
  vm.isDirty = true;
5727
6051
  }
5728
6052
  vm.state = 2 /* VMState.disconnected */;
5729
- // reporting disconnection
5730
- const { disconnected } = Services;
5731
- if (disconnected) {
5732
- invokeServiceHook(vm, disconnected);
5733
- }
5734
6053
  if (hasWireAdapters(vm)) {
5735
6054
  disconnectWireAdapters(vm);
5736
6055
  }
@@ -5855,7 +6174,12 @@ function runWithBoundaryProtection(vm, owner, pre, job, post) {
5855
6174
  if (!isUndefined$1(error)) {
5856
6175
  addErrorComponentStack(vm, error);
5857
6176
  const errorBoundaryVm = isNull(owner) ? undefined : getErrorBoundaryVM(owner);
5858
- if (isUndefined$1(errorBoundaryVm)) {
6177
+ // Error boundaries are not in effect when server-side rendering. `errorCallback`
6178
+ // is intended to allow recovery from errors - changing the state of a component
6179
+ // and instigating a re-render. That is at odds with the single-pass, synchronous
6180
+ // nature of SSR. For that reason, all errors bubble up to the `renderComponent`
6181
+ // call site.
6182
+ if (!process.env.IS_BROWSER || isUndefined$1(errorBoundaryVm)) {
5859
6183
  throw error; // eslint-disable-line no-unsafe-finally
5860
6184
  }
5861
6185
  resetComponentRoot(vm); // remove offenders
@@ -5883,6 +6207,52 @@ function forceRehydration(vm) {
5883
6207
  scheduleRehydration(vm);
5884
6208
  }
5885
6209
  }
6210
+ function runFormAssociatedCustomElementCallback(vm, faceCb) {
6211
+ const { renderMode, shadowMode, def: { formAssociated }, } = vm;
6212
+ // Technically the UpgradableConstructor always sets `static formAssociated = true` but silently fail here to match browser behavior.
6213
+ if (isUndefined$1(formAssociated) || isFalse(formAssociated)) {
6214
+ if (process.env.NODE_ENV !== 'production') {
6215
+ logWarn(`Form associated lifecycle methods must have the 'static formAssociated' value set in the component's prototype chain.`);
6216
+ }
6217
+ return;
6218
+ }
6219
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
6220
+ throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
6221
+ }
6222
+ invokeComponentCallback(vm, faceCb);
6223
+ }
6224
+ function runFormAssociatedCallback(elm) {
6225
+ const vm = getAssociatedVM(elm);
6226
+ const { formAssociatedCallback } = vm.def;
6227
+ if (!isUndefined$1(formAssociatedCallback)) {
6228
+ runFormAssociatedCustomElementCallback(vm, formAssociatedCallback);
6229
+ }
6230
+ }
6231
+ function runFormDisabledCallback(elm) {
6232
+ const vm = getAssociatedVM(elm);
6233
+ const { formDisabledCallback } = vm.def;
6234
+ if (!isUndefined$1(formDisabledCallback)) {
6235
+ runFormAssociatedCustomElementCallback(vm, formDisabledCallback);
6236
+ }
6237
+ }
6238
+ function runFormResetCallback(elm) {
6239
+ const vm = getAssociatedVM(elm);
6240
+ const { formResetCallback } = vm.def;
6241
+ if (!isUndefined$1(formResetCallback)) {
6242
+ runFormAssociatedCustomElementCallback(vm, formResetCallback);
6243
+ }
6244
+ }
6245
+ function runFormStateRestoreCallback(elm) {
6246
+ const vm = getAssociatedVM(elm);
6247
+ const { formStateRestoreCallback } = vm.def;
6248
+ if (!isUndefined$1(formStateRestoreCallback)) {
6249
+ runFormAssociatedCustomElementCallback(vm, formStateRestoreCallback);
6250
+ }
6251
+ }
6252
+ function resetRefVNodes(vm) {
6253
+ const { cmpTemplate } = vm;
6254
+ vm.refVNodes = !isNull(cmpTemplate) && cmpTemplate.hasRefs ? create(null) : null;
6255
+ }
5886
6256
 
5887
6257
  /*
5888
6258
  * Copyright (c) 2018, salesforce.com, inc.
@@ -6057,6 +6427,12 @@ const NON_STANDARD_ARIA_PROPS = [
6057
6427
  'ariaLabelledBy',
6058
6428
  'ariaOwns',
6059
6429
  ];
6430
+ function isGlobalAriaPolyfillLoaded() {
6431
+ // Sniff for the legacy polyfill being loaded. The reason this works is because ariaActiveDescendant is a
6432
+ // non-standard ARIA property reflection that is only supported in our legacy polyfill. See
6433
+ // @lwc/aria-reflection/README.md for details.
6434
+ return !isUndefined$1(getOwnPropertyDescriptor$1(Element.prototype, 'ariaActiveDescendant'));
6435
+ }
6060
6436
  function findVM(elm) {
6061
6437
  // If it's a shadow DOM component, then it has a host
6062
6438
  const { host } = elm.getRootNode();
@@ -6116,6 +6492,9 @@ function enableDetection() {
6116
6492
  }
6117
6493
  // @ts-ignore
6118
6494
  const { get, set } = descriptor;
6495
+ // It's important for this defineProperty call to happen _after_ ARIA accessors are applied to the
6496
+ // BaseBridgeElement and LightningElement prototypes. Otherwise, we will log/report for access of non-standard
6497
+ // props on these prototypes, which we actually don't want. We only care about access on generic HTMLElements.
6119
6498
  defineProperty(prototype, prop, {
6120
6499
  get() {
6121
6500
  checkAndReportViolation(this, prop, false, undefined);
@@ -6131,16 +6510,14 @@ function enableDetection() {
6131
6510
  }
6132
6511
  }
6133
6512
  // No point in running this code if we're not in a browser, or if the global polyfill is not loaded
6134
- if (process.env.IS_BROWSER) {
6135
- if (lwcRuntimeFlags.ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL) {
6136
- // Always run detection in dev mode, so we can at least print to the console
6137
- if (process.env.NODE_ENV !== 'production') {
6138
- enableDetection();
6139
- }
6140
- else {
6141
- // In prod mode, only enable detection if reporting is enabled
6142
- onReportingEnabled(enableDetection);
6143
- }
6513
+ if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
6514
+ // Always run detection in dev mode, so we can at least print to the console
6515
+ if (process.env.NODE_ENV !== 'production') {
6516
+ enableDetection();
6517
+ }
6518
+ else {
6519
+ // In prod mode, only enable detection if reporting is enabled
6520
+ onReportingEnabled(enableDetection);
6144
6521
  }
6145
6522
  }
6146
6523
 
@@ -6163,6 +6540,8 @@ function hydrateRoot(vm) {
6163
6540
  function hydrateVM(vm) {
6164
6541
  const children = renderComponent(vm);
6165
6542
  vm.children = children;
6543
+ // reset the refs; they will be set during `hydrateChildren`
6544
+ resetRefVNodes(vm);
6166
6545
  const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
6167
6546
  hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
6168
6547
  runRenderedCallback(vm);
@@ -6271,7 +6650,7 @@ function hydrateStaticElement(elm, vnode, renderer) {
6271
6650
  return handleMismatch(elm, vnode, renderer);
6272
6651
  }
6273
6652
  vnode.elm = elm;
6274
- applyEventListeners(vnode, renderer);
6653
+ applyStaticParts(elm, vnode, renderer, true);
6275
6654
  return elm;
6276
6655
  }
6277
6656
  function hydrateFragment(elm, vnode, renderer) {
@@ -6305,7 +6684,7 @@ function hydrateElement(elm, vnode, renderer) {
6305
6684
  }
6306
6685
  }
6307
6686
  }
6308
- patchElementPropsAndAttrs(vnode, renderer);
6687
+ patchElementPropsAndAttrsAndRefs(vnode, renderer);
6309
6688
  if (!isDomManual) {
6310
6689
  const { getFirstChild } = renderer;
6311
6690
  hydrateChildren(getFirstChild(elm), vnode.children, elm, owner);
@@ -6329,6 +6708,8 @@ function hydrateCustomElement(elm, vnode, renderer) {
6329
6708
  return handleMismatch(elm, vnode, renderer);
6330
6709
  }
6331
6710
  const { sel, mode, ctor, owner } = vnode;
6711
+ const { defineCustomElement, getTagName } = renderer;
6712
+ defineCustomElement(StringToLowerCase.call(getTagName(elm)));
6332
6713
  const vm = createVM(elm, ctor, renderer, {
6333
6714
  mode,
6334
6715
  owner,
@@ -6338,7 +6719,7 @@ function hydrateCustomElement(elm, vnode, renderer) {
6338
6719
  vnode.elm = elm;
6339
6720
  vnode.vm = vm;
6340
6721
  allocateChildren(vnode, vm);
6341
- patchElementPropsAndAttrs(vnode, renderer);
6722
+ patchElementPropsAndAttrsAndRefs(vnode, renderer);
6342
6723
  // Insert hook section:
6343
6724
  if (process.env.NODE_ENV !== 'production') {
6344
6725
  assert.isTrue(vm.state === 0 /* VMState.created */, `${vm} cannot be recycled.`);
@@ -6403,9 +6784,11 @@ function handleMismatch(node, vnode, renderer) {
6403
6784
  removeNode(node, parentNode, renderer);
6404
6785
  return vnode.elm;
6405
6786
  }
6406
- function patchElementPropsAndAttrs(vnode, renderer) {
6787
+ function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
6407
6788
  applyEventListeners(vnode, renderer);
6408
6789
  patchProps(null, vnode, renderer);
6790
+ // The `refs` object is blown away in every re-render, so we always need to re-apply them
6791
+ applyRefs(vnode, vnode.owner);
6409
6792
  }
6410
6793
  function hasCorrectNodeType(vnode, node, nodeType, renderer) {
6411
6794
  const { getProperty } = renderer;
@@ -6473,7 +6856,8 @@ function validateClassAttr(vnode, elm, renderer) {
6473
6856
  const { data, owner } = vnode;
6474
6857
  let { className, classMap } = data;
6475
6858
  const { getProperty, getClassList, getAttribute } = renderer;
6476
- const scopedToken = getScopeTokenClass(owner);
6859
+ // we don't care about legacy for hydration. it's a new use case
6860
+ const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
6477
6861
  const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
6478
6862
  // Classnames for scoped CSS are added directly to the DOM during rendering,
6479
6863
  // or to the VDOM on the server in the case of SSR. As such, these classnames
@@ -6788,7 +7172,7 @@ function trackMutations(tmpl) {
6788
7172
  }
6789
7173
  function addLegacyStylesheetTokensShim(tmpl) {
6790
7174
  // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6791
- // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
7175
+ // is accessing the old internal API (backwards compat). Details: W-14210169
6792
7176
  defineProperty(tmpl, 'stylesheetTokens', {
6793
7177
  enumerable: true,
6794
7178
  configurable: true,
@@ -6882,6 +7266,6 @@ function readonly(obj) {
6882
7266
  return getReadOnlyProxy(obj);
6883
7267
  }
6884
7268
 
6885
- export { LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6886
- /** version: 4.0.0-alpha.0 */
7269
+ export { LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, computeShadowAndRenderMode, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, runFormAssociatedCallback, runFormDisabledCallback, runFormResetCallback, runFormStateRestoreCallback, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
7270
+ /** version: 4.0.0 */
6887
7271
  //# sourceMappingURL=index.js.map