@lwc/synthetic-shadow 2.5.11 → 2.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -194,7 +194,7 @@ const KEY__SYNTHETIC_MODE = '$$lwc-synthetic-mode';
194
194
 
195
195
 
196
196
  const hasNativeSymbolSupport = /*@__PURE__*/(() => Symbol('x').toString() === 'Symbol(x)')();
197
- /** version: 2.5.11 */
197
+ /** version: 2.6.3 */
198
198
 
199
199
  /*
200
200
  * Copyright (c) 2018, salesforce.com, inc.
@@ -301,6 +301,7 @@ const {
301
301
  getElementsByClassName: getElementsByClassName$1
302
302
  } = HTMLElement.prototype;
303
303
  const shadowRootGetter = hasOwnProperty.call(Element.prototype, 'shadowRoot') ? getOwnPropertyDescriptor(Element.prototype, 'shadowRoot').get : () => null;
304
+ const assignedSlotGetter$1 = hasOwnProperty.call(Element.prototype, 'assignedSlot') ? getOwnPropertyDescriptor(Element.prototype, 'assignedSlot').get : () => null;
304
305
 
305
306
  /*
306
307
  * Copyright (c) 2018, salesforce.com, inc.
@@ -515,19 +516,6 @@ function arrayFromCollection(collection) {
515
516
  return cloned;
516
517
  }
517
518
 
518
- /**
519
- * Copyright (C) 2018 salesforce.com, inc.
520
- */
521
-
522
- if (!_globalThis.lwcRuntimeFlags) {
523
- Object.defineProperty(_globalThis, 'lwcRuntimeFlags', {
524
- value: create(null)
525
- });
526
- }
527
-
528
- const runtimeFlags = _globalThis.lwcRuntimeFlags;
529
- /** version: 2.5.11 */
530
-
531
519
  /*
532
520
  * Copyright (c) 2018, salesforce.com, inc.
533
521
  * All rights reserved.
@@ -587,19 +575,9 @@ function getEventListenerWrapper(fnOrObj) {
587
575
  assert.invariant(isFalse(isSyntheticShadowHost(currentTarget)), 'This routine should not be used to wrap event listeners for host elements and shadow roots.');
588
576
  }
589
577
 
590
- const {
591
- composed
592
- } = event;
593
- let shouldInvoke;
594
-
595
- if (runtimeFlags.ENABLE_NON_COMPOSED_EVENTS_LEAKAGE) {
596
- shouldInvoke = !(eventToShadowRootMap.has(event) && isFalse(composed));
597
- } else {
598
- const actualTarget = getActualTarget(event);
599
- shouldInvoke = shouldInvokeListener(event, actualTarget, currentTarget);
600
- }
578
+ const actualTarget = getActualTarget(event);
601
579
 
602
- if (!shouldInvoke) {
580
+ if (!shouldInvokeListener(event, actualTarget, currentTarget)) {
603
581
  return;
604
582
  }
605
583
 
@@ -619,25 +597,6 @@ function getEventListenerWrapper(fnOrObj) {
619
597
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
620
598
  */
621
599
  const eventToContextMap = new WeakMap();
622
-
623
- function isChildNode(root, node) {
624
- return !!(compareDocumentPosition.call(root, node) & DOCUMENT_POSITION_CONTAINED_BY);
625
- }
626
-
627
- const GET_ROOT_NODE_CONFIG_FALSE = {
628
- composed: false
629
- };
630
-
631
- function getRootNodeHost(node, options) {
632
- let rootNode = node.getRootNode(options);
633
-
634
- if (isSyntheticShadowRoot(rootNode)) {
635
- rootNode = getHost(rootNode);
636
- }
637
-
638
- return rootNode;
639
- }
640
-
641
600
  const customElementToWrappedListeners = new WeakMap();
642
601
 
643
602
  function getEventMap(elm) {
@@ -681,16 +640,9 @@ function getWrappedShadowRootListener(listener) {
681
640
  currentTarget = getShadowRoot(currentTarget);
682
641
  }
683
642
 
684
- let shouldInvoke;
643
+ const actualTarget = getActualTarget(event);
685
644
 
686
- if (runtimeFlags.ENABLE_NON_COMPOSED_EVENTS_LEAKAGE) {
687
- shouldInvoke = shouldInvokeShadowRootListener(event);
688
- } else {
689
- const actualTarget = getActualTarget(event);
690
- shouldInvoke = shouldInvokeListener(event, actualTarget, currentTarget);
691
- }
692
-
693
- if (shouldInvoke) {
645
+ if (shouldInvokeListener(event, actualTarget, currentTarget)) {
694
646
  listener.call(currentTarget, event);
695
647
  }
696
648
  };
@@ -717,16 +669,9 @@ function getWrappedCustomElementListener(listener) {
717
669
  customElementWrappedListener = function (event) {
718
670
  // currentTarget is always defined inside an event listener
719
671
  const currentTarget = eventCurrentTargetGetter.call(event);
720
- let shouldInvoke;
672
+ const actualTarget = getActualTarget(event);
721
673
 
722
- if (runtimeFlags.ENABLE_NON_COMPOSED_EVENTS_LEAKAGE) {
723
- shouldInvoke = shouldInvokeCustomElementListener(event);
724
- } else {
725
- const actualTarget = getActualTarget(event);
726
- shouldInvoke = shouldInvokeListener(event, actualTarget, currentTarget);
727
- }
728
-
729
- if (shouldInvoke) {
674
+ if (shouldInvokeListener(event, actualTarget, currentTarget)) {
730
675
  listener.call(currentTarget, event);
731
676
  }
732
677
  };
@@ -847,70 +792,6 @@ function detachDOMListener(elm, type, wrappedListener) {
847
792
  }
848
793
  }
849
794
 
850
- function shouldInvokeCustomElementListener(event) {
851
- const {
852
- composed
853
- } = event;
854
-
855
- if (isTrue(composed)) {
856
- // Listeners on host elements should always be invoked for {composed: true} events.
857
- return true;
858
- } // If this {composed: false} event was dispatched on any root.
859
-
860
-
861
- if (eventToShadowRootMap.has(event)) {
862
- return false;
863
- }
864
-
865
- const target = eventTargetGetter.call(event);
866
- const currentTarget = eventCurrentTargetGetter.call(event); // If this {composed: false} event was dispatched on the current target host.
867
-
868
- if (target === currentTarget) {
869
- return true;
870
- } // At this point the event must be {bubbles: true, composed: false} and was dispatched from a
871
- // shadow-excluding descendant node. In this case, we only invoke the listener if the target
872
- // host was assigned to a slot in the composed subtree of the current target host.
873
-
874
-
875
- const targetHost = getRootNodeHost(target, GET_ROOT_NODE_CONFIG_FALSE);
876
- const currentTargetHost = currentTarget;
877
- return isChildNode(targetHost, currentTargetHost);
878
- }
879
-
880
- function shouldInvokeShadowRootListener(event) {
881
- const {
882
- composed
883
- } = event;
884
- const target = eventTargetGetter.call(event);
885
- const currentTarget = eventCurrentTargetGetter.call(event); // If the event was dispatched on the host or its root.
886
-
887
- if (target === currentTarget) {
888
- // Invoke the listener if the event was dispatched directly on the root.
889
- return eventToShadowRootMap.get(event) === getShadowRoot(target);
890
- } // At this point the event is {bubbles: true} and was dispatched from a shadow-including descendant node.
891
-
892
-
893
- if (isTrue(composed)) {
894
- // Invoke the listener if the event is {composed: true}.
895
- return true;
896
- } // At this point the event must be {bubbles: true, composed: false}.
897
-
898
-
899
- if (isTrue(eventToShadowRootMap.has(event))) {
900
- // Don't invoke the listener because the event was dispatched on a descendant root.
901
- return false;
902
- }
903
-
904
- const targetHost = getRootNodeHost(target, GET_ROOT_NODE_CONFIG_FALSE);
905
- const currentTargetHost = currentTarget;
906
- const isCurrentTargetSlotted = isChildNode(targetHost, currentTargetHost); // At this point the event must be {bubbles: true, composed: false} and was dispatched from a
907
- // shadow-excluding descendant node. In this case, we only invoke the listener if the target
908
- // host was assigned to a slot in the composed subtree of the current target host, or the
909
- // descendant node is in the shadow tree of the current root.
910
-
911
- return isCurrentTargetSlotted || targetHost === currentTargetHost;
912
- }
913
-
914
795
  function addCustomElementEventListener(type, listener, _options) {
915
796
  if (process.env.NODE_ENV !== 'production') {
916
797
  if (!isFunction(listener)) {
@@ -1019,6 +900,14 @@ function getNodeKey(node) {
1019
900
  function isNodeShadowed(node) {
1020
901
  return !isUndefined(getNodeOwnerKey(node));
1021
902
  }
903
+ /**
904
+ * Returns true if this node is a shadow host, is in a shadow host, or contains a shadow host
905
+ * anywhere in its tree.
906
+ */
907
+
908
+ function isNodeOrDescendantsShadowed(node) {
909
+ return isNodeShadowed(node) || isSyntheticShadowHost(node) || containsHost(node);
910
+ }
1022
911
 
1023
912
  /*
1024
913
  * Copyright (c) 2018, salesforce.com, inc.
@@ -1632,6 +1521,19 @@ function getOuterHTML(node) {
1632
1521
  }
1633
1522
  }
1634
1523
 
1524
+ /**
1525
+ * Copyright (C) 2018 salesforce.com, inc.
1526
+ */
1527
+
1528
+ if (!_globalThis.lwcRuntimeFlags) {
1529
+ Object.defineProperty(_globalThis, 'lwcRuntimeFlags', {
1530
+ value: create(null)
1531
+ });
1532
+ }
1533
+
1534
+ const runtimeFlags = _globalThis.lwcRuntimeFlags;
1535
+ /** version: 2.6.3 */
1536
+
1635
1537
  /*
1636
1538
  * Copyright (c) 2018, salesforce.com, inc.
1637
1539
  * All rights reserved.
@@ -1723,7 +1625,9 @@ function parentElementGetterPatched() {
1723
1625
  }
1724
1626
 
1725
1627
  function compareDocumentPositionPatched(otherNode) {
1726
- if (this.getRootNode() === otherNode) {
1628
+ if (this === otherNode) {
1629
+ return 0;
1630
+ } else if (this.getRootNode() === otherNode) {
1727
1631
  // "this" is in a shadow tree where the shadow root is the "otherNode".
1728
1632
  return 10; // Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING
1729
1633
  } else if (getNodeOwnerKey(this) !== getNodeOwnerKey(otherNode)) {
@@ -1769,7 +1673,7 @@ function cloneNodePatched(deep) {
1769
1673
  function childNodesGetterPatched() {
1770
1674
  if (isSyntheticShadowHost(this)) {
1771
1675
  const owner = getNodeOwner(this);
1772
- const childNodes = isNull(owner) ? [] : getAllMatches(owner, getFilteredChildNodes(this));
1676
+ const childNodes = isNull(owner) ? getFilteredChildNodes(this) : getAllMatches(owner, getFilteredChildNodes(this));
1773
1677
 
1774
1678
  if (process.env.NODE_ENV !== 'production' && isFalse(hasNativeSymbolSupport) && isExternalChildNodeAccessorFlagOn()) {
1775
1679
  // inserting a comment node as the first childNode to trick the IE11
@@ -1880,7 +1784,8 @@ defineProperties(_Node.prototype, {
1880
1784
  textContent: {
1881
1785
  get() {
1882
1786
  if (!runtimeFlags.ENABLE_NODE_PATCH) {
1883
- if (isNodeShadowed(this) || isSyntheticShadowHost(this)) {
1787
+ // See note on get innerHTML in faux-shadow/element.ts
1788
+ if (isNodeOrDescendantsShadowed(this)) {
1884
1789
  return textContentGetterPatched.call(this);
1885
1790
  }
1886
1791
 
@@ -2114,7 +2019,22 @@ function getAllRootNodes(node) {
2114
2019
  }
2115
2020
 
2116
2021
  return rootNodes;
2117
- }
2022
+ } // Keep searching up the host tree until we find an element that is within the immediate shadow root
2023
+
2024
+
2025
+ const findAncestorHostInImmediateShadowRoot = (rootNode, targetRootNode) => {
2026
+ let host;
2027
+
2028
+ while (!isUndefined(host = rootNode.host)) {
2029
+ const thisRootNode = host.getRootNode();
2030
+
2031
+ if (thisRootNode === targetRootNode) {
2032
+ return host;
2033
+ }
2034
+
2035
+ rootNode = thisRootNode;
2036
+ }
2037
+ };
2118
2038
 
2119
2039
  function fauxElementsFromPoint(context, doc, left, top) {
2120
2040
  const elements = elementsFromPoint.call(doc, left, top);
@@ -2128,8 +2048,28 @@ function fauxElementsFromPoint(context, doc, left, top) {
2128
2048
  for (let i = 0; i < elements.length; i++) {
2129
2049
  const element = elements[i];
2130
2050
 
2131
- if (rootNodes.indexOf(element.getRootNode()) !== -1 && !isSyntheticSlotElement(element)) {
2132
- result.push(element);
2051
+ if (isSyntheticSlotElement(element)) {
2052
+ continue;
2053
+ }
2054
+
2055
+ const elementRootNode = element.getRootNode();
2056
+
2057
+ if (ArrayIndexOf.call(rootNodes, elementRootNode) !== -1) {
2058
+ ArrayPush.call(result, element);
2059
+ continue;
2060
+ } // In cases where the host element is not visible but its shadow descendants are, then
2061
+ // we may get the shadow descendant instead of the host element here. (The
2062
+ // browser doesn't know the difference in synthetic shadow DOM.)
2063
+ // In native shadow DOM, however, elementsFromPoint would return the host but not
2064
+ // the child. So we need to detect if this shadow element's host is accessible from
2065
+ // the context's shadow root. Note we also need to be careful not to add the host
2066
+ // multiple times.
2067
+
2068
+
2069
+ const ancestorHost = findAncestorHostInImmediateShadowRoot(elementRootNode, rootNodes[0]);
2070
+
2071
+ if (!isUndefined(ancestorHost) && ArrayIndexOf.call(elements, ancestorHost) === -1 && ArrayIndexOf.call(result, ancestorHost) === -1) {
2072
+ ArrayPush.call(result, ancestorHost);
2133
2073
  }
2134
2074
  }
2135
2075
  }
@@ -2203,6 +2143,28 @@ function isSyntheticShadowHost(node) {
2203
2143
  function isSyntheticShadowRoot(node) {
2204
2144
  const shadowRootRecord = InternalSlot.get(node);
2205
2145
  return !isUndefined(shadowRootRecord) && node === shadowRootRecord.shadowRoot;
2146
+ } // Return true if any descendant is a host element
2147
+
2148
+ function containsHost(node) {
2149
+ // IE11 complains with "Unexpected call to method or property access." when calling walker.nextNode().
2150
+ // The fix for this is to only walk trees for nodes that are Node.ELEMENT_NODE.
2151
+ if (node.nodeType !== _Node.ELEMENT_NODE) {
2152
+ return false;
2153
+ } // IE requires all four arguments, even though the fourth is deprecated
2154
+ // https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker#browser_compatibility
2155
+ // @ts-ignore
2156
+
2157
+
2158
+ const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, null, false);
2159
+ let descendant;
2160
+
2161
+ while (!isNull(descendant = walker.nextNode())) {
2162
+ if (isSyntheticShadowHost(descendant)) {
2163
+ return true;
2164
+ }
2165
+ }
2166
+
2167
+ return false;
2206
2168
  }
2207
2169
  let uid = 0;
2208
2170
  function attachShadow(elm, options) {
@@ -2250,6 +2212,12 @@ const SyntheticShadowRootDescriptors = {
2250
2212
  return `[object ShadowRoot]`;
2251
2213
  }
2252
2214
 
2215
+ },
2216
+ synthetic: {
2217
+ writable: false,
2218
+ enumerable: false,
2219
+ configurable: false,
2220
+ value: true
2253
2221
  }
2254
2222
  };
2255
2223
  const ShadowRootDescriptors = {
@@ -4078,6 +4046,14 @@ retargetRelatedTarget(FocusEvent);
4078
4046
  */
4079
4047
  retargetRelatedTarget(MouseEvent);
4080
4048
 
4049
+ /*
4050
+ * Copyright (c) 2021, salesforce.com, inc.
4051
+ * All rights reserved.
4052
+ * SPDX-License-Identifier: MIT
4053
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
4054
+ */
4055
+ const assignedSlotGetter = hasOwnProperty.call(Text.prototype, 'assignedSlot') ? getOwnPropertyDescriptor(Text.prototype, 'assignedSlot').get : () => null;
4056
+
4081
4057
  /*
4082
4058
  * Copyright (c) 2018, salesforce.com, inc.
4083
4059
  * All rights reserved.
@@ -4131,10 +4107,22 @@ function getFilteredSlotFlattenNodes(slot) {
4131
4107
  }
4132
4108
 
4133
4109
  function assignedSlotGetterPatched() {
4134
- const parentNode = parentNodeGetter.call(this);
4110
+ const parentNode = parentNodeGetter.call(this); // use original assignedSlot if parent has a native shdow root
4111
+
4112
+ if (parentNode instanceof Element) {
4113
+ const sr = shadowRootGetter.call(parentNode);
4114
+
4115
+ if (isInstanceOfNativeShadowRoot(sr)) {
4116
+ if (this instanceof Text) {
4117
+ return assignedSlotGetter.call(this);
4118
+ }
4119
+
4120
+ return assignedSlotGetter$1.call(this);
4121
+ }
4122
+ }
4135
4123
  /**
4136
4124
  * The node is assigned to a slot if:
4137
- * - it has a parent and it parent its parent is a slot element
4125
+ * - it has a parent and its parent is a slot element
4138
4126
  * - and if the slot owner key is different than the node owner key.
4139
4127
  *
4140
4128
  * When the slot and the slotted node are 2 different shadow trees, the owner keys will be
@@ -4143,6 +4131,7 @@ function assignedSlotGetterPatched() {
4143
4131
  * different than the node owner key (always `undefined`).
4144
4132
  */
4145
4133
 
4134
+
4146
4135
  if (!isNull(parentNode) && isSlotElement(parentNode) && getNodeOwnerKey(parentNode) !== getNodeOwnerKey(this)) {
4147
4136
  return parentNode;
4148
4137
  }
@@ -4359,7 +4348,10 @@ defineProperties(Element.prototype, {
4359
4348
  innerHTML: {
4360
4349
  get() {
4361
4350
  if (!runtimeFlags.ENABLE_ELEMENT_PATCH) {
4362
- if (isNodeShadowed(this) || isSyntheticShadowHost(this)) {
4351
+ // If this element is in synthetic shadow, if it's a synthetic shadow host,
4352
+ // or if any of its descendants are synthetic shadow hosts, then we can't
4353
+ // use the native innerHTML because it would expose private node internals.
4354
+ if (isNodeOrDescendantsShadowed(this)) {
4363
4355
  return innerHTMLGetterPatched.call(this);
4364
4356
  }
4365
4357
 
@@ -4384,7 +4376,8 @@ defineProperties(Element.prototype, {
4384
4376
  outerHTML: {
4385
4377
  get() {
4386
4378
  if (!runtimeFlags.ENABLE_ELEMENT_PATCH) {
4387
- if (isNodeShadowed(this) || isSyntheticShadowHost(this)) {
4379
+ // See notes above on get innerHTML
4380
+ if (isNodeOrDescendantsShadowed(this)) {
4388
4381
  return outerHTMLGetterPatched.call(this);
4389
4382
  }
4390
4383
 
@@ -5757,4 +5750,4 @@ defineProperty(Element.prototype, '$domManual$', {
5757
5750
 
5758
5751
  configurable: true
5759
5752
  });
5760
- /** version: 2.5.11 */
5753
+ /** version: 2.6.3 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/synthetic-shadow",
3
- "version": "2.5.11",
3
+ "version": "2.6.3",
4
4
  "description": "Synthetic Shadow Root for LWC",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -36,8 +36,8 @@
36
36
  "access": "public"
37
37
  },
38
38
  "devDependencies": {
39
- "@lwc/features": "2.5.11",
40
- "@lwc/shared": "2.5.11"
39
+ "@lwc/features": "2.6.3",
40
+ "@lwc/shared": "2.6.3"
41
41
  },
42
- "gitHead": "2e72bcacbf105ef92277372bb4e52f8280d7fa72"
42
+ "gitHead": "1fdd835243eed190b8ab9ca61ae7eae9f9a4073d"
43
43
  }