版博士V2.0程序
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

709 строки
25 KiB

  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@floating-ui/core')) :
  3. typeof define === 'function' && define.amd ? define(['exports', '@floating-ui/core'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.FloatingUIDOM = {}, global.FloatingUICore));
  5. })(this, (function (exports, core) { 'use strict';
  6. function getWindow(node) {
  7. var _node$ownerDocument;
  8. return ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
  9. }
  10. function getComputedStyle$1(element) {
  11. return getWindow(element).getComputedStyle(element);
  12. }
  13. function isNode(value) {
  14. return value instanceof getWindow(value).Node;
  15. }
  16. function getNodeName(node) {
  17. return isNode(node) ? (node.nodeName || '').toLowerCase() : '';
  18. }
  19. let uaString;
  20. function getUAString() {
  21. if (uaString) {
  22. return uaString;
  23. }
  24. const uaData = navigator.userAgentData;
  25. if (uaData && Array.isArray(uaData.brands)) {
  26. uaString = uaData.brands.map(item => item.brand + "/" + item.version).join(' ');
  27. return uaString;
  28. }
  29. return navigator.userAgent;
  30. }
  31. function isHTMLElement(value) {
  32. return value instanceof getWindow(value).HTMLElement;
  33. }
  34. function isElement(value) {
  35. return value instanceof getWindow(value).Element;
  36. }
  37. function isShadowRoot(node) {
  38. // Browsers without `ShadowRoot` support.
  39. if (typeof ShadowRoot === 'undefined') {
  40. return false;
  41. }
  42. const OwnElement = getWindow(node).ShadowRoot;
  43. return node instanceof OwnElement || node instanceof ShadowRoot;
  44. }
  45. function isOverflowElement(element) {
  46. const {
  47. overflow,
  48. overflowX,
  49. overflowY,
  50. display
  51. } = getComputedStyle$1(element);
  52. return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
  53. }
  54. function isTableElement(element) {
  55. return ['table', 'td', 'th'].includes(getNodeName(element));
  56. }
  57. function isContainingBlock(element) {
  58. // TODO: Try to use feature detection here instead.
  59. const isFirefox = /firefox/i.test(getUAString());
  60. const css = getComputedStyle$1(element);
  61. const backdropFilter = css.backdropFilter || css.WebkitBackdropFilter;
  62. // This is non-exhaustive but covers the most common CSS properties that
  63. // create a containing block.
  64. // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
  65. return css.transform !== 'none' || css.perspective !== 'none' || (backdropFilter ? backdropFilter !== 'none' : false) || isFirefox && css.willChange === 'filter' || isFirefox && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective'].some(value => css.willChange.includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => {
  66. // Add type check for old browsers.
  67. const contain = css.contain;
  68. return contain != null ? contain.includes(value) : false;
  69. });
  70. }
  71. /**
  72. * Determines whether or not `.getBoundingClientRect()` is affected by visual
  73. * viewport offsets. In Safari, the `x`/`y` offsets are values relative to the
  74. * visual viewport, while in other engines, they are values relative to the
  75. * layout viewport.
  76. */
  77. function isClientRectVisualViewportBased() {
  78. // TODO: Try to use feature detection here instead. Feature detection for
  79. // this can fail in various ways, making the userAgent check the most
  80. // reliable:
  81. // • Always-visible scrollbar or not
  82. // • Width of <html>
  83. // Is Safari.
  84. return /^((?!chrome|android).)*safari/i.test(getUAString());
  85. }
  86. function isLastTraversableNode(node) {
  87. return ['html', 'body', '#document'].includes(getNodeName(node));
  88. }
  89. const min = Math.min;
  90. const max = Math.max;
  91. const round = Math.round;
  92. function getCssDimensions(element) {
  93. const css = getComputedStyle$1(element);
  94. let width = parseFloat(css.width);
  95. let height = parseFloat(css.height);
  96. const hasOffset = isHTMLElement(element);
  97. const offsetWidth = hasOffset ? element.offsetWidth : width;
  98. const offsetHeight = hasOffset ? element.offsetHeight : height;
  99. const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
  100. if (shouldFallback) {
  101. width = offsetWidth;
  102. height = offsetHeight;
  103. }
  104. return {
  105. width,
  106. height,
  107. fallback: shouldFallback
  108. };
  109. }
  110. function unwrapElement(element) {
  111. return !isElement(element) ? element.contextElement : element;
  112. }
  113. const FALLBACK_SCALE = {
  114. x: 1,
  115. y: 1
  116. };
  117. function getScale(element) {
  118. const domElement = unwrapElement(element);
  119. if (!isHTMLElement(domElement)) {
  120. return FALLBACK_SCALE;
  121. }
  122. const rect = domElement.getBoundingClientRect();
  123. const {
  124. width,
  125. height,
  126. fallback
  127. } = getCssDimensions(domElement);
  128. let x = (fallback ? round(rect.width) : rect.width) / width;
  129. let y = (fallback ? round(rect.height) : rect.height) / height;
  130. // 0, NaN, or Infinity should always fallback to 1.
  131. if (!x || !Number.isFinite(x)) {
  132. x = 1;
  133. }
  134. if (!y || !Number.isFinite(y)) {
  135. y = 1;
  136. }
  137. return {
  138. x,
  139. y
  140. };
  141. }
  142. function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
  143. var _win$visualViewport, _win$visualViewport2;
  144. if (includeScale === void 0) {
  145. includeScale = false;
  146. }
  147. if (isFixedStrategy === void 0) {
  148. isFixedStrategy = false;
  149. }
  150. const clientRect = element.getBoundingClientRect();
  151. const domElement = unwrapElement(element);
  152. let scale = FALLBACK_SCALE;
  153. if (includeScale) {
  154. if (offsetParent) {
  155. if (isElement(offsetParent)) {
  156. scale = getScale(offsetParent);
  157. }
  158. } else {
  159. scale = getScale(element);
  160. }
  161. }
  162. const win = domElement ? getWindow(domElement) : window;
  163. const addVisualOffsets = isClientRectVisualViewportBased() && isFixedStrategy;
  164. let x = (clientRect.left + (addVisualOffsets ? ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0 : 0)) / scale.x;
  165. let y = (clientRect.top + (addVisualOffsets ? ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0 : 0)) / scale.y;
  166. let width = clientRect.width / scale.x;
  167. let height = clientRect.height / scale.y;
  168. if (domElement) {
  169. const win = getWindow(domElement);
  170. const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
  171. let currentIFrame = win.frameElement;
  172. while (currentIFrame && offsetParent && offsetWin !== win) {
  173. const iframeScale = getScale(currentIFrame);
  174. const iframeRect = currentIFrame.getBoundingClientRect();
  175. const css = getComputedStyle(currentIFrame);
  176. iframeRect.x += (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
  177. iframeRect.y += (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
  178. x *= iframeScale.x;
  179. y *= iframeScale.y;
  180. width *= iframeScale.x;
  181. height *= iframeScale.y;
  182. x += iframeRect.x;
  183. y += iframeRect.y;
  184. currentIFrame = getWindow(currentIFrame).frameElement;
  185. }
  186. }
  187. return core.rectToClientRect({
  188. width,
  189. height,
  190. x,
  191. y
  192. });
  193. }
  194. function getDocumentElement(node) {
  195. return ((isNode(node) ? node.ownerDocument : node.document) || window.document).documentElement;
  196. }
  197. function getNodeScroll(element) {
  198. if (isElement(element)) {
  199. return {
  200. scrollLeft: element.scrollLeft,
  201. scrollTop: element.scrollTop
  202. };
  203. }
  204. return {
  205. scrollLeft: element.pageXOffset,
  206. scrollTop: element.pageYOffset
  207. };
  208. }
  209. function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
  210. let {
  211. rect,
  212. offsetParent,
  213. strategy
  214. } = _ref;
  215. const isOffsetParentAnElement = isHTMLElement(offsetParent);
  216. const documentElement = getDocumentElement(offsetParent);
  217. if (offsetParent === documentElement) {
  218. return rect;
  219. }
  220. let scroll = {
  221. scrollLeft: 0,
  222. scrollTop: 0
  223. };
  224. let scale = {
  225. x: 1,
  226. y: 1
  227. };
  228. const offsets = {
  229. x: 0,
  230. y: 0
  231. };
  232. if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
  233. if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
  234. scroll = getNodeScroll(offsetParent);
  235. }
  236. if (isHTMLElement(offsetParent)) {
  237. const offsetRect = getBoundingClientRect(offsetParent);
  238. scale = getScale(offsetParent);
  239. offsets.x = offsetRect.x + offsetParent.clientLeft;
  240. offsets.y = offsetRect.y + offsetParent.clientTop;
  241. }
  242. }
  243. return {
  244. width: rect.width * scale.x,
  245. height: rect.height * scale.y,
  246. x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
  247. y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y
  248. };
  249. }
  250. function getWindowScrollBarX(element) {
  251. // If <html> has a CSS width greater than the viewport, then this will be
  252. // incorrect for RTL.
  253. return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft;
  254. }
  255. // Gets the entire size of the scrollable document area, even extending outside
  256. // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
  257. function getDocumentRect(element) {
  258. const html = getDocumentElement(element);
  259. const scroll = getNodeScroll(element);
  260. const body = element.ownerDocument.body;
  261. const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
  262. const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
  263. let x = -scroll.scrollLeft + getWindowScrollBarX(element);
  264. const y = -scroll.scrollTop;
  265. if (getComputedStyle$1(body).direction === 'rtl') {
  266. x += max(html.clientWidth, body.clientWidth) - width;
  267. }
  268. return {
  269. width,
  270. height,
  271. x,
  272. y
  273. };
  274. }
  275. function getParentNode(node) {
  276. if (getNodeName(node) === 'html') {
  277. return node;
  278. }
  279. const result =
  280. // Step into the shadow DOM of the parent of a slotted node.
  281. node.assignedSlot ||
  282. // DOM Element detected.
  283. node.parentNode ||
  284. // ShadowRoot detected.
  285. isShadowRoot(node) && node.host ||
  286. // Fallback.
  287. getDocumentElement(node);
  288. return isShadowRoot(result) ? result.host : result;
  289. }
  290. function getNearestOverflowAncestor(node) {
  291. const parentNode = getParentNode(node);
  292. if (isLastTraversableNode(parentNode)) {
  293. // `getParentNode` will never return a `Document` due to the fallback
  294. // check, so it's either the <html> or <body> element.
  295. return parentNode.ownerDocument.body;
  296. }
  297. if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
  298. return parentNode;
  299. }
  300. return getNearestOverflowAncestor(parentNode);
  301. }
  302. function getOverflowAncestors(node, list) {
  303. var _node$ownerDocument;
  304. if (list === void 0) {
  305. list = [];
  306. }
  307. const scrollableAncestor = getNearestOverflowAncestor(node);
  308. const isBody = scrollableAncestor === ((_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.body);
  309. const win = getWindow(scrollableAncestor);
  310. if (isBody) {
  311. return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : []);
  312. }
  313. return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor));
  314. }
  315. function getViewportRect(element, strategy) {
  316. const win = getWindow(element);
  317. const html = getDocumentElement(element);
  318. const visualViewport = win.visualViewport;
  319. let width = html.clientWidth;
  320. let height = html.clientHeight;
  321. let x = 0;
  322. let y = 0;
  323. if (visualViewport) {
  324. width = visualViewport.width;
  325. height = visualViewport.height;
  326. const visualViewportBased = isClientRectVisualViewportBased();
  327. if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
  328. x = visualViewport.offsetLeft;
  329. y = visualViewport.offsetTop;
  330. }
  331. }
  332. return {
  333. width,
  334. height,
  335. x,
  336. y
  337. };
  338. }
  339. // Returns the inner client rect, subtracting scrollbars if present.
  340. function getInnerBoundingClientRect(element, strategy) {
  341. const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
  342. const top = clientRect.top + element.clientTop;
  343. const left = clientRect.left + element.clientLeft;
  344. const scale = isHTMLElement(element) ? getScale(element) : {
  345. x: 1,
  346. y: 1
  347. };
  348. const width = element.clientWidth * scale.x;
  349. const height = element.clientHeight * scale.y;
  350. const x = left * scale.x;
  351. const y = top * scale.y;
  352. return {
  353. width,
  354. height,
  355. x,
  356. y
  357. };
  358. }
  359. function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
  360. let rect;
  361. if (clippingAncestor === 'viewport') {
  362. rect = getViewportRect(element, strategy);
  363. } else if (clippingAncestor === 'document') {
  364. rect = getDocumentRect(getDocumentElement(element));
  365. } else if (isElement(clippingAncestor)) {
  366. rect = getInnerBoundingClientRect(clippingAncestor, strategy);
  367. } else {
  368. const mutableRect = {
  369. ...clippingAncestor
  370. };
  371. if (isClientRectVisualViewportBased()) {
  372. var _win$visualViewport, _win$visualViewport2;
  373. const win = getWindow(element);
  374. mutableRect.x -= ((_win$visualViewport = win.visualViewport) == null ? void 0 : _win$visualViewport.offsetLeft) || 0;
  375. mutableRect.y -= ((_win$visualViewport2 = win.visualViewport) == null ? void 0 : _win$visualViewport2.offsetTop) || 0;
  376. }
  377. rect = mutableRect;
  378. }
  379. return core.rectToClientRect(rect);
  380. }
  381. // A "clipping ancestor" is an `overflow` element with the characteristic of
  382. // clipping (or hiding) child elements. This returns all clipping ancestors
  383. // of the given element up the tree.
  384. function getClippingElementAncestors(element, cache) {
  385. const cachedResult = cache.get(element);
  386. if (cachedResult) {
  387. return cachedResult;
  388. }
  389. let result = getOverflowAncestors(element).filter(el => isElement(el) && getNodeName(el) !== 'body');
  390. let currentContainingBlockComputedStyle = null;
  391. const elementIsFixed = getComputedStyle$1(element).position === 'fixed';
  392. let currentNode = elementIsFixed ? getParentNode(element) : element;
  393. // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
  394. while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
  395. const computedStyle = getComputedStyle$1(currentNode);
  396. const containingBlock = isContainingBlock(currentNode);
  397. if (computedStyle.position === 'fixed') {
  398. currentContainingBlockComputedStyle = null;
  399. }
  400. const shouldDropCurrentNode = elementIsFixed ? !containingBlock && !currentContainingBlockComputedStyle : !containingBlock && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position);
  401. if (shouldDropCurrentNode) {
  402. // Drop non-containing blocks.
  403. result = result.filter(ancestor => ancestor !== currentNode);
  404. } else {
  405. // Record last containing block for next iteration.
  406. currentContainingBlockComputedStyle = computedStyle;
  407. }
  408. currentNode = getParentNode(currentNode);
  409. }
  410. cache.set(element, result);
  411. return result;
  412. }
  413. // Gets the maximum area that the element is visible in due to any number of
  414. // clipping ancestors.
  415. function getClippingRect(_ref) {
  416. let {
  417. element,
  418. boundary,
  419. rootBoundary,
  420. strategy
  421. } = _ref;
  422. const elementClippingAncestors = boundary === 'clippingAncestors' ? getClippingElementAncestors(element, this._c) : [].concat(boundary);
  423. const clippingAncestors = [...elementClippingAncestors, rootBoundary];
  424. const firstClippingAncestor = clippingAncestors[0];
  425. const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
  426. const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
  427. accRect.top = max(rect.top, accRect.top);
  428. accRect.right = min(rect.right, accRect.right);
  429. accRect.bottom = min(rect.bottom, accRect.bottom);
  430. accRect.left = max(rect.left, accRect.left);
  431. return accRect;
  432. }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
  433. return {
  434. width: clippingRect.right - clippingRect.left,
  435. height: clippingRect.bottom - clippingRect.top,
  436. x: clippingRect.left,
  437. y: clippingRect.top
  438. };
  439. }
  440. function getDimensions(element) {
  441. return getCssDimensions(element);
  442. }
  443. function getTrueOffsetParent(element, polyfill) {
  444. if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {
  445. return null;
  446. }
  447. if (polyfill) {
  448. return polyfill(element);
  449. }
  450. return element.offsetParent;
  451. }
  452. function getContainingBlock(element) {
  453. let currentNode = getParentNode(element);
  454. while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
  455. if (isContainingBlock(currentNode)) {
  456. return currentNode;
  457. } else {
  458. currentNode = getParentNode(currentNode);
  459. }
  460. }
  461. return null;
  462. }
  463. // Gets the closest ancestor positioned element. Handles some edge cases,
  464. // such as table ancestors and cross browser bugs.
  465. function getOffsetParent(element, polyfill) {
  466. const window = getWindow(element);
  467. if (!isHTMLElement(element)) {
  468. return window;
  469. }
  470. let offsetParent = getTrueOffsetParent(element, polyfill);
  471. while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
  472. offsetParent = getTrueOffsetParent(offsetParent, polyfill);
  473. }
  474. if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static' && !isContainingBlock(offsetParent))) {
  475. return window;
  476. }
  477. return offsetParent || getContainingBlock(element) || window;
  478. }
  479. function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
  480. const isOffsetParentAnElement = isHTMLElement(offsetParent);
  481. const documentElement = getDocumentElement(offsetParent);
  482. const rect = getBoundingClientRect(element, true, strategy === 'fixed', offsetParent);
  483. let scroll = {
  484. scrollLeft: 0,
  485. scrollTop: 0
  486. };
  487. const offsets = {
  488. x: 0,
  489. y: 0
  490. };
  491. if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== 'fixed') {
  492. if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
  493. scroll = getNodeScroll(offsetParent);
  494. }
  495. if (isHTMLElement(offsetParent)) {
  496. const offsetRect = getBoundingClientRect(offsetParent, true);
  497. offsets.x = offsetRect.x + offsetParent.clientLeft;
  498. offsets.y = offsetRect.y + offsetParent.clientTop;
  499. } else if (documentElement) {
  500. offsets.x = getWindowScrollBarX(documentElement);
  501. }
  502. }
  503. return {
  504. x: rect.left + scroll.scrollLeft - offsets.x,
  505. y: rect.top + scroll.scrollTop - offsets.y,
  506. width: rect.width,
  507. height: rect.height
  508. };
  509. }
  510. const platform = {
  511. getClippingRect,
  512. convertOffsetParentRelativeRectToViewportRelativeRect,
  513. isElement,
  514. getDimensions,
  515. getOffsetParent,
  516. getDocumentElement,
  517. getScale,
  518. async getElementRects(_ref) {
  519. let {
  520. reference,
  521. floating,
  522. strategy
  523. } = _ref;
  524. const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
  525. const getDimensionsFn = this.getDimensions;
  526. return {
  527. reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy),
  528. floating: {
  529. x: 0,
  530. y: 0,
  531. ...(await getDimensionsFn(floating))
  532. }
  533. };
  534. },
  535. getClientRects: element => Array.from(element.getClientRects()),
  536. isRTL: element => getComputedStyle$1(element).direction === 'rtl'
  537. };
  538. /**
  539. * Automatically updates the position of the floating element when necessary.
  540. * Should only be called when the floating element is mounted on the DOM or
  541. * visible on the screen.
  542. * @returns cleanup function that should be invoked when the floating element is
  543. * removed from the DOM or hidden from the screen.
  544. * @see https://floating-ui.com/docs/autoUpdate
  545. */
  546. function autoUpdate(reference, floating, update, options) {
  547. if (options === void 0) {
  548. options = {};
  549. }
  550. const {
  551. ancestorScroll: _ancestorScroll = true,
  552. ancestorResize = true,
  553. elementResize = true,
  554. animationFrame = false
  555. } = options;
  556. const ancestorScroll = _ancestorScroll && !animationFrame;
  557. const ancestors = ancestorScroll || ancestorResize ? [...(isElement(reference) ? getOverflowAncestors(reference) : reference.contextElement ? getOverflowAncestors(reference.contextElement) : []), ...getOverflowAncestors(floating)] : [];
  558. ancestors.forEach(ancestor => {
  559. ancestorScroll && ancestor.addEventListener('scroll', update, {
  560. passive: true
  561. });
  562. ancestorResize && ancestor.addEventListener('resize', update);
  563. });
  564. let observer = null;
  565. if (elementResize) {
  566. observer = new ResizeObserver(() => {
  567. update();
  568. });
  569. isElement(reference) && !animationFrame && observer.observe(reference);
  570. if (!isElement(reference) && reference.contextElement && !animationFrame) {
  571. observer.observe(reference.contextElement);
  572. }
  573. observer.observe(floating);
  574. }
  575. let frameId;
  576. let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
  577. if (animationFrame) {
  578. frameLoop();
  579. }
  580. function frameLoop() {
  581. const nextRefRect = getBoundingClientRect(reference);
  582. if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) {
  583. update();
  584. }
  585. prevRefRect = nextRefRect;
  586. frameId = requestAnimationFrame(frameLoop);
  587. }
  588. update();
  589. return () => {
  590. var _observer;
  591. ancestors.forEach(ancestor => {
  592. ancestorScroll && ancestor.removeEventListener('scroll', update);
  593. ancestorResize && ancestor.removeEventListener('resize', update);
  594. });
  595. (_observer = observer) == null ? void 0 : _observer.disconnect();
  596. observer = null;
  597. if (animationFrame) {
  598. cancelAnimationFrame(frameId);
  599. }
  600. };
  601. }
  602. /**
  603. * Computes the `x` and `y` coordinates that will place the floating element
  604. * next to a reference element when it is given a certain CSS positioning
  605. * strategy.
  606. */
  607. const computePosition = (reference, floating, options) => {
  608. // This caches the expensive `getClippingElementAncestors` function so that
  609. // multiple lifecycle resets re-use the same result. It only lives for a
  610. // single call. If other functions become expensive, we can add them as well.
  611. const cache = new Map();
  612. const mergedOptions = {
  613. platform,
  614. ...options
  615. };
  616. const platformWithCache = {
  617. ...mergedOptions.platform,
  618. _c: cache
  619. };
  620. return core.computePosition(reference, floating, {
  621. ...mergedOptions,
  622. platform: platformWithCache
  623. });
  624. };
  625. Object.defineProperty(exports, 'arrow', {
  626. enumerable: true,
  627. get: function () { return core.arrow; }
  628. });
  629. Object.defineProperty(exports, 'autoPlacement', {
  630. enumerable: true,
  631. get: function () { return core.autoPlacement; }
  632. });
  633. Object.defineProperty(exports, 'detectOverflow', {
  634. enumerable: true,
  635. get: function () { return core.detectOverflow; }
  636. });
  637. Object.defineProperty(exports, 'flip', {
  638. enumerable: true,
  639. get: function () { return core.flip; }
  640. });
  641. Object.defineProperty(exports, 'hide', {
  642. enumerable: true,
  643. get: function () { return core.hide; }
  644. });
  645. Object.defineProperty(exports, 'inline', {
  646. enumerable: true,
  647. get: function () { return core.inline; }
  648. });
  649. Object.defineProperty(exports, 'limitShift', {
  650. enumerable: true,
  651. get: function () { return core.limitShift; }
  652. });
  653. Object.defineProperty(exports, 'offset', {
  654. enumerable: true,
  655. get: function () { return core.offset; }
  656. });
  657. Object.defineProperty(exports, 'shift', {
  658. enumerable: true,
  659. get: function () { return core.shift; }
  660. });
  661. Object.defineProperty(exports, 'size', {
  662. enumerable: true,
  663. get: function () { return core.size; }
  664. });
  665. exports.autoUpdate = autoUpdate;
  666. exports.computePosition = computePosition;
  667. exports.getOverflowAncestors = getOverflowAncestors;
  668. exports.platform = platform;
  669. Object.defineProperty(exports, '__esModule', { value: true });
  670. }));