floating-ui.utils.dom.umd.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIUtilsDOM = {}));
  5. })(this, (function (exports) { 'use strict';
  6. function getNodeName(node) {
  7. if (isNode(node)) {
  8. return (node.nodeName || '').toLowerCase();
  9. }
  10. // Mocked nodes in testing environments may not be instances of Node. By
  11. // returning `#document` an infinite loop won't occur.
  12. // https://github.com/floating-ui/floating-ui/issues/2317
  13. return '#document';
  14. }
  15. function getWindow(node) {
  16. var _node$ownerDocument;
  17. return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
  18. }
  19. function getDocumentElement(node) {
  20. var _ref;
  21. return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
  22. }
  23. function isNode(value) {
  24. return value instanceof Node || value instanceof getWindow(value).Node;
  25. }
  26. function isElement(value) {
  27. return value instanceof Element || value instanceof getWindow(value).Element;
  28. }
  29. function isHTMLElement(value) {
  30. return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
  31. }
  32. function isShadowRoot(value) {
  33. // Browsers without `ShadowRoot` support.
  34. if (typeof ShadowRoot === 'undefined') {
  35. return false;
  36. }
  37. return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
  38. }
  39. function isOverflowElement(element) {
  40. const {
  41. overflow,
  42. overflowX,
  43. overflowY,
  44. display
  45. } = getComputedStyle(element);
  46. return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
  47. }
  48. function isTableElement(element) {
  49. return ['table', 'td', 'th'].includes(getNodeName(element));
  50. }
  51. function isContainingBlock(element) {
  52. const webkit = isWebKit();
  53. const css = getComputedStyle(element);
  54. // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
  55. return css.transform !== 'none' || css.perspective !== 'none' || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective', 'filter'].some(value => (css.willChange || '').includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => (css.contain || '').includes(value));
  56. }
  57. function getContainingBlock(element) {
  58. let currentNode = getParentNode(element);
  59. while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
  60. if (isContainingBlock(currentNode)) {
  61. return currentNode;
  62. } else {
  63. currentNode = getParentNode(currentNode);
  64. }
  65. }
  66. return null;
  67. }
  68. function isWebKit() {
  69. if (typeof CSS === 'undefined' || !CSS.supports) return false;
  70. return CSS.supports('-webkit-backdrop-filter', 'none');
  71. }
  72. function isLastTraversableNode(node) {
  73. return ['html', 'body', '#document'].includes(getNodeName(node));
  74. }
  75. function getComputedStyle(element) {
  76. return getWindow(element).getComputedStyle(element);
  77. }
  78. function getNodeScroll(element) {
  79. if (isElement(element)) {
  80. return {
  81. scrollLeft: element.scrollLeft,
  82. scrollTop: element.scrollTop
  83. };
  84. }
  85. return {
  86. scrollLeft: element.pageXOffset,
  87. scrollTop: element.pageYOffset
  88. };
  89. }
  90. function getParentNode(node) {
  91. if (getNodeName(node) === 'html') {
  92. return node;
  93. }
  94. const result =
  95. // Step into the shadow DOM of the parent of a slotted node.
  96. node.assignedSlot ||
  97. // DOM Element detected.
  98. node.parentNode ||
  99. // ShadowRoot detected.
  100. isShadowRoot(node) && node.host ||
  101. // Fallback.
  102. getDocumentElement(node);
  103. return isShadowRoot(result) ? result.host : result;
  104. }
  105. function getNearestOverflowAncestor(node) {
  106. const parentNode = getParentNode(node);
  107. if (isLastTraversableNode(parentNode)) {
  108. return node.ownerDocument ? node.ownerDocument.body : node.body;
  109. }
  110. if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
  111. return parentNode;
  112. }
  113. return getNearestOverflowAncestor(parentNode);
  114. }
  115. function getOverflowAncestors(node, list, traverseIframes) {
  116. var _node$ownerDocument2;
  117. if (list === void 0) {
  118. list = [];
  119. }
  120. if (traverseIframes === void 0) {
  121. traverseIframes = true;
  122. }
  123. const scrollableAncestor = getNearestOverflowAncestor(node);
  124. const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
  125. const win = getWindow(scrollableAncestor);
  126. if (isBody) {
  127. return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], win.frameElement && traverseIframes ? getOverflowAncestors(win.frameElement) : []);
  128. }
  129. return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
  130. }
  131. exports.getComputedStyle = getComputedStyle;
  132. exports.getContainingBlock = getContainingBlock;
  133. exports.getDocumentElement = getDocumentElement;
  134. exports.getNearestOverflowAncestor = getNearestOverflowAncestor;
  135. exports.getNodeName = getNodeName;
  136. exports.getNodeScroll = getNodeScroll;
  137. exports.getOverflowAncestors = getOverflowAncestors;
  138. exports.getParentNode = getParentNode;
  139. exports.getWindow = getWindow;
  140. exports.isContainingBlock = isContainingBlock;
  141. exports.isElement = isElement;
  142. exports.isHTMLElement = isHTMLElement;
  143. exports.isLastTraversableNode = isLastTraversableNode;
  144. exports.isNode = isNode;
  145. exports.isOverflowElement = isOverflowElement;
  146. exports.isShadowRoot = isShadowRoot;
  147. exports.isTableElement = isTableElement;
  148. exports.isWebKit = isWebKit;
  149. }));