@lwc/engine-core 2.14.0 → 2.15.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.
@@ -112,164 +112,6 @@ function flattenStylesheets(stylesheets) {
112
112
  return list;
113
113
  }
114
114
 
115
- //
116
- // Primitives
117
- //
118
- let ssr;
119
- function setSsr(ssrImpl) {
120
- ssr = ssrImpl;
121
- }
122
- let isNativeShadowDefined;
123
- function setIsNativeShadowDefined(isNativeShadowDefinedImpl) {
124
- isNativeShadowDefined = isNativeShadowDefinedImpl;
125
- }
126
- let isSyntheticShadowDefined;
127
- function setIsSyntheticShadowDefined(isSyntheticShadowDefinedImpl) {
128
- isSyntheticShadowDefined = isSyntheticShadowDefinedImpl;
129
- }
130
- let HTMLElementExported;
131
- function setHTMLElement(HTMLElementImpl) {
132
- HTMLElementExported = HTMLElementImpl;
133
- }
134
- function setIsHydrating(isHydratingImpl) {
135
- }
136
- let insert;
137
- function setInsert(insertImpl) {
138
- insert = insertImpl;
139
- }
140
- let remove;
141
- function setRemove(removeImpl) {
142
- remove = removeImpl;
143
- }
144
- let createElement;
145
- function setCreateElement(createElementImpl) {
146
- createElement = createElementImpl;
147
- }
148
- let createText;
149
- function setCreateText(createTextImpl) {
150
- createText = createTextImpl;
151
- }
152
- let createComment;
153
- function setCreateComment(createCommentImpl) {
154
- createComment = createCommentImpl;
155
- }
156
- let nextSibling;
157
- function setNextSibling(nextSiblingImpl) {
158
- nextSibling = nextSiblingImpl;
159
- }
160
- let attachShadow;
161
- function setAttachShadow(attachShadowImpl) {
162
- attachShadow = attachShadowImpl;
163
- }
164
- let getProperty;
165
- function setGetProperty(getPropertyImpl) {
166
- getProperty = getPropertyImpl;
167
- }
168
- let setProperty;
169
- function setSetProperty(setPropertyImpl) {
170
- setProperty = setPropertyImpl;
171
- }
172
- let setText;
173
- function setSetText(setTextImpl) {
174
- setText = setTextImpl;
175
- }
176
- let getAttribute;
177
- function setGetAttribute(getAttributeImpl) {
178
- getAttribute = getAttributeImpl;
179
- }
180
- let setAttribute;
181
- function setSetAttribute(setAttributeImpl) {
182
- setAttribute = setAttributeImpl;
183
- }
184
- let removeAttribute;
185
- function setRemoveAttribute(removeAttributeImpl) {
186
- removeAttribute = removeAttributeImpl;
187
- }
188
- let addEventListener;
189
- function setAddEventListener(addEventListenerImpl) {
190
- addEventListener = addEventListenerImpl;
191
- }
192
- let removeEventListener;
193
- function setRemoveEventListener(removeEventListenerImpl) {
194
- removeEventListener = removeEventListenerImpl;
195
- }
196
- let dispatchEvent;
197
- function setDispatchEvent(dispatchEventImpl) {
198
- dispatchEvent = dispatchEventImpl;
199
- }
200
- let getClassList;
201
- function setGetClassList(getClassListImpl) {
202
- getClassList = getClassListImpl;
203
- }
204
- let setCSSStyleProperty;
205
- function setSetCSSStyleProperty(setCSSStylePropertyImpl) {
206
- setCSSStyleProperty = setCSSStylePropertyImpl;
207
- }
208
- let getBoundingClientRect;
209
- function setGetBoundingClientRect(getBoundingClientRectImpl) {
210
- getBoundingClientRect = getBoundingClientRectImpl;
211
- }
212
- let querySelector;
213
- function setQuerySelector(querySelectorImpl) {
214
- querySelector = querySelectorImpl;
215
- }
216
- let querySelectorAll;
217
- function setQuerySelectorAll(querySelectorAllImpl) {
218
- querySelectorAll = querySelectorAllImpl;
219
- }
220
- let getElementsByTagName;
221
- function setGetElementsByTagName(getElementsByTagNameImpl) {
222
- getElementsByTagName = getElementsByTagNameImpl;
223
- }
224
- let getElementsByClassName;
225
- function setGetElementsByClassName(getElementsByClassNameImpl) {
226
- getElementsByClassName = getElementsByClassNameImpl;
227
- }
228
- let getChildren;
229
- function setGetChildren(getChildrenImpl) {
230
- getChildren = getChildrenImpl;
231
- }
232
- let getChildNodes;
233
- function setGetChildNodes(getChildNodesImpl) {
234
- getChildNodes = getChildNodesImpl;
235
- }
236
- let getFirstChild;
237
- function setGetFirstChild(getFirstChildImpl) {
238
- getFirstChild = getFirstChildImpl;
239
- }
240
- let getFirstElementChild;
241
- function setGetFirstElementChild(getFirstElementChildImpl) {
242
- getFirstElementChild = getFirstElementChildImpl;
243
- }
244
- let getLastChild;
245
- function setGetLastChild(getLastChildImpl) {
246
- getLastChild = getLastChildImpl;
247
- }
248
- let getLastElementChild;
249
- function setGetLastElementChild(getLastElementChildImpl) {
250
- getLastElementChild = getLastElementChildImpl;
251
- }
252
- let isConnected;
253
- function setIsConnected(isConnectedImpl) {
254
- isConnected = isConnectedImpl;
255
- }
256
- let insertStylesheet;
257
- function setInsertStylesheet(insertStylesheetImpl) {
258
- insertStylesheet = insertStylesheetImpl;
259
- }
260
- let assertInstanceOfHTMLElement;
261
- function setAssertInstanceOfHTMLElement(assertInstanceOfHTMLElementImpl) {
262
- assertInstanceOfHTMLElement = assertInstanceOfHTMLElementImpl;
263
- }
264
- let defineCustomElement;
265
- function setDefineCustomElement(defineCustomElementImpl) {
266
- defineCustomElement = defineCustomElementImpl;
267
- }
268
- let getCustomElement;
269
- function setGetCustomElement(getCustomElementImpl) {
270
- getCustomElement = getCustomElementImpl;
271
- }
272
-
273
115
  /*
274
116
  * Copyright (c) 2019, salesforce.com, inc.
275
117
  * All rights reserved.
@@ -1574,6 +1416,7 @@ const LightningElement = function () {
1574
1416
  const { def, elm } = vm;
1575
1417
  const { bridge } = def;
1576
1418
  if (process.env.NODE_ENV !== 'production') {
1419
+ const { assertInstanceOfHTMLElement } = vm.renderer;
1577
1420
  assertInstanceOfHTMLElement(vm.elm, `Component creation requires a DOM element to be associated to ${vm}.`);
1578
1421
  }
1579
1422
  const component = this;
@@ -1608,7 +1451,7 @@ const LightningElement = function () {
1608
1451
  return this;
1609
1452
  };
1610
1453
  function doAttachShadow(vm) {
1611
- const { elm, mode, shadowMode, def: { ctor }, } = vm;
1454
+ const { elm, mode, shadowMode, def: { ctor }, renderer: { attachShadow }, } = vm;
1612
1455
  const shadowRoot = attachShadow(elm, {
1613
1456
  [shared.KEY__SYNTHETIC_MODE]: shadowMode === 1 /* Synthetic */,
1614
1457
  delegatesFocus: Boolean(ctor.delegatesFocus),
@@ -1630,12 +1473,13 @@ function warnIfInvokedDuringConstruction(vm, methodOrPropName) {
1630
1473
  LightningElement.prototype = {
1631
1474
  constructor: LightningElement,
1632
1475
  dispatchEvent(event) {
1633
- const { elm } = getAssociatedVM(this);
1476
+ const vm = getAssociatedVM(this);
1477
+ const { elm, renderer: { dispatchEvent }, } = vm;
1634
1478
  return dispatchEvent(elm, event);
1635
1479
  },
1636
1480
  addEventListener(type, listener, options) {
1637
1481
  const vm = getAssociatedVM(this);
1638
- const { elm } = vm;
1482
+ const { elm, renderer: { addEventListener }, } = vm;
1639
1483
  if (process.env.NODE_ENV !== 'production') {
1640
1484
  const vmBeingRendered = getVMBeingRendered();
1641
1485
  shared.assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm} by adding an event listener for "${type}".`);
@@ -1647,41 +1491,48 @@ LightningElement.prototype = {
1647
1491
  },
1648
1492
  removeEventListener(type, listener, options) {
1649
1493
  const vm = getAssociatedVM(this);
1650
- const { elm } = vm;
1494
+ const { elm, renderer: { removeEventListener }, } = vm;
1651
1495
  const wrappedListener = getWrappedComponentsListener(vm, listener);
1652
1496
  removeEventListener(elm, type, wrappedListener, options);
1653
1497
  },
1654
1498
  hasAttribute(name) {
1655
- const { elm } = getAssociatedVM(this);
1499
+ const vm = getAssociatedVM(this);
1500
+ const { elm, renderer: { getAttribute }, } = vm;
1656
1501
  return !shared.isNull(getAttribute(elm, name));
1657
1502
  },
1658
1503
  hasAttributeNS(namespace, name) {
1659
- const { elm } = getAssociatedVM(this);
1504
+ const vm = getAssociatedVM(this);
1505
+ const { elm, renderer: { getAttribute }, } = vm;
1660
1506
  return !shared.isNull(getAttribute(elm, name, namespace));
1661
1507
  },
1662
1508
  removeAttribute(name) {
1663
- const { elm } = getAssociatedVM(this);
1509
+ const vm = getAssociatedVM(this);
1510
+ const { elm, renderer: { removeAttribute }, } = vm;
1664
1511
  unlockAttribute(elm, name);
1665
1512
  removeAttribute(elm, name);
1666
1513
  lockAttribute();
1667
1514
  },
1668
1515
  removeAttributeNS(namespace, name) {
1669
- const { elm } = getAssociatedVM(this);
1516
+ const { elm, renderer: { removeAttribute }, } = getAssociatedVM(this);
1670
1517
  unlockAttribute(elm, name);
1671
1518
  removeAttribute(elm, name, namespace);
1672
1519
  lockAttribute();
1673
1520
  },
1674
1521
  getAttribute(name) {
1675
- const { elm } = getAssociatedVM(this);
1522
+ const vm = getAssociatedVM(this);
1523
+ const { elm } = vm;
1524
+ const { getAttribute } = vm.renderer;
1676
1525
  return getAttribute(elm, name);
1677
1526
  },
1678
1527
  getAttributeNS(namespace, name) {
1679
- const { elm } = getAssociatedVM(this);
1528
+ const vm = getAssociatedVM(this);
1529
+ const { elm } = vm;
1530
+ const { getAttribute } = vm.renderer;
1680
1531
  return getAttribute(elm, name, namespace);
1681
1532
  },
1682
1533
  setAttribute(name, value) {
1683
1534
  const vm = getAssociatedVM(this);
1684
- const { elm } = vm;
1535
+ const { elm, renderer: { setAttribute }, } = vm;
1685
1536
  if (process.env.NODE_ENV !== 'production') {
1686
1537
  shared.assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1687
1538
  }
@@ -1691,7 +1542,7 @@ LightningElement.prototype = {
1691
1542
  },
1692
1543
  setAttributeNS(namespace, name, value) {
1693
1544
  const vm = getAssociatedVM(this);
1694
- const { elm } = vm;
1545
+ const { elm, renderer: { setAttribute }, } = vm;
1695
1546
  if (process.env.NODE_ENV !== 'production') {
1696
1547
  shared.assert.isFalse(isBeingConstructed(vm), `Failed to construct '${getComponentTag(vm)}': The result must not have attributes.`);
1697
1548
  }
@@ -1701,19 +1552,20 @@ LightningElement.prototype = {
1701
1552
  },
1702
1553
  getBoundingClientRect() {
1703
1554
  const vm = getAssociatedVM(this);
1704
- const { elm } = vm;
1555
+ const { elm, renderer: { getBoundingClientRect }, } = vm;
1705
1556
  if (process.env.NODE_ENV !== 'production') {
1706
1557
  warnIfInvokedDuringConstruction(vm, 'getBoundingClientRect()');
1707
1558
  }
1708
1559
  return getBoundingClientRect(elm);
1709
1560
  },
1710
1561
  get isConnected() {
1711
- const { elm } = getAssociatedVM(this);
1562
+ const vm = getAssociatedVM(this);
1563
+ const { elm, renderer: { isConnected }, } = vm;
1712
1564
  return isConnected(elm);
1713
1565
  },
1714
1566
  get classList() {
1715
1567
  const vm = getAssociatedVM(this);
1716
- const { elm } = vm;
1568
+ const { elm, renderer: { getClassList }, } = vm;
1717
1569
  if (process.env.NODE_ENV !== 'production') {
1718
1570
  // TODO [#1290]: this still fails in dev but works in production, eventually, we should
1719
1571
  // just throw in all modes
@@ -1735,6 +1587,54 @@ LightningElement.prototype = {
1735
1587
  // Authors should rely on this.template instead.
1736
1588
  return null;
1737
1589
  },
1590
+ get children() {
1591
+ const vm = getAssociatedVM(this);
1592
+ const renderer = vm.renderer;
1593
+ if (process.env.NODE_ENV !== 'production') {
1594
+ warnIfInvokedDuringConstruction(vm, 'children');
1595
+ }
1596
+ return renderer.getChildren(vm.elm);
1597
+ },
1598
+ get childNodes() {
1599
+ const vm = getAssociatedVM(this);
1600
+ const renderer = vm.renderer;
1601
+ if (process.env.NODE_ENV !== 'production') {
1602
+ warnIfInvokedDuringConstruction(vm, 'childNodes');
1603
+ }
1604
+ return renderer.getChildNodes(vm.elm);
1605
+ },
1606
+ get firstChild() {
1607
+ const vm = getAssociatedVM(this);
1608
+ const renderer = vm.renderer;
1609
+ if (process.env.NODE_ENV !== 'production') {
1610
+ warnIfInvokedDuringConstruction(vm, 'firstChild');
1611
+ }
1612
+ return renderer.getFirstChild(vm.elm);
1613
+ },
1614
+ get firstElementChild() {
1615
+ const vm = getAssociatedVM(this);
1616
+ const renderer = vm.renderer;
1617
+ if (process.env.NODE_ENV !== 'production') {
1618
+ warnIfInvokedDuringConstruction(vm, 'firstElementChild');
1619
+ }
1620
+ return renderer.getFirstElementChild(vm.elm);
1621
+ },
1622
+ get lastChild() {
1623
+ const vm = getAssociatedVM(this);
1624
+ const renderer = vm.renderer;
1625
+ if (process.env.NODE_ENV !== 'production') {
1626
+ warnIfInvokedDuringConstruction(vm, 'lastChild');
1627
+ }
1628
+ return renderer.getLastChild(vm.elm);
1629
+ },
1630
+ get lastElementChild() {
1631
+ const vm = getAssociatedVM(this);
1632
+ const renderer = vm.renderer;
1633
+ if (process.env.NODE_ENV !== 'production') {
1634
+ warnIfInvokedDuringConstruction(vm, 'lastElementChild');
1635
+ }
1636
+ return renderer.getLastElementChild(vm.elm);
1637
+ },
1738
1638
  render() {
1739
1639
  const vm = getAssociatedVM(this);
1740
1640
  return vm.def.template;
@@ -1745,76 +1645,22 @@ LightningElement.prototype = {
1745
1645
  },
1746
1646
  };
1747
1647
  const queryAndChildGetterDescriptors = shared.create(null);
1748
- // The reason we don't just call `import * as renderer from '../renderer'` here is that the bundle size
1749
- // is smaller if we reference each function individually. Otherwise Rollup will create one big frozen
1750
- // object representing the renderer, with a lot of methods we don't actually need.
1751
- const childGetters = [
1752
- 'children',
1753
- 'childNodes',
1754
- 'firstChild',
1755
- 'firstElementChild',
1756
- 'lastChild',
1757
- 'lastElementChild',
1758
- ];
1759
- function getChildGetter(methodName) {
1760
- switch (methodName) {
1761
- case 'children':
1762
- return getChildren;
1763
- case 'childNodes':
1764
- return getChildNodes;
1765
- case 'firstChild':
1766
- return getFirstChild;
1767
- case 'firstElementChild':
1768
- return getFirstElementChild;
1769
- case 'lastChild':
1770
- return getLastChild;
1771
- case 'lastElementChild':
1772
- return getLastElementChild;
1773
- }
1774
- }
1775
- // Generic passthrough for child getters on HTMLElement to the relevant Renderer APIs
1776
- for (const childGetter of childGetters) {
1777
- queryAndChildGetterDescriptors[childGetter] = {
1778
- get() {
1779
- const vm = getAssociatedVM(this);
1780
- const { elm } = vm;
1781
- if (process.env.NODE_ENV !== 'production') {
1782
- warnIfInvokedDuringConstruction(vm, childGetter);
1783
- }
1784
- return getChildGetter(childGetter)(elm);
1785
- },
1786
- configurable: true,
1787
- enumerable: true,
1788
- };
1789
- }
1790
1648
  const queryMethods = [
1791
1649
  'getElementsByClassName',
1792
1650
  'getElementsByTagName',
1793
1651
  'querySelector',
1794
1652
  'querySelectorAll',
1795
1653
  ];
1796
- function getQueryMethod(methodName) {
1797
- switch (methodName) {
1798
- case 'getElementsByClassName':
1799
- return getElementsByClassName;
1800
- case 'getElementsByTagName':
1801
- return getElementsByTagName;
1802
- case 'querySelector':
1803
- return querySelector;
1804
- case 'querySelectorAll':
1805
- return querySelectorAll;
1806
- }
1807
- }
1808
1654
  // Generic passthrough for query APIs on HTMLElement to the relevant Renderer APIs
1809
1655
  for (const queryMethod of queryMethods) {
1810
1656
  queryAndChildGetterDescriptors[queryMethod] = {
1811
1657
  value(arg) {
1812
1658
  const vm = getAssociatedVM(this);
1813
- const { elm } = vm;
1659
+ const { elm, renderer } = vm;
1814
1660
  if (process.env.NODE_ENV !== 'production') {
1815
1661
  warnIfInvokedDuringConstruction(vm, `${queryMethod}()`);
1816
1662
  }
1817
- return getQueryMethod(queryMethod)(elm, arg);
1663
+ return renderer[queryMethod](elm, arg);
1818
1664
  },
1819
1665
  configurable: true,
1820
1666
  enumerable: true,
@@ -2319,7 +2165,8 @@ function getDecoratorsMeta(Ctor) {
2319
2165
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2320
2166
  */
2321
2167
  let warned = false;
2322
- if (process.env.NODE_ENV === 'development') {
2168
+ // @ts-ignore
2169
+ if (process.env.NODE_ENV !== 'production' && typeof __karma__ !== 'undefined') {
2323
2170
  // @ts-ignore
2324
2171
  window.__lwcResetWarnedOnVersionMismatch = () => {
2325
2172
  warned = false;
@@ -3037,7 +2884,8 @@ function getComponentDef(Ctor) {
3037
2884
  * SPDX-License-Identifier: MIT
3038
2885
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3039
2886
  */
3040
- function getUpgradableConstructor(tagName) {
2887
+ function getUpgradableConstructor(tagName, renderer) {
2888
+ const { getCustomElement, HTMLElementExported: RendererHTMLElement, defineCustomElement, } = renderer;
3041
2889
  // Should never get a tag with upper case letter at this point, the compiler should
3042
2890
  // produce only tags with lowercase letters
3043
2891
  // But, for backwards compatibility, we will lower case the tagName
@@ -3050,7 +2898,7 @@ function getUpgradableConstructor(tagName) {
3050
2898
  * LWC Upgradable Element reference to an element that was created
3051
2899
  * via the scoped registry mechanism, and that is ready to be upgraded.
3052
2900
  */
3053
- CE = class LWCUpgradableElement extends HTMLElementExported {
2901
+ CE = class LWCUpgradableElement extends RendererHTMLElement {
3054
2902
  constructor(upgradeCallback) {
3055
2903
  super();
3056
2904
  if (shared.isFunction(upgradeCallback)) {
@@ -3083,7 +2931,7 @@ function isSameVnode(vnode1, vnode2) {
3083
2931
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3084
2932
  */
3085
2933
  const ColonCharCode = 58;
3086
- function patchAttributes(oldVnode, vnode) {
2934
+ function patchAttributes(oldVnode, vnode, renderer) {
3087
2935
  const { attrs } = vnode.data;
3088
2936
  if (shared.isUndefined(attrs)) {
3089
2937
  return;
@@ -3093,6 +2941,7 @@ function patchAttributes(oldVnode, vnode) {
3093
2941
  return;
3094
2942
  }
3095
2943
  const { elm } = vnode;
2944
+ const { setAttribute, removeAttribute } = renderer;
3096
2945
  for (const key in attrs) {
3097
2946
  const cur = attrs[key];
3098
2947
  const old = oldAttrs[key];
@@ -3128,7 +2977,7 @@ function isLiveBindingProp(sel, key) {
3128
2977
  // instead of relying on internally tracked values.
3129
2978
  return sel === 'input' && (key === 'value' || key === 'checked');
3130
2979
  }
3131
- function patchProps(oldVnode, vnode) {
2980
+ function patchProps(oldVnode, vnode, renderer) {
3132
2981
  const { props } = vnode.data;
3133
2982
  if (shared.isUndefined(props)) {
3134
2983
  return;
@@ -3139,6 +2988,7 @@ function patchProps(oldVnode, vnode) {
3139
2988
  }
3140
2989
  const isFirstPatch = shared.isNull(oldVnode);
3141
2990
  const { elm, sel } = vnode;
2991
+ const { getProperty, setProperty } = renderer;
3142
2992
  for (const key in props) {
3143
2993
  const cur = props[key];
3144
2994
  // Set the property if it's the first time is is patched or if the previous property is
@@ -3190,12 +3040,13 @@ function getMapFromClassName(className) {
3190
3040
  }
3191
3041
  return map;
3192
3042
  }
3193
- function patchClassAttribute(oldVnode, vnode) {
3043
+ function patchClassAttribute(oldVnode, vnode, renderer) {
3194
3044
  const { elm, data: { className: newClass }, } = vnode;
3195
3045
  const oldClass = shared.isNull(oldVnode) ? undefined : oldVnode.data.className;
3196
3046
  if (oldClass === newClass) {
3197
3047
  return;
3198
3048
  }
3049
+ const { getClassList } = renderer;
3199
3050
  const classList = getClassList(elm);
3200
3051
  const newClassMap = getMapFromClassName(newClass);
3201
3052
  const oldClassMap = getMapFromClassName(oldClass);
@@ -3220,12 +3071,13 @@ function patchClassAttribute(oldVnode, vnode) {
3220
3071
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3221
3072
  */
3222
3073
  // The style property is a string when defined via an expression in the template.
3223
- function patchStyleAttribute(oldVnode, vnode) {
3074
+ function patchStyleAttribute(oldVnode, vnode, renderer) {
3224
3075
  const { elm, data: { style: newStyle }, } = vnode;
3225
3076
  const oldStyle = shared.isNull(oldVnode) ? undefined : oldVnode.data.style;
3226
3077
  if (oldStyle === newStyle) {
3227
3078
  return;
3228
3079
  }
3080
+ const { setAttribute, removeAttribute } = renderer;
3229
3081
  if (!shared.isString(newStyle) || newStyle === '') {
3230
3082
  removeAttribute(elm, 'style');
3231
3083
  }
@@ -3240,11 +3092,12 @@ function patchStyleAttribute(oldVnode, vnode) {
3240
3092
  * SPDX-License-Identifier: MIT
3241
3093
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3242
3094
  */
3243
- function applyEventListeners(vnode) {
3095
+ function applyEventListeners(vnode, renderer) {
3244
3096
  const { elm, data: { on }, } = vnode;
3245
3097
  if (shared.isUndefined(on)) {
3246
3098
  return;
3247
3099
  }
3100
+ const { addEventListener } = renderer;
3248
3101
  for (const name in on) {
3249
3102
  const handler = on[name];
3250
3103
  addEventListener(elm, name, handler);
@@ -3260,11 +3113,12 @@ function applyEventListeners(vnode) {
3260
3113
  // The HTML class property becomes the vnode.data.classMap object when defined as a string in the template.
3261
3114
  // The compiler takes care of transforming the inline classnames into an object. It's faster to set the
3262
3115
  // different classnames properties individually instead of via a string.
3263
- function applyStaticClassAttribute(vnode) {
3116
+ function applyStaticClassAttribute(vnode, renderer) {
3264
3117
  const { elm, data: { classMap }, } = vnode;
3265
3118
  if (shared.isUndefined(classMap)) {
3266
3119
  return;
3267
3120
  }
3121
+ const { getClassList } = renderer;
3268
3122
  const classList = getClassList(elm);
3269
3123
  for (const name in classMap) {
3270
3124
  classList.add(name);
@@ -3280,11 +3134,12 @@ function applyStaticClassAttribute(vnode) {
3280
3134
  // The HTML style property becomes the vnode.data.styleDecls object when defined as a string in the template.
3281
3135
  // The compiler takes care of transforming the inline style into an object. It's faster to set the
3282
3136
  // different style properties individually instead of via a string.
3283
- function applyStaticStyleAttribute(vnode) {
3137
+ function applyStaticStyleAttribute(vnode, renderer) {
3284
3138
  const { elm, data: { styleDecls }, } = vnode;
3285
3139
  if (shared.isUndefined(styleDecls)) {
3286
3140
  return;
3287
3141
  }
3142
+ const { setCSSStyleProperty } = renderer;
3288
3143
  for (let i = 0; i < styleDecls.length; i++) {
3289
3144
  const [prop, value, important] = styleDecls[i];
3290
3145
  setCSSStyleProperty(elm, prop, value, important);
@@ -3297,15 +3152,16 @@ function applyStaticStyleAttribute(vnode) {
3297
3152
  * SPDX-License-Identifier: MIT
3298
3153
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
3299
3154
  */
3300
- function patchChildren(c1, c2, parent) {
3155
+ function patchChildren(c1, c2, parent, renderer) {
3301
3156
  if (hasDynamicChildren(c2)) {
3302
- updateDynamicChildren(c1, c2, parent);
3157
+ updateDynamicChildren(c1, c2, parent, renderer);
3303
3158
  }
3304
3159
  else {
3305
- updateStaticChildren(c1, c2, parent);
3160
+ updateStaticChildren(c1, c2, parent, renderer);
3306
3161
  }
3307
3162
  }
3308
- function patch(n1, n2) {
3163
+ function patch(n1, n2, renderer) {
3164
+ var _a, _b;
3309
3165
  if (n1 === n2) {
3310
3166
  return;
3311
3167
  }
@@ -3319,80 +3175,115 @@ function patch(n1, n2) {
3319
3175
  }
3320
3176
  switch (n2.type) {
3321
3177
  case 0 /* Text */:
3322
- patchText(n1, n2);
3178
+ // VText has no special capability, fallback to the owner's renderer
3179
+ patchText(n1, n2, renderer);
3323
3180
  break;
3324
3181
  case 1 /* Comment */:
3325
- patchComment(n1, n2);
3182
+ // VComment has no special capability, fallback to the owner's renderer
3183
+ patchComment(n1, n2, renderer);
3184
+ break;
3185
+ case 4 /* Static */:
3186
+ n2.elm = n1.elm;
3326
3187
  break;
3327
3188
  case 2 /* Element */:
3328
- patchElement(n1, n2);
3189
+ patchElement(n1, n2, (_a = n2.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3329
3190
  break;
3330
3191
  case 3 /* CustomElement */:
3331
- patchCustomElement(n1, n2);
3192
+ patchCustomElement(n1, n2, (_b = n2.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3332
3193
  break;
3333
3194
  }
3334
3195
  }
3335
- function mount(node, parent, anchor) {
3196
+ function mount(node, parent, renderer, anchor) {
3197
+ var _a, _b;
3336
3198
  switch (node.type) {
3337
3199
  case 0 /* Text */:
3338
- mountText(node, parent, anchor);
3200
+ // VText has no special capability, fallback to the owner's renderer
3201
+ mountText(node, parent, anchor, renderer);
3339
3202
  break;
3340
3203
  case 1 /* Comment */:
3341
- mountComment(node, parent, anchor);
3204
+ // VComment has no special capability, fallback to the owner's renderer
3205
+ mountComment(node, parent, anchor, renderer);
3206
+ break;
3207
+ case 4 /* Static */:
3208
+ // VStatic cannot have a custom renderer associated to them, using owner's renderer
3209
+ mountStatic(node, parent, anchor, renderer);
3342
3210
  break;
3343
3211
  case 2 /* Element */:
3344
- mountElement(node, parent, anchor);
3212
+ // If the vnode data has a renderer override use it, else fallback to owner's renderer
3213
+ mountElement(node, parent, anchor, (_a = node.data.renderer) !== null && _a !== void 0 ? _a : renderer);
3345
3214
  break;
3346
3215
  case 3 /* CustomElement */:
3347
- mountCustomElement(node, parent, anchor);
3216
+ // If the vnode data has a renderer override use it, else fallback to owner's renderer
3217
+ mountCustomElement(node, parent, anchor, (_b = node.data.renderer) !== null && _b !== void 0 ? _b : renderer);
3348
3218
  break;
3349
3219
  }
3350
3220
  }
3351
- function patchText(n1, n2) {
3221
+ function patchText(n1, n2, renderer) {
3352
3222
  n2.elm = n1.elm;
3353
3223
  if (n2.text !== n1.text) {
3354
- updateTextContent(n2);
3224
+ updateTextContent(n2, renderer);
3355
3225
  }
3356
3226
  }
3357
- function mountText(node, parent, anchor) {
3358
- const { owner } = node;
3359
- const textNode = (node.elm = createText(node.text));
3360
- linkNodeToShadow(textNode, owner);
3361
- insertNode(textNode, parent, anchor);
3227
+ function mountText(vnode, parent, anchor, renderer) {
3228
+ const { owner } = vnode;
3229
+ const { createText } = renderer;
3230
+ const textNode = (vnode.elm = createText(vnode.text));
3231
+ linkNodeToShadow(textNode, owner, renderer);
3232
+ insertNode(textNode, parent, anchor, renderer);
3362
3233
  }
3363
- function patchComment(n1, n2) {
3234
+ function patchComment(n1, n2, renderer) {
3364
3235
  n2.elm = n1.elm;
3365
3236
  // FIXME: Comment nodes should be static, we shouldn't need to diff them together. However
3366
3237
  // it is the case today.
3367
3238
  if (n2.text !== n1.text) {
3368
- updateTextContent(n2);
3239
+ updateTextContent(n2, renderer);
3369
3240
  }
3370
3241
  }
3371
- function mountComment(node, parent, anchor) {
3372
- const { owner } = node;
3373
- const commentNode = (node.elm = createComment(node.text));
3374
- linkNodeToShadow(commentNode, owner);
3375
- insertNode(commentNode, parent, anchor);
3242
+ function mountComment(vnode, parent, anchor, renderer) {
3243
+ const { owner } = vnode;
3244
+ const { createComment } = renderer;
3245
+ const commentNode = (vnode.elm = createComment(vnode.text));
3246
+ linkNodeToShadow(commentNode, owner, renderer);
3247
+ insertNode(commentNode, parent, anchor, renderer);
3376
3248
  }
3377
- function mountElement(vnode, parent, anchor) {
3249
+ function mountElement(vnode, parent, anchor, renderer) {
3378
3250
  const { sel, owner, data: { svg }, } = vnode;
3251
+ const { createElement } = renderer;
3379
3252
  const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
3380
3253
  const elm = createElement(sel, namespace);
3381
- linkNodeToShadow(elm, owner);
3382
- fallbackElmHook(elm, vnode);
3254
+ linkNodeToShadow(elm, owner, renderer);
3255
+ fallbackElmHook(elm, vnode, renderer);
3383
3256
  vnode.elm = elm;
3384
- patchElementPropsAndAttrs$1(null, vnode);
3385
- insertNode(elm, parent, anchor);
3386
- mountVNodes(vnode.children, elm, null);
3257
+ patchElementPropsAndAttrs$1(null, vnode, renderer);
3258
+ insertNode(elm, parent, anchor, renderer);
3259
+ mountVNodes(vnode.children, elm, renderer, null);
3387
3260
  }
3388
- function patchElement(n1, n2) {
3261
+ function patchElement(n1, n2, renderer) {
3389
3262
  const elm = (n2.elm = n1.elm);
3390
- patchElementPropsAndAttrs$1(n1, n2);
3391
- patchChildren(n1.children, n2.children, elm);
3263
+ patchElementPropsAndAttrs$1(n1, n2, renderer);
3264
+ patchChildren(n1.children, n2.children, elm, renderer);
3265
+ }
3266
+ function mountStatic(vnode, parent, anchor, renderer) {
3267
+ const { owner } = vnode;
3268
+ const { cloneNode, isSyntheticShadowDefined } = renderer;
3269
+ const elm = (vnode.elm = cloneNode(vnode.fragment, true));
3270
+ linkNodeToShadow(elm, owner, renderer);
3271
+ // Marks this node as Static to propagate the shadow resolver. must happen after elm is assigned to the proper shadow
3272
+ const { renderMode, shadowMode } = owner;
3273
+ if (isSyntheticShadowDefined) {
3274
+ if (shadowMode === 1 /* Synthetic */ || renderMode === 0 /* Light */) {
3275
+ elm[shared.KEY__SHADOW_STATIC] = true;
3276
+ }
3277
+ }
3278
+ if (process.env.NODE_ENV !== 'production') {
3279
+ const isLight = renderMode === 0 /* Light */;
3280
+ patchElementWithRestrictions(elm, { isPortal: false, isLight });
3281
+ }
3282
+ insertNode(elm, parent, anchor, renderer);
3392
3283
  }
3393
- function mountCustomElement(vnode, parent, anchor) {
3284
+ function mountCustomElement(vnode, parent, anchor, renderer) {
3394
3285
  const { sel, owner } = vnode;
3395
- const UpgradableConstructor = getUpgradableConstructor(sel);
3286
+ const UpgradableConstructor = getUpgradableConstructor(sel, renderer);
3396
3287
  /**
3397
3288
  * Note: if the upgradable constructor does not expect, or throw when we new it
3398
3289
  * with a callback as the first argument, we could implement a more advanced
@@ -3402,9 +3293,9 @@ function mountCustomElement(vnode, parent, anchor) {
3402
3293
  let vm;
3403
3294
  const elm = new UpgradableConstructor((elm) => {
3404
3295
  // the custom element from the registry is expecting an upgrade callback
3405
- vm = createViewModelHook(elm, vnode);
3296
+ vm = createViewModelHook(elm, vnode, renderer);
3406
3297
  });
3407
- linkNodeToShadow(elm, owner);
3298
+ linkNodeToShadow(elm, owner, renderer);
3408
3299
  vnode.elm = elm;
3409
3300
  vnode.vm = vm;
3410
3301
  if (vm) {
@@ -3413,23 +3304,23 @@ function mountCustomElement(vnode, parent, anchor) {
3413
3304
  else if (vnode.ctor !== UpgradableConstructor) {
3414
3305
  throw new TypeError(`Incorrect Component Constructor`);
3415
3306
  }
3416
- patchElementPropsAndAttrs$1(null, vnode);
3417
- insertNode(elm, parent, anchor);
3307
+ patchElementPropsAndAttrs$1(null, vnode, renderer);
3308
+ insertNode(elm, parent, anchor, renderer);
3418
3309
  if (vm) {
3419
3310
  if (process.env.NODE_ENV !== 'production') {
3420
3311
  shared.assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
3421
3312
  }
3422
3313
  runConnectedCallback(vm);
3423
3314
  }
3424
- mountVNodes(vnode.children, elm, null);
3315
+ mountVNodes(vnode.children, elm, renderer, null);
3425
3316
  if (vm) {
3426
3317
  appendVM(vm);
3427
3318
  }
3428
3319
  }
3429
- function patchCustomElement(n1, n2) {
3320
+ function patchCustomElement(n1, n2, renderer) {
3430
3321
  const elm = (n2.elm = n1.elm);
3431
3322
  const vm = (n2.vm = n1.vm);
3432
- patchElementPropsAndAttrs$1(n1, n2);
3323
+ patchElementPropsAndAttrs$1(n1, n2, renderer);
3433
3324
  if (!shared.isUndefined(vm)) {
3434
3325
  // in fallback mode, the allocation will always set children to
3435
3326
  // empty and delegate the real allocation to the slot elements
@@ -3437,33 +3328,38 @@ function patchCustomElement(n1, n2) {
3437
3328
  }
3438
3329
  // in fallback mode, the children will be always empty, so, nothing
3439
3330
  // will happen, but in native, it does allocate the light dom
3440
- patchChildren(n1.children, n2.children, elm);
3331
+ patchChildren(n1.children, n2.children, elm, renderer);
3441
3332
  if (!shared.isUndefined(vm)) {
3442
3333
  // this will probably update the shadowRoot, but only if the vm is in a dirty state
3443
3334
  // this is important to preserve the top to bottom synchronous rendering phase.
3444
3335
  rerenderVM(vm);
3445
3336
  }
3446
3337
  }
3447
- function mountVNodes(vnodes, parent, anchor, start = 0, end = vnodes.length) {
3338
+ function mountVNodes(vnodes, parent, renderer, anchor, start = 0, end = vnodes.length) {
3448
3339
  for (; start < end; ++start) {
3449
3340
  const vnode = vnodes[start];
3450
3341
  if (isVNode(vnode)) {
3451
- mount(vnode, parent, anchor);
3342
+ mount(vnode, parent, renderer, anchor);
3452
3343
  }
3453
3344
  }
3454
3345
  }
3455
- function unmount(vnode, parent, doRemove = false) {
3346
+ function unmount(vnode, parent, renderer, doRemove = false) {
3456
3347
  const { type, elm, sel } = vnode;
3457
3348
  // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
3458
3349
  // subtree root, is the only element worth unmounting from the subtree.
3459
3350
  if (doRemove) {
3460
- removeNode(elm, parent);
3351
+ // The vnode might or might not have a data.renderer associated to it
3352
+ // but the removal used here is from the owner instead.
3353
+ removeNode(elm, parent, renderer);
3461
3354
  }
3462
- const removeChildren = sel === 'slot'; // slot content is removed to trigger slotchange event when removing slot
3463
3355
  switch (type) {
3464
- case 2 /* Element */:
3465
- unmountVNodes(vnode.children, elm, removeChildren);
3356
+ case 2 /* Element */: {
3357
+ // Slot content is removed to trigger slotchange event when removing slot.
3358
+ // Only required for synthetic shadow.
3359
+ const shouldRemoveChildren = sel === 'slot' && vnode.owner.shadowMode === 1 /* Synthetic */;
3360
+ unmountVNodes(vnode.children, elm, renderer, shouldRemoveChildren);
3466
3361
  break;
3362
+ }
3467
3363
  case 3 /* CustomElement */: {
3468
3364
  const { vm } = vnode;
3469
3365
  // No need to unmount the children here, `removeVM` will take care of removing the
@@ -3474,11 +3370,11 @@ function unmount(vnode, parent, doRemove = false) {
3474
3370
  }
3475
3371
  }
3476
3372
  }
3477
- function unmountVNodes(vnodes, parent, doRemove = false, start = 0, end = vnodes.length) {
3373
+ function unmountVNodes(vnodes, parent, renderer, doRemove = false, start = 0, end = vnodes.length) {
3478
3374
  for (; start < end; ++start) {
3479
3375
  const ch = vnodes[start];
3480
3376
  if (isVNode(ch)) {
3481
- unmount(ch, parent, doRemove);
3377
+ unmount(ch, parent, renderer, doRemove);
3482
3378
  }
3483
3379
  }
3484
3380
  }
@@ -3492,15 +3388,19 @@ function setElementShadowToken(elm, token) {
3492
3388
  elm.$shadowToken$ = token;
3493
3389
  }
3494
3390
  // Set the scope token class for *.scoped.css styles
3495
- function setScopeTokenClassIfNecessary(elm, owner) {
3391
+ function setScopeTokenClassIfNecessary(elm, owner, renderer) {
3496
3392
  const { cmpTemplate, context } = owner;
3393
+ const { getClassList } = renderer;
3497
3394
  const token = cmpTemplate === null || cmpTemplate === void 0 ? void 0 : cmpTemplate.stylesheetToken;
3498
3395
  if (!shared.isUndefined(token) && context.hasScopedStyles) {
3396
+ // TODO [#2762]: this dot notation with add is probably problematic
3397
+ // probably we should have a renderer api for just the add operation
3499
3398
  getClassList(elm).add(token);
3500
3399
  }
3501
3400
  }
3502
- function linkNodeToShadow(elm, owner) {
3401
+ function linkNodeToShadow(elm, owner, renderer) {
3503
3402
  const { renderRoot, renderMode, shadowMode } = owner;
3403
+ const { isSyntheticShadowDefined } = renderer;
3504
3404
  // TODO [#1164]: this should eventually be done by the polyfill directly
3505
3405
  if (isSyntheticShadowDefined) {
3506
3406
  if (shadowMode === 1 /* Synthetic */ || renderMode === 0 /* Light */) {
@@ -3508,8 +3408,9 @@ function linkNodeToShadow(elm, owner) {
3508
3408
  }
3509
3409
  }
3510
3410
  }
3511
- function updateTextContent(vnode) {
3411
+ function updateTextContent(vnode, renderer) {
3512
3412
  const { elm, text } = vnode;
3413
+ const { setText } = renderer;
3513
3414
  if (process.env.NODE_ENV !== 'production') {
3514
3415
  unlockDomMutation();
3515
3416
  }
@@ -3518,40 +3419,40 @@ function updateTextContent(vnode) {
3518
3419
  lockDomMutation();
3519
3420
  }
3520
3421
  }
3521
- function insertNode(node, parent, anchor) {
3422
+ function insertNode(node, parent, anchor, renderer) {
3522
3423
  if (process.env.NODE_ENV !== 'production') {
3523
3424
  unlockDomMutation();
3524
3425
  }
3525
- insert(node, parent, anchor);
3426
+ renderer.insert(node, parent, anchor);
3526
3427
  if (process.env.NODE_ENV !== 'production') {
3527
3428
  lockDomMutation();
3528
3429
  }
3529
3430
  }
3530
- function removeNode(node, parent) {
3431
+ function removeNode(node, parent, renderer) {
3531
3432
  if (process.env.NODE_ENV !== 'production') {
3532
3433
  unlockDomMutation();
3533
3434
  }
3534
- remove(node, parent);
3435
+ renderer.remove(node, parent);
3535
3436
  if (process.env.NODE_ENV !== 'production') {
3536
3437
  lockDomMutation();
3537
3438
  }
3538
3439
  }
3539
- function patchElementPropsAndAttrs$1(oldVnode, vnode) {
3440
+ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3540
3441
  if (shared.isNull(oldVnode)) {
3541
- applyEventListeners(vnode);
3542
- applyStaticClassAttribute(vnode);
3543
- applyStaticStyleAttribute(vnode);
3442
+ applyEventListeners(vnode, renderer);
3443
+ applyStaticClassAttribute(vnode, renderer);
3444
+ applyStaticStyleAttribute(vnode, renderer);
3544
3445
  }
3545
3446
  // Attrs need to be applied to element before props IE11 will wipe out value on radio inputs if
3546
3447
  // value is set before type=radio.
3547
- patchClassAttribute(oldVnode, vnode);
3548
- patchStyleAttribute(oldVnode, vnode);
3549
- patchAttributes(oldVnode, vnode);
3550
- patchProps(oldVnode, vnode);
3448
+ patchClassAttribute(oldVnode, vnode, renderer);
3449
+ patchStyleAttribute(oldVnode, vnode, renderer);
3450
+ patchAttributes(oldVnode, vnode, renderer);
3451
+ patchProps(oldVnode, vnode, renderer);
3551
3452
  }
3552
- function fallbackElmHook(elm, vnode) {
3453
+ function fallbackElmHook(elm, vnode, renderer) {
3553
3454
  const { owner } = vnode;
3554
- setScopeTokenClassIfNecessary(elm, owner);
3455
+ setScopeTokenClassIfNecessary(elm, owner, renderer);
3555
3456
  if (owner.shadowMode === 1 /* Synthetic */) {
3556
3457
  const { data: { context }, } = vnode;
3557
3458
  const { stylesheetToken } = owner.context;
@@ -3599,7 +3500,7 @@ function allocateChildren(vnode, vm) {
3599
3500
  vnode.children = EmptyArray;
3600
3501
  }
3601
3502
  }
3602
- function createViewModelHook(elm, vnode) {
3503
+ function createViewModelHook(elm, vnode, renderer) {
3603
3504
  let vm = getAssociatedVMIfPresent(elm);
3604
3505
  // There is a possibility that a custom element is registered under tagName, in which case, the
3605
3506
  // initialization is already carry on, and there is nothing else to do here since this hook is
@@ -3608,7 +3509,7 @@ function createViewModelHook(elm, vnode) {
3608
3509
  return vm;
3609
3510
  }
3610
3511
  const { sel, mode, ctor, owner } = vnode;
3611
- setScopeTokenClassIfNecessary(elm, owner);
3512
+ setScopeTokenClassIfNecessary(elm, owner, renderer);
3612
3513
  if (owner.shadowMode === 1 /* Synthetic */) {
3613
3514
  const { stylesheetToken } = owner.context;
3614
3515
  // when running in synthetic shadow mode, we need to set the shadowToken value
@@ -3617,7 +3518,7 @@ function createViewModelHook(elm, vnode) {
3617
3518
  setElementShadowToken(elm, stylesheetToken);
3618
3519
  }
3619
3520
  }
3620
- vm = createVM(elm, ctor, {
3521
+ vm = createVM(elm, ctor, renderer, {
3621
3522
  mode,
3622
3523
  owner,
3623
3524
  tagName: sel,
@@ -3692,7 +3593,7 @@ function createKeyToOldIdx(children, beginIdx, endIdx) {
3692
3593
  }
3693
3594
  return map;
3694
3595
  }
3695
- function updateDynamicChildren(oldCh, newCh, parent) {
3596
+ function updateDynamicChildren(oldCh, newCh, parent, renderer) {
3696
3597
  let oldStartIdx = 0;
3697
3598
  let newStartIdx = 0;
3698
3599
  let oldEndIdx = oldCh.length - 1;
@@ -3721,26 +3622,26 @@ function updateDynamicChildren(oldCh, newCh, parent) {
3721
3622
  newEndVnode = newCh[--newEndIdx];
3722
3623
  }
3723
3624
  else if (isSameVnode(oldStartVnode, newStartVnode)) {
3724
- patch(oldStartVnode, newStartVnode);
3625
+ patch(oldStartVnode, newStartVnode, renderer);
3725
3626
  oldStartVnode = oldCh[++oldStartIdx];
3726
3627
  newStartVnode = newCh[++newStartIdx];
3727
3628
  }
3728
3629
  else if (isSameVnode(oldEndVnode, newEndVnode)) {
3729
- patch(oldEndVnode, newEndVnode);
3630
+ patch(oldEndVnode, newEndVnode, renderer);
3730
3631
  oldEndVnode = oldCh[--oldEndIdx];
3731
3632
  newEndVnode = newCh[--newEndIdx];
3732
3633
  }
3733
3634
  else if (isSameVnode(oldStartVnode, newEndVnode)) {
3734
3635
  // Vnode moved right
3735
- patch(oldStartVnode, newEndVnode);
3736
- insertNode(oldStartVnode.elm, parent, nextSibling(oldEndVnode.elm));
3636
+ patch(oldStartVnode, newEndVnode, renderer);
3637
+ insertNode(oldStartVnode.elm, parent, renderer.nextSibling(oldEndVnode.elm), renderer);
3737
3638
  oldStartVnode = oldCh[++oldStartIdx];
3738
3639
  newEndVnode = newCh[--newEndIdx];
3739
3640
  }
3740
3641
  else if (isSameVnode(oldEndVnode, newStartVnode)) {
3741
3642
  // Vnode moved left
3742
- patch(oldEndVnode, newStartVnode);
3743
- insertNode(newStartVnode.elm, parent, oldStartVnode.elm);
3643
+ patch(oldEndVnode, newStartVnode, renderer);
3644
+ insertNode(newStartVnode.elm, parent, oldStartVnode.elm, renderer);
3744
3645
  oldEndVnode = oldCh[--oldEndIdx];
3745
3646
  newStartVnode = newCh[++newStartIdx];
3746
3647
  }
@@ -3751,7 +3652,7 @@ function updateDynamicChildren(oldCh, newCh, parent) {
3751
3652
  idxInOld = oldKeyToIdx[newStartVnode.key];
3752
3653
  if (shared.isUndefined(idxInOld)) {
3753
3654
  // New element
3754
- mount(newStartVnode, parent, oldStartVnode.elm);
3655
+ mount(newStartVnode, parent, renderer, oldStartVnode.elm);
3755
3656
  newStartVnode = newCh[++newStartIdx];
3756
3657
  }
3757
3658
  else {
@@ -3759,10 +3660,10 @@ function updateDynamicChildren(oldCh, newCh, parent) {
3759
3660
  if (isVNode(elmToMove)) {
3760
3661
  if (elmToMove.sel !== newStartVnode.sel) {
3761
3662
  // New element
3762
- mount(newStartVnode, parent, oldStartVnode.elm);
3663
+ mount(newStartVnode, parent, renderer, oldStartVnode.elm);
3763
3664
  }
3764
3665
  else {
3765
- patch(elmToMove, newStartVnode);
3666
+ patch(elmToMove, newStartVnode, renderer);
3766
3667
  // Delete the old child, but copy the array since it is read-only.
3767
3668
  // The `oldCh` will be GC'ed after `updateDynamicChildren` is complete,
3768
3669
  // so we only care about the `oldCh` object inside this function.
@@ -3774,7 +3675,7 @@ function updateDynamicChildren(oldCh, newCh, parent) {
3774
3675
  }
3775
3676
  // We've already cloned at least once, so it's no longer read-only
3776
3677
  oldCh[idxInOld] = undefined;
3777
- insertNode(elmToMove.elm, parent, oldStartVnode.elm);
3678
+ insertNode(elmToMove.elm, parent, oldStartVnode.elm, renderer);
3778
3679
  }
3779
3680
  }
3780
3681
  newStartVnode = newCh[++newStartIdx];
@@ -3791,25 +3692,25 @@ function updateDynamicChildren(oldCh, newCh, parent) {
3791
3692
  n = newCh[++i];
3792
3693
  } while (!isVNode(n) && i < newChEnd);
3793
3694
  before = isVNode(n) ? n.elm : null;
3794
- mountVNodes(newCh, parent, before, newStartIdx, newEndIdx + 1);
3695
+ mountVNodes(newCh, parent, renderer, before, newStartIdx, newEndIdx + 1);
3795
3696
  }
3796
3697
  else {
3797
- unmountVNodes(oldCh, parent, true, oldStartIdx, oldEndIdx + 1);
3698
+ unmountVNodes(oldCh, parent, renderer, true, oldStartIdx, oldEndIdx + 1);
3798
3699
  }
3799
3700
  }
3800
3701
  }
3801
- function updateStaticChildren(c1, c2, parent) {
3702
+ function updateStaticChildren(c1, c2, parent, renderer) {
3802
3703
  const c1Length = c1.length;
3803
3704
  const c2Length = c2.length;
3804
3705
  if (c1Length === 0) {
3805
3706
  // the old list is empty, we can directly insert anything new
3806
- mountVNodes(c2, parent, null);
3707
+ mountVNodes(c2, parent, renderer, null);
3807
3708
  return;
3808
3709
  }
3809
3710
  if (c2Length === 0) {
3810
3711
  // the old list is nonempty and the new list is empty so we can directly remove all old nodes
3811
3712
  // this is the case in which the dynamic children of an if-directive should be removed
3812
- unmountVNodes(c1, parent, true);
3713
+ unmountVNodes(c1, parent, renderer, true);
3813
3714
  return;
3814
3715
  }
3815
3716
  // if the old list is not empty, the new list MUST have the same
@@ -3822,16 +3723,16 @@ function updateStaticChildren(c1, c2, parent) {
3822
3723
  if (isVNode(n1)) {
3823
3724
  if (isVNode(n2)) {
3824
3725
  // both vnodes are equivalent, and we just need to patch them
3825
- patch(n1, n2);
3726
+ patch(n1, n2, renderer);
3826
3727
  anchor = n2.elm;
3827
3728
  }
3828
3729
  else {
3829
3730
  // removing the old vnode since the new one is null
3830
- unmount(n1, parent, true);
3731
+ unmount(n1, parent, renderer, true);
3831
3732
  }
3832
3733
  }
3833
3734
  else if (isVNode(n2)) {
3834
- mount(n2, parent, anchor);
3735
+ mount(n2, parent, renderer, anchor);
3835
3736
  anchor = n2.elm;
3836
3737
  }
3837
3738
  }
@@ -3848,6 +3749,17 @@ const SymbolIterator = Symbol.iterator;
3848
3749
  function addVNodeToChildLWC(vnode) {
3849
3750
  shared.ArrayPush.call(getVMBeingRendered().velements, vnode);
3850
3751
  }
3752
+ // [st]atic node
3753
+ function st(fragment, key) {
3754
+ return {
3755
+ type: 4 /* Static */,
3756
+ sel: undefined,
3757
+ key,
3758
+ elm: undefined,
3759
+ fragment,
3760
+ owner: getVMBeingRendered(),
3761
+ };
3762
+ }
3851
3763
  // [h]tml node
3852
3764
  function h(sel, data, children = EmptyArray) {
3853
3765
  const vmBeingRendered = getVMBeingRendered();
@@ -4237,6 +4149,7 @@ const api = shared.freeze({
4237
4149
  co,
4238
4150
  dc,
4239
4151
  ti,
4152
+ st,
4240
4153
  gid,
4241
4154
  fid,
4242
4155
  shc,
@@ -4260,7 +4173,7 @@ function createInlineStyleVNode(content) {
4260
4173
  }, [api.t(content)]);
4261
4174
  }
4262
4175
  function updateStylesheetToken(vm, template) {
4263
- const { elm, context, renderMode, shadowMode } = vm;
4176
+ const { elm, context, renderMode, shadowMode, renderer: { getClassList, removeAttribute, setAttribute }, } = vm;
4264
4177
  const { stylesheets: newStylesheets, stylesheetToken: newStylesheetToken } = template;
4265
4178
  const isSyntheticShadow = renderMode === 1 /* Shadow */ && shadowMode === 1 /* Synthetic */;
4266
4179
  const { hasScopedStyles } = context;
@@ -4377,7 +4290,7 @@ function getNearestNativeShadowComponent(vm) {
4377
4290
  return owner;
4378
4291
  }
4379
4292
  function createStylesheet(vm, stylesheets) {
4380
- const { renderMode, shadowMode } = vm;
4293
+ const { renderMode, shadowMode, renderer: { ssr, insertStylesheet }, } = vm;
4381
4294
  if (renderMode === 1 /* Shadow */ && shadowMode === 1 /* Synthetic */) {
4382
4295
  for (let i = 0; i < stylesheets.length; i++) {
4383
4296
  insertStylesheet(stylesheets[i]);
@@ -4388,8 +4301,7 @@ function createStylesheet(vm, stylesheets) {
4388
4301
  // This works in the client, because the stylesheets are created, and cached in the VM
4389
4302
  // the first time the VM renders.
4390
4303
  // native shadow or light DOM, SSR
4391
- const combinedStylesheetContent = shared.ArrayJoin.call(stylesheets, '\n');
4392
- return createInlineStyleVNode(combinedStylesheetContent);
4304
+ return shared.ArrayMap.call(stylesheets, createInlineStyleVNode);
4393
4305
  }
4394
4306
  else {
4395
4307
  // native shadow or light DOM, DOM renderer
@@ -4557,6 +4469,59 @@ function validateLightDomTemplate(template, vm) {
4557
4469
  shared.assert.isTrue(shared.isUndefined(template.renderMode), `Shadow DOM components template can't render light DOM templates. Either remove the 'lwc:render-mode' directive from ${getComponentTag(vm)} or set it to 'lwc:render-mode="shadow"`);
4558
4470
  }
4559
4471
  }
4472
+ function buildParseFragmentFn(createFragmentFn) {
4473
+ return (strings, ...keys) => {
4474
+ const cache = shared.create(null);
4475
+ return function () {
4476
+ const { context: { hasScopedStyles, stylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
4477
+ const hasStyleToken = !shared.isUndefined(stylesheetToken);
4478
+ const isSyntheticShadow = shadowMode === 1 /* Synthetic */;
4479
+ let cacheKey = 0;
4480
+ if (hasStyleToken && hasScopedStyles) {
4481
+ cacheKey |= 1 /* HAS_SCOPED_STYLE */;
4482
+ }
4483
+ if (hasStyleToken && isSyntheticShadow) {
4484
+ cacheKey |= 2 /* SHADOW_MODE_SYNTHETIC */;
4485
+ }
4486
+ if (!shared.isUndefined(cache[cacheKey])) {
4487
+ return cache[cacheKey];
4488
+ }
4489
+ const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetToken : '';
4490
+ const classAttrToken = hasScopedStyles && hasStyleToken ? ` class="${stylesheetToken}"` : '';
4491
+ const attrToken = hasStyleToken && isSyntheticShadow ? ' ' + stylesheetToken : '';
4492
+ let htmlFragment = '';
4493
+ for (let i = 0, n = keys.length; i < n; i++) {
4494
+ switch (keys[i]) {
4495
+ case 0: // styleToken in existing class attr
4496
+ htmlFragment += strings[i] + classToken;
4497
+ break;
4498
+ case 1: // styleToken for added class attr
4499
+ htmlFragment += strings[i] + classAttrToken;
4500
+ break;
4501
+ case 2: // styleToken as attr
4502
+ htmlFragment += strings[i] + attrToken;
4503
+ break;
4504
+ case 3: // ${1}${2}
4505
+ htmlFragment += strings[i] + classAttrToken + attrToken;
4506
+ break;
4507
+ }
4508
+ }
4509
+ htmlFragment += strings[strings.length - 1];
4510
+ cache[cacheKey] = createFragmentFn(htmlFragment, renderer);
4511
+ return cache[cacheKey];
4512
+ };
4513
+ };
4514
+ }
4515
+ // Note: at the moment this code executes, we don't have a renderer yet.
4516
+ const parseFragment = buildParseFragmentFn((html, renderer) => {
4517
+ const { createFragment } = renderer;
4518
+ return createFragment(html);
4519
+ });
4520
+ const parseSVGFragment = buildParseFragmentFn((html, renderer) => {
4521
+ const { createFragment, getFirstChild } = renderer;
4522
+ const fragment = createFragment('<svg>' + html + '</svg>');
4523
+ return getFirstChild(fragment);
4524
+ });
4560
4525
  function evaluateTemplate(vm, html) {
4561
4526
  if (process.env.NODE_ENV !== 'production') {
4562
4527
  shared.assert.isTrue(shared.isFunction(html), `evaluateTemplate() second argument must be an imported template instead of ${shared.toString(html)}`);
@@ -4603,7 +4568,7 @@ function evaluateTemplate(vm, html) {
4603
4568
  // Evaluate, create stylesheet and cache the produced VNode for future
4604
4569
  // re-rendering.
4605
4570
  const stylesheetsContent = getStylesheetsContent(vm, html);
4606
- context.styleVNode =
4571
+ context.styleVNodes =
4607
4572
  stylesheetsContent.length === 0
4608
4573
  ? null
4609
4574
  : createStylesheet(vm, stylesheetsContent);
@@ -4620,9 +4585,9 @@ function evaluateTemplate(vm, html) {
4620
4585
  // Set the global flag that template is being updated
4621
4586
  isUpdatingTemplate = true;
4622
4587
  vnodes = html.call(undefined, api, component, cmpSlots, context.tplCache);
4623
- const { styleVNode } = context;
4624
- if (!shared.isNull(styleVNode)) {
4625
- shared.ArrayUnshift.call(vnodes, styleVNode);
4588
+ const { styleVNodes } = context;
4589
+ if (!shared.isNull(styleVNodes)) {
4590
+ shared.ArrayUnshift.apply(vnodes, styleVNodes);
4626
4591
  }
4627
4592
  });
4628
4593
  }, () => {
@@ -4939,9 +4904,20 @@ function removeVM(vm) {
4939
4904
 
4940
4905
  resetComponentStateWhenRemoved(vm);
4941
4906
  }
4942
- function createVM(elm, ctor, options) {
4943
- var _a;
4944
4907
 
4908
+ function getNearestShadowAncestor(vm) {
4909
+ let ancestor = vm.owner;
4910
+
4911
+ while (!shared.isNull(ancestor) && ancestor.renderMode === 0
4912
+ /* Light */
4913
+ ) {
4914
+ ancestor = ancestor.owner;
4915
+ }
4916
+
4917
+ return ancestor;
4918
+ }
4919
+
4920
+ function createVM(elm, ctor, renderer, options) {
4945
4921
  const {
4946
4922
  mode,
4947
4923
  owner,
@@ -4971,28 +4947,29 @@ function createVM(elm, ctor, options) {
4971
4947
  cmpTemplate: null,
4972
4948
  hydrated: Boolean(hydrated),
4973
4949
  renderMode: def.renderMode,
4974
- shadowMode: computeShadowMode(def, owner),
4975
- nearestShadowMode: (owner === null || owner === void 0 ? void 0 : owner.shadowRoot) ? owner.shadowMode : (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : null,
4976
4950
  context: {
4977
4951
  stylesheetToken: undefined,
4978
4952
  hasTokenInClass: undefined,
4979
4953
  hasTokenInAttribute: undefined,
4980
4954
  hasScopedStyles: undefined,
4981
- styleVNode: null,
4955
+ styleVNodes: null,
4982
4956
  tplCache: EmptyObject,
4983
4957
  wiredConnecting: EmptyArray,
4984
4958
  wiredDisconnecting: EmptyArray
4985
4959
  },
4986
4960
  // Properties set right after VM creation.
4987
4961
  tro: null,
4962
+ shadowMode: null,
4988
4963
  // Properties set by the LightningElement constructor.
4989
4964
  component: null,
4990
4965
  shadowRoot: null,
4991
4966
  renderRoot: null,
4992
4967
  callHook,
4993
4968
  setHook,
4994
- getHook
4969
+ getHook,
4970
+ renderer
4995
4971
  };
4972
+ vm.shadowMode = computeShadowMode(vm, renderer);
4996
4973
  vm.tro = getTemplateReactiveObserver(vm);
4997
4974
 
4998
4975
  if (process.env.NODE_ENV !== 'production') {
@@ -5017,9 +4994,14 @@ function createVM(elm, ctor, options) {
5017
4994
  return vm;
5018
4995
  }
5019
4996
 
5020
- function computeShadowMode(def, owner) {
5021
- var _a;
5022
-
4997
+ function computeShadowMode(vm, renderer) {
4998
+ const {
4999
+ def
5000
+ } = vm;
5001
+ const {
5002
+ isSyntheticShadowDefined,
5003
+ isNativeShadowDefined
5004
+ } = renderer;
5023
5005
  let shadowMode;
5024
5006
 
5025
5007
  if (isSyntheticShadowDefined) {
@@ -5042,13 +5024,23 @@ function computeShadowMode(def, owner) {
5042
5024
  /* Native */
5043
5025
  ;
5044
5026
  } else {
5045
- // Transitive support for native Shadow DOM. A component in native mode
5046
- // transitively opts all of its descendants into native.
5047
- // Synthetic if neither this component nor any of its ancestors are configured
5048
- // to be native.
5049
- shadowMode = (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : 1
5050
- /* Synthetic */
5051
- ;
5027
+ const shadowAncestor = getNearestShadowAncestor(vm);
5028
+
5029
+ if (!shared.isNull(shadowAncestor) && shadowAncestor.shadowMode === 0
5030
+ /* Native */
5031
+ ) {
5032
+ // Transitive support for native Shadow DOM. A component in native mode
5033
+ // transitively opts all of its descendants into native.
5034
+ shadowMode = 0
5035
+ /* Native */
5036
+ ;
5037
+ } else {
5038
+ // Synthetic if neither this component nor any of its ancestors are configured
5039
+ // to be native.
5040
+ shadowMode = 1
5041
+ /* Synthetic */
5042
+ ;
5043
+ }
5052
5044
  }
5053
5045
  } else {
5054
5046
  shadowMode = 1
@@ -5111,7 +5103,8 @@ function rehydrate(vm) {
5111
5103
  function patchShadowRoot(vm, newCh) {
5112
5104
  const {
5113
5105
  renderRoot,
5114
- children: oldCh
5106
+ children: oldCh,
5107
+ renderer
5115
5108
  } = vm; // caching the new children collection
5116
5109
 
5117
5110
  vm.children = newCh;
@@ -5127,7 +5120,7 @@ function patchShadowRoot(vm, newCh) {
5127
5120
  , vm);
5128
5121
  }, () => {
5129
5122
  // job
5130
- patchChildren(oldCh, newCh, renderRoot);
5123
+ patchChildren(oldCh, newCh, renderRoot, renderer);
5131
5124
  }, () => {
5132
5125
  // post
5133
5126
  logOperationEnd(2
@@ -5152,6 +5145,9 @@ function runRenderedCallback(vm) {
5152
5145
  const {
5153
5146
  def: {
5154
5147
  renderedCallback
5148
+ },
5149
+ renderer: {
5150
+ ssr
5155
5151
  }
5156
5152
  } = vm;
5157
5153
 
@@ -5389,7 +5385,10 @@ function recursivelyDisconnectChildren(vnodes) {
5389
5385
  function resetComponentRoot(vm) {
5390
5386
  const {
5391
5387
  children,
5392
- renderRoot
5388
+ renderRoot,
5389
+ renderer: {
5390
+ remove
5391
+ }
5393
5392
  } = vm;
5394
5393
 
5395
5394
  for (let i = 0, len = children.length; i < len; i++) {
@@ -5405,6 +5404,12 @@ function resetComponentRoot(vm) {
5405
5404
  vm.velements = EmptyArray;
5406
5405
  }
5407
5406
  function scheduleRehydration(vm) {
5407
+ const {
5408
+ renderer: {
5409
+ ssr
5410
+ }
5411
+ } = vm;
5412
+
5408
5413
  if (shared.isTrue(ssr) || shared.isTrue(vm.isScheduled)) {
5409
5414
  return;
5410
5415
  }
@@ -5581,6 +5586,9 @@ function createContextWatcher(vm, wireDef, callbackWhenContextIsReady) {
5581
5586
  context: {
5582
5587
  wiredConnecting,
5583
5588
  wiredDisconnecting
5589
+ },
5590
+ renderer: {
5591
+ dispatchEvent
5584
5592
  }
5585
5593
  } = vm; // waiting for the component to be connected to formally request the context via the token
5586
5594
 
@@ -5852,70 +5860,90 @@ function hydrateRoot(vm) {
5852
5860
  function hydrateVM(vm) {
5853
5861
  const children = renderComponent(vm);
5854
5862
  vm.children = children;
5855
- const parentNode = vm.renderRoot;
5863
+ const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
5856
5864
  hydrateChildren(getFirstChild(parentNode), children, parentNode, vm);
5857
5865
  runRenderedCallback(vm);
5858
5866
  }
5859
- function hydrateNode(node, vnode) {
5867
+ function hydrateNode(node, vnode, renderer) {
5868
+ var _a, _b;
5860
5869
  let hydratedNode;
5861
5870
  switch (vnode.type) {
5862
5871
  case 0 /* Text */:
5863
- hydratedNode = hydrateText(node, vnode);
5872
+ // VText has no special capability, fallback to the owner's renderer
5873
+ hydratedNode = hydrateText(node, vnode, renderer);
5864
5874
  break;
5865
5875
  case 1 /* Comment */:
5866
- hydratedNode = hydrateComment(node, vnode);
5876
+ // VComment has no special capability, fallback to the owner's renderer
5877
+ hydratedNode = hydrateComment(node, vnode, renderer);
5878
+ break;
5879
+ case 4 /* Static */:
5880
+ // VStatic are cacheable and cannot have custom renderer associated to them
5881
+ hydratedNode = hydrateStaticElement(node, vnode, renderer);
5867
5882
  break;
5868
5883
  case 2 /* Element */:
5869
- hydratedNode = hydrateElement(node, vnode);
5884
+ hydratedNode = hydrateElement(node, vnode, (_a = vnode.data.renderer) !== null && _a !== void 0 ? _a : renderer);
5870
5885
  break;
5871
5886
  case 3 /* CustomElement */:
5872
- hydratedNode = hydrateCustomElement(node, vnode);
5887
+ hydratedNode = hydrateCustomElement(node, vnode, (_b = vnode.data.renderer) !== null && _b !== void 0 ? _b : renderer);
5873
5888
  break;
5874
5889
  }
5875
- return nextSibling(hydratedNode);
5890
+ return renderer.nextSibling(hydratedNode);
5876
5891
  }
5877
- function hydrateText(node, vnode) {
5892
+ function hydrateText(node, vnode, renderer) {
5878
5893
  var _a;
5879
- if (!hasCorrectNodeType(vnode, node, 3 /* TEXT */)) {
5880
- return handleMismatch(node, vnode);
5894
+ if (!hasCorrectNodeType(vnode, node, 3 /* TEXT */, renderer)) {
5895
+ return handleMismatch(node, vnode, renderer);
5881
5896
  }
5882
5897
  if (process.env.NODE_ENV !== 'production') {
5898
+ const { getProperty } = renderer;
5883
5899
  const nodeValue = getProperty(node, 'nodeValue');
5884
5900
  if (nodeValue !== vnode.text && !(nodeValue === '\u200D' && vnode.text === '')) {
5885
5901
  logWarn('Hydration mismatch: text values do not match, will recover from the difference', vnode.owner);
5886
5902
  }
5887
5903
  }
5904
+ const { setText } = renderer;
5888
5905
  setText(node, (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
5889
5906
  vnode.elm = node;
5890
5907
  return node;
5891
5908
  }
5892
- function hydrateComment(node, vnode) {
5909
+ function hydrateComment(node, vnode, renderer) {
5893
5910
  var _a;
5894
- if (!hasCorrectNodeType(vnode, node, 8 /* COMMENT */)) {
5895
- return handleMismatch(node, vnode);
5911
+ if (!hasCorrectNodeType(vnode, node, 8 /* COMMENT */, renderer)) {
5912
+ return handleMismatch(node, vnode, renderer);
5896
5913
  }
5897
5914
  if (process.env.NODE_ENV !== 'production') {
5915
+ const { getProperty } = renderer;
5898
5916
  const nodeValue = getProperty(node, 'nodeValue');
5899
5917
  if (nodeValue !== vnode.text) {
5900
5918
  logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
5901
5919
  }
5902
5920
  }
5921
+ const { setProperty } = renderer;
5903
5922
  setProperty(node, 'nodeValue', (_a = vnode.text) !== null && _a !== void 0 ? _a : null);
5904
5923
  vnode.elm = node;
5905
5924
  return node;
5906
5925
  }
5907
- function hydrateElement(elm, vnode) {
5908
- if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
5909
- !isMatchingElement(vnode, elm)) {
5910
- return handleMismatch(elm, vnode);
5926
+ function hydrateStaticElement(elm, vnode, renderer) {
5927
+ if (!areCompatibleNodes(vnode.fragment, elm, vnode, renderer)) {
5928
+ return handleMismatch(elm, vnode, renderer);
5929
+ }
5930
+ vnode.elm = elm;
5931
+ return elm;
5932
+ }
5933
+ function hydrateElement(elm, vnode, renderer) {
5934
+ if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */, renderer) ||
5935
+ !isMatchingElement(vnode, elm, renderer)) {
5936
+ return handleMismatch(elm, vnode, renderer);
5911
5937
  }
5912
5938
  vnode.elm = elm;
5939
+ const { owner } = vnode;
5913
5940
  const { context } = vnode.data;
5914
5941
  const isDomManual = Boolean(!shared.isUndefined(context) && !shared.isUndefined(context.lwc) && context.lwc.dom === "manual" /* Manual */);
5915
5942
  if (isDomManual) {
5916
5943
  // it may be that this element has lwc:inner-html, we need to diff and in case are the same,
5917
5944
  // remove the innerHTML from props so it reuses the existing dom elements.
5918
- const { props } = vnode.data;
5945
+ const { data: { props }, } = vnode;
5946
+ const { getProperty } = renderer;
5919
5947
  if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
5920
5948
  if (getProperty(elm, 'innerHTML') === props.innerHTML) {
5921
5949
  // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
@@ -5923,24 +5951,25 @@ function hydrateElement(elm, vnode) {
5923
5951
  }
5924
5952
  else {
5925
5953
  if (process.env.NODE_ENV !== 'production') {
5926
- logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
5954
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, owner);
5927
5955
  }
5928
5956
  }
5929
5957
  }
5930
5958
  }
5931
- patchElementPropsAndAttrs(vnode);
5959
+ patchElementPropsAndAttrs(vnode, renderer);
5932
5960
  if (!isDomManual) {
5933
- hydrateChildren(getFirstChild(elm), vnode.children, elm, vnode.owner);
5961
+ const { getFirstChild } = renderer;
5962
+ hydrateChildren(getFirstChild(elm), vnode.children, elm, owner);
5934
5963
  }
5935
5964
  return elm;
5936
5965
  }
5937
- function hydrateCustomElement(elm, vnode) {
5938
- if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */) ||
5939
- !isMatchingElement(vnode, elm)) {
5940
- return handleMismatch(elm, vnode);
5966
+ function hydrateCustomElement(elm, vnode, renderer) {
5967
+ if (!hasCorrectNodeType(vnode, elm, 1 /* ELEMENT */, renderer) ||
5968
+ !isMatchingElement(vnode, elm, renderer)) {
5969
+ return handleMismatch(elm, vnode, renderer);
5941
5970
  }
5942
5971
  const { sel, mode, ctor, owner } = vnode;
5943
- const vm = createVM(elm, ctor, {
5972
+ const vm = createVM(elm, ctor, renderer, {
5944
5973
  mode,
5945
5974
  owner,
5946
5975
  tagName: sel,
@@ -5949,13 +5978,14 @@ function hydrateCustomElement(elm, vnode) {
5949
5978
  vnode.elm = elm;
5950
5979
  vnode.vm = vm;
5951
5980
  allocateChildren(vnode, vm);
5952
- patchElementPropsAndAttrs(vnode);
5981
+ patchElementPropsAndAttrs(vnode, renderer);
5953
5982
  // Insert hook section:
5954
5983
  if (process.env.NODE_ENV !== 'production') {
5955
5984
  shared.assert.isTrue(vm.state === 0 /* created */, `${vm} cannot be recycled.`);
5956
5985
  }
5957
5986
  runConnectedCallback(vm);
5958
5987
  if (vm.renderMode !== 0 /* Light */) {
5988
+ const { getFirstChild } = renderer;
5959
5989
  // VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
5960
5990
  // Note: for Light DOM, this is handled while hydrating the VM
5961
5991
  hydrateChildren(getFirstChild(elm), vnode.children, elm, vm);
@@ -5967,11 +5997,12 @@ function hydrateChildren(node, children, parentNode, owner) {
5967
5997
  let hasWarned = false;
5968
5998
  let nextNode = node;
5969
5999
  let anchor = null;
6000
+ const { renderer } = owner;
5970
6001
  for (let i = 0; i < children.length; i++) {
5971
6002
  const childVnode = children[i];
5972
6003
  if (!shared.isNull(childVnode)) {
5973
6004
  if (nextNode) {
5974
- nextNode = hydrateNode(nextNode, childVnode);
6005
+ nextNode = hydrateNode(nextNode, childVnode, renderer);
5975
6006
  anchor = childVnode.elm;
5976
6007
  }
5977
6008
  else {
@@ -5982,7 +6013,7 @@ function hydrateChildren(node, children, parentNode, owner) {
5982
6013
  logError(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
5983
6014
  }
5984
6015
  }
5985
- mount(childVnode, parentNode, anchor);
6016
+ mount(childVnode, parentNode, renderer, anchor);
5986
6017
  anchor = childVnode.elm;
5987
6018
  }
5988
6019
  }
@@ -5994,30 +6025,32 @@ function hydrateChildren(node, children, parentNode, owner) {
5994
6025
  logError(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
5995
6026
  }
5996
6027
  }
6028
+ // nextSibling is mostly harmless, and since we don't have
6029
+ // a good reference to what element to act upon, we instead
6030
+ // rely on the vm's associated renderer for navigating to the
6031
+ // next node in the list to be hydrated.
6032
+ const { nextSibling } = renderer;
5997
6033
  do {
5998
6034
  const current = nextNode;
5999
6035
  nextNode = nextSibling(nextNode);
6000
- removeNode(current, parentNode);
6036
+ removeNode(current, parentNode, renderer);
6001
6037
  } while (nextNode);
6002
6038
  }
6003
6039
  }
6004
- function handleMismatch(node, vnode, msg) {
6040
+ function handleMismatch(node, vnode, renderer) {
6005
6041
  hasMismatch = true;
6006
- if (!shared.isUndefined(msg)) {
6007
- if (process.env.NODE_ENV !== 'production') {
6008
- logError(msg, vnode.owner);
6009
- }
6010
- }
6042
+ const { getProperty } = renderer;
6011
6043
  const parentNode = getProperty(node, 'parentNode');
6012
- mount(vnode, parentNode, node);
6013
- removeNode(node, parentNode);
6044
+ mount(vnode, parentNode, renderer, node);
6045
+ removeNode(node, parentNode, renderer);
6014
6046
  return vnode.elm;
6015
6047
  }
6016
- function patchElementPropsAndAttrs(vnode) {
6017
- applyEventListeners(vnode);
6018
- patchProps(null, vnode);
6048
+ function patchElementPropsAndAttrs(vnode, renderer) {
6049
+ applyEventListeners(vnode, renderer);
6050
+ patchProps(null, vnode, renderer);
6019
6051
  }
6020
- function hasCorrectNodeType(vnode, node, nodeType) {
6052
+ function hasCorrectNodeType(vnode, node, nodeType, renderer) {
6053
+ const { getProperty } = renderer;
6021
6054
  if (getProperty(node, 'nodeType') !== nodeType) {
6022
6055
  if (process.env.NODE_ENV !== 'production') {
6023
6056
  logError('Hydration mismatch: incorrect node type received', vnode.owner);
@@ -6026,36 +6059,41 @@ function hasCorrectNodeType(vnode, node, nodeType) {
6026
6059
  }
6027
6060
  return true;
6028
6061
  }
6029
- function isMatchingElement(vnode, elm) {
6062
+ function isMatchingElement(vnode, elm, renderer) {
6063
+ const { getProperty } = renderer;
6030
6064
  if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
6031
6065
  if (process.env.NODE_ENV !== 'production') {
6032
6066
  logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
6033
6067
  }
6034
6068
  return false;
6035
6069
  }
6036
- const hasIncompatibleAttrs = validateAttrs(vnode, elm);
6037
- const hasIncompatibleClass = validateClassAttr(vnode, elm);
6038
- const hasIncompatibleStyle = validateStyleAttr(vnode, elm);
6070
+ const hasIncompatibleAttrs = validateAttrs(vnode, elm, renderer);
6071
+ const hasIncompatibleClass = validateClassAttr(vnode, elm, renderer);
6072
+ const hasIncompatibleStyle = validateStyleAttr(vnode, elm, renderer);
6039
6073
  return hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
6040
6074
  }
6041
- function validateAttrs(vnode, elm) {
6075
+ function validateAttrs(vnode, elm, renderer) {
6042
6076
  const { data: { attrs = {} }, } = vnode;
6043
6077
  let nodesAreCompatible = true;
6044
6078
  // Validate attributes, though we could always recovery from those by running the update mods.
6045
6079
  // Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
6046
6080
  for (const [attrName, attrValue] of Object.entries(attrs)) {
6081
+ const { owner } = vnode;
6082
+ const { getAttribute } = renderer;
6047
6083
  const elmAttrValue = getAttribute(elm, attrName);
6048
6084
  if (String(attrValue) !== elmAttrValue) {
6049
6085
  if (process.env.NODE_ENV !== 'production') {
6050
- logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
6086
+ const { getProperty } = renderer;
6087
+ logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, owner);
6051
6088
  }
6052
6089
  nodesAreCompatible = false;
6053
6090
  }
6054
6091
  }
6055
6092
  return nodesAreCompatible;
6056
6093
  }
6057
- function validateClassAttr(vnode, elm) {
6094
+ function validateClassAttr(vnode, elm, renderer) {
6058
6095
  const { data: { className, classMap }, } = vnode;
6096
+ const { getProperty, getClassList } = renderer;
6059
6097
  let nodesAreCompatible = true;
6060
6098
  let vnodeClassName;
6061
6099
  if (!shared.isUndefined(className) && String(className) !== getProperty(elm, 'className')) {
@@ -6086,8 +6124,9 @@ function validateClassAttr(vnode, elm) {
6086
6124
  }
6087
6125
  return nodesAreCompatible;
6088
6126
  }
6089
- function validateStyleAttr(vnode, elm) {
6127
+ function validateStyleAttr(vnode, elm, renderer) {
6090
6128
  const { data: { style, styleDecls }, } = vnode;
6129
+ const { getAttribute } = renderer;
6091
6130
  const elmStyle = getAttribute(elm, 'style') || '';
6092
6131
  let vnodeStyle;
6093
6132
  let nodesAreCompatible = true;
@@ -6120,11 +6159,45 @@ function validateStyleAttr(vnode, elm) {
6120
6159
  }
6121
6160
  if (!nodesAreCompatible) {
6122
6161
  if (process.env.NODE_ENV !== 'production') {
6162
+ const { getProperty } = renderer;
6123
6163
  logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
6124
6164
  }
6125
6165
  }
6126
6166
  return nodesAreCompatible;
6127
6167
  }
6168
+ function areCompatibleNodes(client, ssr, vnode, renderer) {
6169
+ const { getProperty, getAttribute } = renderer;
6170
+ if (getProperty(client, 'nodeType') === 3 /* TEXT */) {
6171
+ if (!hasCorrectNodeType(vnode, ssr, 3 /* TEXT */, renderer)) {
6172
+ return false;
6173
+ }
6174
+ return getProperty(client, 'nodeValue') === getProperty(ssr, 'nodeValue');
6175
+ }
6176
+ if (getProperty(client, 'nodeType') === 8 /* COMMENT */) {
6177
+ if (!hasCorrectNodeType(vnode, ssr, 8 /* COMMENT */, renderer)) {
6178
+ return false;
6179
+ }
6180
+ return getProperty(client, 'nodeValue') === getProperty(ssr, 'nodeValue');
6181
+ }
6182
+ if (!hasCorrectNodeType(vnode, ssr, 1 /* ELEMENT */, renderer)) {
6183
+ return false;
6184
+ }
6185
+ let isCompatibleElements = true;
6186
+ if (getProperty(client, 'tagName') !== getProperty(ssr, 'tagName')) {
6187
+ if (process.env.NODE_ENV !== 'production') {
6188
+ logError(`Hydration mismatch: expecting element with tag "${getProperty(client, 'tagName').toLowerCase()}" but found "${getProperty(ssr, 'tagName').toLowerCase()}".`, vnode.owner);
6189
+ }
6190
+ return false;
6191
+ }
6192
+ const clientAttrsNames = getProperty(client, 'getAttributeNames').call(client);
6193
+ clientAttrsNames.forEach((attrName) => {
6194
+ if (getAttribute(client, attrName) !== getAttribute(ssr, attrName)) {
6195
+ logError(`Mismatch hydrating element <${getProperty(client, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${getAttribute(client, attrName)}" but found "${getAttribute(ssr, attrName)}"`, vnode.owner);
6196
+ isCompatibleElements = false;
6197
+ }
6198
+ });
6199
+ return isCompatibleElements;
6200
+ }
6128
6201
 
6129
6202
  /*
6130
6203
  * Copyright (c) 2018, salesforce.com, inc.
@@ -6284,56 +6357,19 @@ exports.getComponentHtmlPrototype = getComponentHtmlPrototype;
6284
6357
  exports.getUpgradableConstructor = getUpgradableConstructor;
6285
6358
  exports.hydrateRoot = hydrateRoot;
6286
6359
  exports.isComponentConstructor = isComponentConstructor;
6360
+ exports.parseFragment = parseFragment;
6361
+ exports.parseSVGFragment = parseSVGFragment;
6287
6362
  exports.readonly = readonly;
6288
6363
  exports.register = register;
6289
6364
  exports.registerComponent = registerComponent;
6290
6365
  exports.registerDecorators = registerDecorators;
6291
6366
  exports.registerTemplate = registerTemplate;
6292
6367
  exports.sanitizeAttribute = sanitizeAttribute;
6293
- exports.setAddEventListener = setAddEventListener;
6294
- exports.setAssertInstanceOfHTMLElement = setAssertInstanceOfHTMLElement;
6295
- exports.setAttachShadow = setAttachShadow;
6296
- exports.setCreateComment = setCreateComment;
6297
- exports.setCreateElement = setCreateElement;
6298
- exports.setCreateText = setCreateText;
6299
- exports.setDefineCustomElement = setDefineCustomElement;
6300
- exports.setDispatchEvent = setDispatchEvent;
6301
- exports.setGetAttribute = setGetAttribute;
6302
- exports.setGetBoundingClientRect = setGetBoundingClientRect;
6303
- exports.setGetChildNodes = setGetChildNodes;
6304
- exports.setGetChildren = setGetChildren;
6305
- exports.setGetClassList = setGetClassList;
6306
- exports.setGetCustomElement = setGetCustomElement;
6307
- exports.setGetElementsByClassName = setGetElementsByClassName;
6308
- exports.setGetElementsByTagName = setGetElementsByTagName;
6309
- exports.setGetFirstChild = setGetFirstChild;
6310
- exports.setGetFirstElementChild = setGetFirstElementChild;
6311
- exports.setGetLastChild = setGetLastChild;
6312
- exports.setGetLastElementChild = setGetLastElementChild;
6313
- exports.setGetProperty = setGetProperty;
6314
- exports.setHTMLElement = setHTMLElement;
6315
6368
  exports.setHooks = setHooks;
6316
- exports.setInsert = setInsert;
6317
- exports.setInsertStylesheet = setInsertStylesheet;
6318
- exports.setIsConnected = setIsConnected;
6319
- exports.setIsHydrating = setIsHydrating;
6320
- exports.setIsNativeShadowDefined = setIsNativeShadowDefined;
6321
- exports.setIsSyntheticShadowDefined = setIsSyntheticShadowDefined;
6322
- exports.setNextSibling = setNextSibling;
6323
- exports.setQuerySelector = setQuerySelector;
6324
- exports.setQuerySelectorAll = setQuerySelectorAll;
6325
- exports.setRemove = setRemove;
6326
- exports.setRemoveAttribute = setRemoveAttribute;
6327
- exports.setRemoveEventListener = setRemoveEventListener;
6328
- exports.setSetAttribute = setSetAttribute;
6329
- exports.setSetCSSStyleProperty = setSetCSSStyleProperty;
6330
- exports.setSetProperty = setSetProperty;
6331
- exports.setSetText = setSetText;
6332
- exports.setSsr = setSsr;
6333
6369
  exports.swapComponent = swapComponent;
6334
6370
  exports.swapStyle = swapStyle;
6335
6371
  exports.swapTemplate = swapTemplate;
6336
6372
  exports.track = track;
6337
6373
  exports.unwrap = unwrap;
6338
6374
  exports.wire = wire;
6339
- /* version: 2.14.0 */
6375
+ /* version: 2.15.0 */