Tipyy-5.2.1

Tippy库

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/515866/1477949/Tipyy-521.js

  1. /**!
  2. * @fileOverview Kickass library to create and place poppers near their reference elements.
  3. * @version 1.16.1
  4. * @license
  5. * Copyright (c) 2016 Federico Zivolo and contributors
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. */
  25. (function (global, factory) {
  26. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  27. typeof define === 'function' && define.amd ? define(factory) :
  28. (global.Popper = factory());
  29. }(this, (function () { 'use strict';
  30.  
  31. var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
  32.  
  33. var timeoutDuration = function () {
  34. var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
  35. for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
  36. if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
  37. return 1;
  38. }
  39. }
  40. return 0;
  41. }();
  42.  
  43. function microtaskDebounce(fn) {
  44. var called = false;
  45. return function () {
  46. if (called) {
  47. return;
  48. }
  49. called = true;
  50. window.Promise.resolve().then(function () {
  51. called = false;
  52. fn();
  53. });
  54. };
  55. }
  56.  
  57. function taskDebounce(fn) {
  58. var scheduled = false;
  59. return function () {
  60. if (!scheduled) {
  61. scheduled = true;
  62. setTimeout(function () {
  63. scheduled = false;
  64. fn();
  65. }, timeoutDuration);
  66. }
  67. };
  68. }
  69.  
  70. var supportsMicroTasks = isBrowser && window.Promise;
  71.  
  72. /**
  73. * Create a debounced version of a method, that's asynchronously deferred
  74. * but called in the minimum time possible.
  75. *
  76. * @method
  77. * @memberof Popper.Utils
  78. * @argument {Function} fn
  79. * @returns {Function}
  80. */
  81. var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
  82.  
  83. /**
  84. * Check if the given variable is a function
  85. * @method
  86. * @memberof Popper.Utils
  87. * @argument {Any} functionToCheck - variable to check
  88. * @returns {Boolean} answer to: is a function?
  89. */
  90. function isFunction(functionToCheck) {
  91. var getType = {};
  92. return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
  93. }
  94.  
  95. /**
  96. * Get CSS computed property of the given element
  97. * @method
  98. * @memberof Popper.Utils
  99. * @argument {Eement} element
  100. * @argument {String} property
  101. */
  102. function getStyleComputedProperty(element, property) {
  103. if (element.nodeType !== 1) {
  104. return [];
  105. }
  106. // NOTE: 1 DOM access here
  107. var window = element.ownerDocument.defaultView;
  108. var css = window.getComputedStyle(element, null);
  109. return property ? css[property] : css;
  110. }
  111.  
  112. /**
  113. * Returns the parentNode or the host of the element
  114. * @method
  115. * @memberof Popper.Utils
  116. * @argument {Element} element
  117. * @returns {Element} parent
  118. */
  119. function getParentNode(element) {
  120. if (element.nodeName === 'HTML') {
  121. return element;
  122. }
  123. return element.parentNode || element.host;
  124. }
  125.  
  126. /**
  127. * Returns the scrolling parent of the given element
  128. * @method
  129. * @memberof Popper.Utils
  130. * @argument {Element} element
  131. * @returns {Element} scroll parent
  132. */
  133. function getScrollParent(element) {
  134. // Return body, `getScroll` will take care to get the correct `scrollTop` from it
  135. if (!element) {
  136. return document.body;
  137. }
  138.  
  139. switch (element.nodeName) {
  140. case 'HTML':
  141. case 'BODY':
  142. return element.ownerDocument.body;
  143. case '#document':
  144. return element.body;
  145. }
  146.  
  147. // Firefox want us to check `-x` and `-y` variations as well
  148.  
  149. var _getStyleComputedProp = getStyleComputedProperty(element),
  150. overflow = _getStyleComputedProp.overflow,
  151. overflowX = _getStyleComputedProp.overflowX,
  152. overflowY = _getStyleComputedProp.overflowY;
  153.  
  154. if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
  155. return element;
  156. }
  157.  
  158. return getScrollParent(getParentNode(element));
  159. }
  160.  
  161. /**
  162. * Returns the reference node of the reference object, or the reference object itself.
  163. * @method
  164. * @memberof Popper.Utils
  165. * @param {Element|Object} reference - the reference element (the popper will be relative to this)
  166. * @returns {Element} parent
  167. */
  168. function getReferenceNode(reference) {
  169. return reference && reference.referenceNode ? reference.referenceNode : reference;
  170. }
  171.  
  172. var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
  173. var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
  174.  
  175. /**
  176. * Determines if the browser is Internet Explorer
  177. * @method
  178. * @memberof Popper.Utils
  179. * @param {Number} version to check
  180. * @returns {Boolean} isIE
  181. */
  182. function isIE(version) {
  183. if (version === 11) {
  184. return isIE11;
  185. }
  186. if (version === 10) {
  187. return isIE10;
  188. }
  189. return isIE11 || isIE10;
  190. }
  191.  
  192. /**
  193. * Returns the offset parent of the given element
  194. * @method
  195. * @memberof Popper.Utils
  196. * @argument {Element} element
  197. * @returns {Element} offset parent
  198. */
  199. function getOffsetParent(element) {
  200. if (!element) {
  201. return document.documentElement;
  202. }
  203.  
  204. var noOffsetParent = isIE(10) ? document.body : null;
  205.  
  206. // NOTE: 1 DOM access here
  207. var offsetParent = element.offsetParent || null;
  208. // Skip hidden elements which don't have an offsetParent
  209. while (offsetParent === noOffsetParent && element.nextElementSibling) {
  210. offsetParent = (element = element.nextElementSibling).offsetParent;
  211. }
  212.  
  213. var nodeName = offsetParent && offsetParent.nodeName;
  214.  
  215. if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
  216. return element ? element.ownerDocument.documentElement : document.documentElement;
  217. }
  218.  
  219. // .offsetParent will return the closest TH, TD or TABLE in case
  220. // no offsetParent is present, I hate this job...
  221. if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
  222. return getOffsetParent(offsetParent);
  223. }
  224.  
  225. return offsetParent;
  226. }
  227.  
  228. function isOffsetContainer(element) {
  229. var nodeName = element.nodeName;
  230.  
  231. if (nodeName === 'BODY') {
  232. return false;
  233. }
  234. return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
  235. }
  236.  
  237. /**
  238. * Finds the root node (document, shadowDOM root) of the given element
  239. * @method
  240. * @memberof Popper.Utils
  241. * @argument {Element} node
  242. * @returns {Element} root node
  243. */
  244. function getRoot(node) {
  245. if (node.parentNode !== null) {
  246. return getRoot(node.parentNode);
  247. }
  248.  
  249. return node;
  250. }
  251.  
  252. /**
  253. * Finds the offset parent common to the two provided nodes
  254. * @method
  255. * @memberof Popper.Utils
  256. * @argument {Element} element1
  257. * @argument {Element} element2
  258. * @returns {Element} common offset parent
  259. */
  260. function findCommonOffsetParent(element1, element2) {
  261. // This check is needed to avoid errors in case one of the elements isn't defined for any reason
  262. if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
  263. return document.documentElement;
  264. }
  265.  
  266. // Here we make sure to give as "start" the element that comes first in the DOM
  267. var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
  268. var start = order ? element1 : element2;
  269. var end = order ? element2 : element1;
  270.  
  271. // Get common ancestor container
  272. var range = document.createRange();
  273. range.setStart(start, 0);
  274. range.setEnd(end, 0);
  275. var commonAncestorContainer = range.commonAncestorContainer;
  276.  
  277. // Both nodes are inside #document
  278.  
  279. if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
  280. if (isOffsetContainer(commonAncestorContainer)) {
  281. return commonAncestorContainer;
  282. }
  283.  
  284. return getOffsetParent(commonAncestorContainer);
  285. }
  286.  
  287. // one of the nodes is inside shadowDOM, find which one
  288. var element1root = getRoot(element1);
  289. if (element1root.host) {
  290. return findCommonOffsetParent(element1root.host, element2);
  291. } else {
  292. return findCommonOffsetParent(element1, getRoot(element2).host);
  293. }
  294. }
  295.  
  296. /**
  297. * Gets the scroll value of the given element in the given side (top and left)
  298. * @method
  299. * @memberof Popper.Utils
  300. * @argument {Element} element
  301. * @argument {String} side `top` or `left`
  302. * @returns {number} amount of scrolled pixels
  303. */
  304. function getScroll(element) {
  305. var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
  306.  
  307. var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
  308. var nodeName = element.nodeName;
  309.  
  310. if (nodeName === 'BODY' || nodeName === 'HTML') {
  311. var html = element.ownerDocument.documentElement;
  312. var scrollingElement = element.ownerDocument.scrollingElement || html;
  313. return scrollingElement[upperSide];
  314. }
  315.  
  316. return element[upperSide];
  317. }
  318.  
  319. /*
  320. * Sum or subtract the element scroll values (left and top) from a given rect object
  321. * @method
  322. * @memberof Popper.Utils
  323. * @param {Object} rect - Rect object you want to change
  324. * @param {HTMLElement} element - The element from the function reads the scroll values
  325. * @param {Boolean} subtract - set to true if you want to subtract the scroll values
  326. * @return {Object} rect - The modifier rect object
  327. */
  328. function includeScroll(rect, element) {
  329. var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  330.  
  331. var scrollTop = getScroll(element, 'top');
  332. var scrollLeft = getScroll(element, 'left');
  333. var modifier = subtract ? -1 : 1;
  334. rect.top += scrollTop * modifier;
  335. rect.bottom += scrollTop * modifier;
  336. rect.left += scrollLeft * modifier;
  337. rect.right += scrollLeft * modifier;
  338. return rect;
  339. }
  340.  
  341. /*
  342. * Helper to detect borders of a given element
  343. * @method
  344. * @memberof Popper.Utils
  345. * @param {CSSStyleDeclaration} styles
  346. * Result of `getStyleComputedProperty` on the given element
  347. * @param {String} axis - `x` or `y`
  348. * @return {number} borders - The borders size of the given axis
  349. */
  350.  
  351. function getBordersSize(styles, axis) {
  352. var sideA = axis === 'x' ? 'Left' : 'Top';
  353. var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
  354.  
  355. return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);
  356. }
  357.  
  358. function getSize(axis, body, html, computedStyle) {
  359. return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
  360. }
  361.  
  362. function getWindowSizes(document) {
  363. var body = document.body;
  364. var html = document.documentElement;
  365. var computedStyle = isIE(10) && getComputedStyle(html);
  366.  
  367. return {
  368. height: getSize('Height', body, html, computedStyle),
  369. width: getSize('Width', body, html, computedStyle)
  370. };
  371. }
  372.  
  373. var classCallCheck = function (instance, Constructor) {
  374. if (!(instance instanceof Constructor)) {
  375. throw new TypeError("Cannot call a class as a function");
  376. }
  377. };
  378.  
  379. var createClass = function () {
  380. function defineProperties(target, props) {
  381. for (var i = 0; i < props.length; i++) {
  382. var descriptor = props[i];
  383. descriptor.enumerable = descriptor.enumerable || false;
  384. descriptor.configurable = true;
  385. if ("value" in descriptor) descriptor.writable = true;
  386. Object.defineProperty(target, descriptor.key, descriptor);
  387. }
  388. }
  389.  
  390. return function (Constructor, protoProps, staticProps) {
  391. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  392. if (staticProps) defineProperties(Constructor, staticProps);
  393. return Constructor;
  394. };
  395. }();
  396.  
  397.  
  398.  
  399.  
  400.  
  401. var defineProperty = function (obj, key, value) {
  402. if (key in obj) {
  403. Object.defineProperty(obj, key, {
  404. value: value,
  405. enumerable: true,
  406. configurable: true,
  407. writable: true
  408. });
  409. } else {
  410. obj[key] = value;
  411. }
  412.  
  413. return obj;
  414. };
  415.  
  416. var _extends = Object.assign || function (target) {
  417. for (var i = 1; i < arguments.length; i++) {
  418. var source = arguments[i];
  419.  
  420. for (var key in source) {
  421. if (Object.prototype.hasOwnProperty.call(source, key)) {
  422. target[key] = source[key];
  423. }
  424. }
  425. }
  426.  
  427. return target;
  428. };
  429.  
  430. /**
  431. * Given element offsets, generate an output similar to getBoundingClientRect
  432. * @method
  433. * @memberof Popper.Utils
  434. * @argument {Object} offsets
  435. * @returns {Object} ClientRect like output
  436. */
  437. function getClientRect(offsets) {
  438. return _extends({}, offsets, {
  439. right: offsets.left + offsets.width,
  440. bottom: offsets.top + offsets.height
  441. });
  442. }
  443.  
  444. /**
  445. * Get bounding client rect of given element
  446. * @method
  447. * @memberof Popper.Utils
  448. * @param {HTMLElement} element
  449. * @return {Object} client rect
  450. */
  451. function getBoundingClientRect(element) {
  452. var rect = {};
  453.  
  454. // IE10 10 FIX: Please, don't ask, the element isn't
  455. // considered in DOM in some circumstances...
  456. // This isn't reproducible in IE10 compatibility mode of IE11
  457. try {
  458. if (isIE(10)) {
  459. rect = element.getBoundingClientRect();
  460. var scrollTop = getScroll(element, 'top');
  461. var scrollLeft = getScroll(element, 'left');
  462. rect.top += scrollTop;
  463. rect.left += scrollLeft;
  464. rect.bottom += scrollTop;
  465. rect.right += scrollLeft;
  466. } else {
  467. rect = element.getBoundingClientRect();
  468. }
  469. } catch (e) {}
  470.  
  471. var result = {
  472. left: rect.left,
  473. top: rect.top,
  474. width: rect.right - rect.left,
  475. height: rect.bottom - rect.top
  476. };
  477.  
  478. // subtract scrollbar size from sizes
  479. var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
  480. var width = sizes.width || element.clientWidth || result.width;
  481. var height = sizes.height || element.clientHeight || result.height;
  482.  
  483. var horizScrollbar = element.offsetWidth - width;
  484. var vertScrollbar = element.offsetHeight - height;
  485.  
  486. // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
  487. // we make this check conditional for performance reasons
  488. if (horizScrollbar || vertScrollbar) {
  489. var styles = getStyleComputedProperty(element);
  490. horizScrollbar -= getBordersSize(styles, 'x');
  491. vertScrollbar -= getBordersSize(styles, 'y');
  492.  
  493. result.width -= horizScrollbar;
  494. result.height -= vertScrollbar;
  495. }
  496.  
  497. return getClientRect(result);
  498. }
  499.  
  500. function getOffsetRectRelativeToArbitraryNode(children, parent) {
  501. var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  502.  
  503. var isIE10 = isIE(10);
  504. var isHTML = parent.nodeName === 'HTML';
  505. var childrenRect = getBoundingClientRect(children);
  506. var parentRect = getBoundingClientRect(parent);
  507. var scrollParent = getScrollParent(children);
  508.  
  509. var styles = getStyleComputedProperty(parent);
  510. var borderTopWidth = parseFloat(styles.borderTopWidth);
  511. var borderLeftWidth = parseFloat(styles.borderLeftWidth);
  512.  
  513. // In cases where the parent is fixed, we must ignore negative scroll in offset calc
  514. if (fixedPosition && isHTML) {
  515. parentRect.top = Math.max(parentRect.top, 0);
  516. parentRect.left = Math.max(parentRect.left, 0);
  517. }
  518. var offsets = getClientRect({
  519. top: childrenRect.top - parentRect.top - borderTopWidth,
  520. left: childrenRect.left - parentRect.left - borderLeftWidth,
  521. width: childrenRect.width,
  522. height: childrenRect.height
  523. });
  524. offsets.marginTop = 0;
  525. offsets.marginLeft = 0;
  526.  
  527. // Subtract margins of documentElement in case it's being used as parent
  528. // we do this only on HTML because it's the only element that behaves
  529. // differently when margins are applied to it. The margins are included in
  530. // the box of the documentElement, in the other cases not.
  531. if (!isIE10 && isHTML) {
  532. var marginTop = parseFloat(styles.marginTop);
  533. var marginLeft = parseFloat(styles.marginLeft);
  534.  
  535. offsets.top -= borderTopWidth - marginTop;
  536. offsets.bottom -= borderTopWidth - marginTop;
  537. offsets.left -= borderLeftWidth - marginLeft;
  538. offsets.right -= borderLeftWidth - marginLeft;
  539.  
  540. // Attach marginTop and marginLeft because in some circumstances we may need them
  541. offsets.marginTop = marginTop;
  542. offsets.marginLeft = marginLeft;
  543. }
  544.  
  545. if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
  546. offsets = includeScroll(offsets, parent);
  547. }
  548.  
  549. return offsets;
  550. }
  551.  
  552. function getViewportOffsetRectRelativeToArtbitraryNode(element) {
  553. var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  554.  
  555. var html = element.ownerDocument.documentElement;
  556. var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
  557. var width = Math.max(html.clientWidth, window.innerWidth || 0);
  558. var height = Math.max(html.clientHeight, window.innerHeight || 0);
  559.  
  560. var scrollTop = !excludeScroll ? getScroll(html) : 0;
  561. var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
  562.  
  563. var offset = {
  564. top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
  565. left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
  566. width: width,
  567. height: height
  568. };
  569.  
  570. return getClientRect(offset);
  571. }
  572.  
  573. /**
  574. * Check if the given element is fixed or is inside a fixed parent
  575. * @method
  576. * @memberof Popper.Utils
  577. * @argument {Element} element
  578. * @argument {Element} customContainer
  579. * @returns {Boolean} answer to "isFixed?"
  580. */
  581. function isFixed(element) {
  582. var nodeName = element.nodeName;
  583. if (nodeName === 'BODY' || nodeName === 'HTML') {
  584. return false;
  585. }
  586. if (getStyleComputedProperty(element, 'position') === 'fixed') {
  587. return true;
  588. }
  589. var parentNode = getParentNode(element);
  590. if (!parentNode) {
  591. return false;
  592. }
  593. return isFixed(parentNode);
  594. }
  595.  
  596. /**
  597. * Finds the first parent of an element that has a transformed property defined
  598. * @method
  599. * @memberof Popper.Utils
  600. * @argument {Element} element
  601. * @returns {Element} first transformed parent or documentElement
  602. */
  603.  
  604. function getFixedPositionOffsetParent(element) {
  605. // This check is needed to avoid errors in case one of the elements isn't defined for any reason
  606. if (!element || !element.parentElement || isIE()) {
  607. return document.documentElement;
  608. }
  609. var el = element.parentElement;
  610. while (el && getStyleComputedProperty(el, 'transform') === 'none') {
  611. el = el.parentElement;
  612. }
  613. return el || document.documentElement;
  614. }
  615.  
  616. /**
  617. * Computed the boundaries limits and return them
  618. * @method
  619. * @memberof Popper.Utils
  620. * @param {HTMLElement} popper
  621. * @param {HTMLElement} reference
  622. * @param {number} padding
  623. * @param {HTMLElement} boundariesElement - Element used to define the boundaries
  624. * @param {Boolean} fixedPosition - Is in fixed position mode
  625. * @returns {Object} Coordinates of the boundaries
  626. */
  627. function getBoundaries(popper, reference, padding, boundariesElement) {
  628. var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
  629.  
  630. // NOTE: 1 DOM access here
  631.  
  632. var boundaries = { top: 0, left: 0 };
  633. var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
  634.  
  635. // Handle viewport case
  636. if (boundariesElement === 'viewport') {
  637. boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
  638. } else {
  639. // Handle other cases based on DOM element used as boundaries
  640. var boundariesNode = void 0;
  641. if (boundariesElement === 'scrollParent') {
  642. boundariesNode = getScrollParent(getParentNode(reference));
  643. if (boundariesNode.nodeName === 'BODY') {
  644. boundariesNode = popper.ownerDocument.documentElement;
  645. }
  646. } else if (boundariesElement === 'window') {
  647. boundariesNode = popper.ownerDocument.documentElement;
  648. } else {
  649. boundariesNode = boundariesElement;
  650. }
  651.  
  652. var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
  653.  
  654. // In case of HTML, we need a different computation
  655. if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
  656. var _getWindowSizes = getWindowSizes(popper.ownerDocument),
  657. height = _getWindowSizes.height,
  658. width = _getWindowSizes.width;
  659.  
  660. boundaries.top += offsets.top - offsets.marginTop;
  661. boundaries.bottom = height + offsets.top;
  662. boundaries.left += offsets.left - offsets.marginLeft;
  663. boundaries.right = width + offsets.left;
  664. } else {
  665. // for all the other DOM elements, this one is good
  666. boundaries = offsets;
  667. }
  668. }
  669.  
  670. // Add paddings
  671. padding = padding || 0;
  672. var isPaddingNumber = typeof padding === 'number';
  673. boundaries.left += isPaddingNumber ? padding : padding.left || 0;
  674. boundaries.top += isPaddingNumber ? padding : padding.top || 0;
  675. boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
  676. boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
  677.  
  678. return boundaries;
  679. }
  680.  
  681. function getArea(_ref) {
  682. var width = _ref.width,
  683. height = _ref.height;
  684.  
  685. return width * height;
  686. }
  687.  
  688. /**
  689. * Utility used to transform the `auto` placement to the placement with more
  690. * available space.
  691. * @method
  692. * @memberof Popper.Utils
  693. * @argument {Object} data - The data object generated by update method
  694. * @argument {Object} options - Modifiers configuration and options
  695. * @returns {Object} The data object, properly modified
  696. */
  697. function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
  698. var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
  699.  
  700. if (placement.indexOf('auto') === -1) {
  701. return placement;
  702. }
  703.  
  704. var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
  705.  
  706. var rects = {
  707. top: {
  708. width: boundaries.width,
  709. height: refRect.top - boundaries.top
  710. },
  711. right: {
  712. width: boundaries.right - refRect.right,
  713. height: boundaries.height
  714. },
  715. bottom: {
  716. width: boundaries.width,
  717. height: boundaries.bottom - refRect.bottom
  718. },
  719. left: {
  720. width: refRect.left - boundaries.left,
  721. height: boundaries.height
  722. }
  723. };
  724.  
  725. var sortedAreas = Object.keys(rects).map(function (key) {
  726. return _extends({
  727. key: key
  728. }, rects[key], {
  729. area: getArea(rects[key])
  730. });
  731. }).sort(function (a, b) {
  732. return b.area - a.area;
  733. });
  734.  
  735. var filteredAreas = sortedAreas.filter(function (_ref2) {
  736. var width = _ref2.width,
  737. height = _ref2.height;
  738. return width >= popper.clientWidth && height >= popper.clientHeight;
  739. });
  740.  
  741. var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
  742.  
  743. var variation = placement.split('-')[1];
  744.  
  745. return computedPlacement + (variation ? '-' + variation : '');
  746. }
  747.  
  748. /**
  749. * Get offsets to the reference element
  750. * @method
  751. * @memberof Popper.Utils
  752. * @param {Object} state
  753. * @param {Element} popper - the popper element
  754. * @param {Element} reference - the reference element (the popper will be relative to this)
  755. * @param {Element} fixedPosition - is in fixed position mode
  756. * @returns {Object} An object containing the offsets which will be applied to the popper
  757. */
  758. function getReferenceOffsets(state, popper, reference) {
  759. var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
  760.  
  761. var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
  762. return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
  763. }
  764.  
  765. /**
  766. * Get the outer sizes of the given element (offset size + margins)
  767. * @method
  768. * @memberof Popper.Utils
  769. * @argument {Element} element
  770. * @returns {Object} object containing width and height properties
  771. */
  772. function getOuterSizes(element) {
  773. var window = element.ownerDocument.defaultView;
  774. var styles = window.getComputedStyle(element);
  775. var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
  776. var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
  777. var result = {
  778. width: element.offsetWidth + y,
  779. height: element.offsetHeight + x
  780. };
  781. return result;
  782. }
  783.  
  784. /**
  785. * Get the opposite placement of the given one
  786. * @method
  787. * @memberof Popper.Utils
  788. * @argument {String} placement
  789. * @returns {String} flipped placement
  790. */
  791. function getOppositePlacement(placement) {
  792. var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
  793. return placement.replace(/left|right|bottom|top/g, function (matched) {
  794. return hash[matched];
  795. });
  796. }
  797.  
  798. /**
  799. * Get offsets to the popper
  800. * @method
  801. * @memberof Popper.Utils
  802. * @param {Object} position - CSS position the Popper will get applied
  803. * @param {HTMLElement} popper - the popper element
  804. * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
  805. * @param {String} placement - one of the valid placement options
  806. * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
  807. */
  808. function getPopperOffsets(popper, referenceOffsets, placement) {
  809. placement = placement.split('-')[0];
  810.  
  811. // Get popper node sizes
  812. var popperRect = getOuterSizes(popper);
  813.  
  814. // Add position, width and height to our offsets object
  815. var popperOffsets = {
  816. width: popperRect.width,
  817. height: popperRect.height
  818. };
  819.  
  820. // depending by the popper placement we have to compute its offsets slightly differently
  821. var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
  822. var mainSide = isHoriz ? 'top' : 'left';
  823. var secondarySide = isHoriz ? 'left' : 'top';
  824. var measurement = isHoriz ? 'height' : 'width';
  825. var secondaryMeasurement = !isHoriz ? 'height' : 'width';
  826.  
  827. popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
  828. if (placement === secondarySide) {
  829. popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
  830. } else {
  831. popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
  832. }
  833.  
  834. return popperOffsets;
  835. }
  836.  
  837. /**
  838. * Mimics the `find` method of Array
  839. * @method
  840. * @memberof Popper.Utils
  841. * @argument {Array} arr
  842. * @argument prop
  843. * @argument value
  844. * @returns index or -1
  845. */
  846. function find(arr, check) {
  847. // use native find if supported
  848. if (Array.prototype.find) {
  849. return arr.find(check);
  850. }
  851.  
  852. // use `filter` to obtain the same behavior of `find`
  853. return arr.filter(check)[0];
  854. }
  855.  
  856. /**
  857. * Return the index of the matching object
  858. * @method
  859. * @memberof Popper.Utils
  860. * @argument {Array} arr
  861. * @argument prop
  862. * @argument value
  863. * @returns index or -1
  864. */
  865. function findIndex(arr, prop, value) {
  866. // use native findIndex if supported
  867. if (Array.prototype.findIndex) {
  868. return arr.findIndex(function (cur) {
  869. return cur[prop] === value;
  870. });
  871. }
  872.  
  873. // use `find` + `indexOf` if `findIndex` isn't supported
  874. var match = find(arr, function (obj) {
  875. return obj[prop] === value;
  876. });
  877. return arr.indexOf(match);
  878. }
  879.  
  880. /**
  881. * Loop trough the list of modifiers and run them in order,
  882. * each of them will then edit the data object.
  883. * @method
  884. * @memberof Popper.Utils
  885. * @param {dataObject} data
  886. * @param {Array} modifiers
  887. * @param {String} ends - Optional modifier name used as stopper
  888. * @returns {dataObject}
  889. */
  890. function runModifiers(modifiers, data, ends) {
  891. var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
  892.  
  893. modifiersToRun.forEach(function (modifier) {
  894. if (modifier['function']) {
  895. // eslint-disable-line dot-notation
  896. console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
  897. }
  898. var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
  899. if (modifier.enabled && isFunction(fn)) {
  900. // Add properties to offsets to make them a complete clientRect object
  901. // we do this before each modifier to make sure the previous one doesn't
  902. // mess with these values
  903. data.offsets.popper = getClientRect(data.offsets.popper);
  904. data.offsets.reference = getClientRect(data.offsets.reference);
  905.  
  906. data = fn(data, modifier);
  907. }
  908. });
  909.  
  910. return data;
  911. }
  912.  
  913. /**
  914. * Updates the position of the popper, computing the new offsets and applying
  915. * the new style.<br />
  916. * Prefer `scheduleUpdate` over `update` because of performance reasons.
  917. * @method
  918. * @memberof Popper
  919. */
  920. function update() {
  921. // if popper is destroyed, don't perform any further update
  922. if (this.state.isDestroyed) {
  923. return;
  924. }
  925.  
  926. var data = {
  927. instance: this,
  928. styles: {},
  929. arrowStyles: {},
  930. attributes: {},
  931. flipped: false,
  932. offsets: {}
  933. };
  934.  
  935. // compute reference element offsets
  936. data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
  937.  
  938. // compute auto placement, store placement inside the data object,
  939. // modifiers will be able to edit `placement` if needed
  940. // and refer to originalPlacement to know the original value
  941. data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
  942.  
  943. // store the computed placement inside `originalPlacement`
  944. data.originalPlacement = data.placement;
  945.  
  946. data.positionFixed = this.options.positionFixed;
  947.  
  948. // compute the popper offsets
  949. data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
  950.  
  951. data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
  952.  
  953. // run the modifiers
  954. data = runModifiers(this.modifiers, data);
  955.  
  956. // the first `update` will call `onCreate` callback
  957. // the other ones will call `onUpdate` callback
  958. if (!this.state.isCreated) {
  959. this.state.isCreated = true;
  960. this.options.onCreate(data);
  961. } else {
  962. this.options.onUpdate(data);
  963. }
  964. }
  965.  
  966. /**
  967. * Helper used to know if the given modifier is enabled.
  968. * @method
  969. * @memberof Popper.Utils
  970. * @returns {Boolean}
  971. */
  972. function isModifierEnabled(modifiers, modifierName) {
  973. return modifiers.some(function (_ref) {
  974. var name = _ref.name,
  975. enabled = _ref.enabled;
  976. return enabled && name === modifierName;
  977. });
  978. }
  979.  
  980. /**
  981. * Get the prefixed supported property name
  982. * @method
  983. * @memberof Popper.Utils
  984. * @argument {String} property (camelCase)
  985. * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
  986. */
  987. function getSupportedPropertyName(property) {
  988. var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
  989. var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
  990.  
  991. for (var i = 0; i < prefixes.length; i++) {
  992. var prefix = prefixes[i];
  993. var toCheck = prefix ? '' + prefix + upperProp : property;
  994. if (typeof document.body.style[toCheck] !== 'undefined') {
  995. return toCheck;
  996. }
  997. }
  998. return null;
  999. }
  1000.  
  1001. /**
  1002. * Destroys the popper.
  1003. * @method
  1004. * @memberof Popper
  1005. */
  1006. function destroy() {
  1007. this.state.isDestroyed = true;
  1008.  
  1009. // touch DOM only if `applyStyle` modifier is enabled
  1010. if (isModifierEnabled(this.modifiers, 'applyStyle')) {
  1011. this.popper.removeAttribute('x-placement');
  1012. this.popper.style.position = '';
  1013. this.popper.style.top = '';
  1014. this.popper.style.left = '';
  1015. this.popper.style.right = '';
  1016. this.popper.style.bottom = '';
  1017. this.popper.style.willChange = '';
  1018. this.popper.style[getSupportedPropertyName('transform')] = '';
  1019. }
  1020.  
  1021. this.disableEventListeners();
  1022.  
  1023. // remove the popper if user explicitly asked for the deletion on destroy
  1024. // do not use `remove` because IE11 doesn't support it
  1025. if (this.options.removeOnDestroy) {
  1026. this.popper.parentNode.removeChild(this.popper);
  1027. }
  1028. return this;
  1029. }
  1030.  
  1031. /**
  1032. * Get the window associated with the element
  1033. * @argument {Element} element
  1034. * @returns {Window}
  1035. */
  1036. function getWindow(element) {
  1037. var ownerDocument = element.ownerDocument;
  1038. return ownerDocument ? ownerDocument.defaultView : window;
  1039. }
  1040.  
  1041. function attachToScrollParents(scrollParent, event, callback, scrollParents) {
  1042. var isBody = scrollParent.nodeName === 'BODY';
  1043. var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
  1044. target.addEventListener(event, callback, { passive: true });
  1045.  
  1046. if (!isBody) {
  1047. attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
  1048. }
  1049. scrollParents.push(target);
  1050. }
  1051.  
  1052. /**
  1053. * Setup needed event listeners used to update the popper position
  1054. * @method
  1055. * @memberof Popper.Utils
  1056. * @private
  1057. */
  1058. function setupEventListeners(reference, options, state, updateBound) {
  1059. // Resize event listener on window
  1060. state.updateBound = updateBound;
  1061. getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
  1062.  
  1063. // Scroll event listener on scroll parents
  1064. var scrollElement = getScrollParent(reference);
  1065. attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
  1066. state.scrollElement = scrollElement;
  1067. state.eventsEnabled = true;
  1068.  
  1069. return state;
  1070. }
  1071.  
  1072. /**
  1073. * It will add resize/scroll events and start recalculating
  1074. * position of the popper element when they are triggered.
  1075. * @method
  1076. * @memberof Popper
  1077. */
  1078. function enableEventListeners() {
  1079. if (!this.state.eventsEnabled) {
  1080. this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
  1081. }
  1082. }
  1083.  
  1084. /**
  1085. * Remove event listeners used to update the popper position
  1086. * @method
  1087. * @memberof Popper.Utils
  1088. * @private
  1089. */
  1090. function removeEventListeners(reference, state) {
  1091. // Remove resize event listener on window
  1092. getWindow(reference).removeEventListener('resize', state.updateBound);
  1093.  
  1094. // Remove scroll event listener on scroll parents
  1095. state.scrollParents.forEach(function (target) {
  1096. target.removeEventListener('scroll', state.updateBound);
  1097. });
  1098.  
  1099. // Reset state
  1100. state.updateBound = null;
  1101. state.scrollParents = [];
  1102. state.scrollElement = null;
  1103. state.eventsEnabled = false;
  1104. return state;
  1105. }
  1106.  
  1107. /**
  1108. * It will remove resize/scroll events and won't recalculate popper position
  1109. * when they are triggered. It also won't trigger `onUpdate` callback anymore,
  1110. * unless you call `update` method manually.
  1111. * @method
  1112. * @memberof Popper
  1113. */
  1114. function disableEventListeners() {
  1115. if (this.state.eventsEnabled) {
  1116. cancelAnimationFrame(this.scheduleUpdate);
  1117. this.state = removeEventListeners(this.reference, this.state);
  1118. }
  1119. }
  1120.  
  1121. /**
  1122. * Tells if a given input is a number
  1123. * @method
  1124. * @memberof Popper.Utils
  1125. * @param {*} input to check
  1126. * @return {Boolean}
  1127. */
  1128. function isNumeric(n) {
  1129. return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
  1130. }
  1131.  
  1132. /**
  1133. * Set the style to the given popper
  1134. * @method
  1135. * @memberof Popper.Utils
  1136. * @argument {Element} element - Element to apply the style to
  1137. * @argument {Object} styles
  1138. * Object with a list of properties and values which will be applied to the element
  1139. */
  1140. function setStyles(element, styles) {
  1141. Object.keys(styles).forEach(function (prop) {
  1142. var unit = '';
  1143. // add unit if the value is numeric and is one of the following
  1144. if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
  1145. unit = 'px';
  1146. }
  1147. element.style[prop] = styles[prop] + unit;
  1148. });
  1149. }
  1150.  
  1151. /**
  1152. * Set the attributes to the given popper
  1153. * @method
  1154. * @memberof Popper.Utils
  1155. * @argument {Element} element - Element to apply the attributes to
  1156. * @argument {Object} styles
  1157. * Object with a list of properties and values which will be applied to the element
  1158. */
  1159. function setAttributes(element, attributes) {
  1160. Object.keys(attributes).forEach(function (prop) {
  1161. var value = attributes[prop];
  1162. if (value !== false) {
  1163. element.setAttribute(prop, attributes[prop]);
  1164. } else {
  1165. element.removeAttribute(prop);
  1166. }
  1167. });
  1168. }
  1169.  
  1170. /**
  1171. * @function
  1172. * @memberof Modifiers
  1173. * @argument {Object} data - The data object generated by `update` method
  1174. * @argument {Object} data.styles - List of style properties - values to apply to popper element
  1175. * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
  1176. * @argument {Object} options - Modifiers configuration and options
  1177. * @returns {Object} The same data object
  1178. */
  1179. function applyStyle(data) {
  1180. // any property present in `data.styles` will be applied to the popper,
  1181. // in this way we can make the 3rd party modifiers add custom styles to it
  1182. // Be aware, modifiers could override the properties defined in the previous
  1183. // lines of this modifier!
  1184. setStyles(data.instance.popper, data.styles);
  1185.  
  1186. // any property present in `data.attributes` will be applied to the popper,
  1187. // they will be set as HTML attributes of the element
  1188. setAttributes(data.instance.popper, data.attributes);
  1189.  
  1190. // if arrowElement is defined and arrowStyles has some properties
  1191. if (data.arrowElement && Object.keys(data.arrowStyles).length) {
  1192. setStyles(data.arrowElement, data.arrowStyles);
  1193. }
  1194.  
  1195. return data;
  1196. }
  1197.  
  1198. /**
  1199. * Set the x-placement attribute before everything else because it could be used
  1200. * to add margins to the popper margins needs to be calculated to get the
  1201. * correct popper offsets.
  1202. * @method
  1203. * @memberof Popper.modifiers
  1204. * @param {HTMLElement} reference - The reference element used to position the popper
  1205. * @param {HTMLElement} popper - The HTML element used as popper
  1206. * @param {Object} options - Popper.js options
  1207. */
  1208. function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
  1209. // compute reference element offsets
  1210. var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
  1211.  
  1212. // compute auto placement, store placement inside the data object,
  1213. // modifiers will be able to edit `placement` if needed
  1214. // and refer to originalPlacement to know the original value
  1215. var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
  1216.  
  1217. popper.setAttribute('x-placement', placement);
  1218.  
  1219. // Apply `position` to popper before anything else because
  1220. // without the position applied we can't guarantee correct computations
  1221. setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
  1222.  
  1223. return options;
  1224. }
  1225.  
  1226. /**
  1227. * @function
  1228. * @memberof Popper.Utils
  1229. * @argument {Object} data - The data object generated by `update` method
  1230. * @argument {Boolean} shouldRound - If the offsets should be rounded at all
  1231. * @returns {Object} The popper's position offsets rounded
  1232. *
  1233. * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
  1234. * good as it can be within reason.
  1235. * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
  1236. *
  1237. * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
  1238. * as well on High DPI screens).
  1239. *
  1240. * Firefox prefers no rounding for positioning and does not have blurriness on
  1241. * high DPI screens.
  1242. *
  1243. * Only horizontal placement and left/right values need to be considered.
  1244. */
  1245. function getRoundedOffsets(data, shouldRound) {
  1246. var _data$offsets = data.offsets,
  1247. popper = _data$offsets.popper,
  1248. reference = _data$offsets.reference;
  1249. var round = Math.round,
  1250. floor = Math.floor;
  1251.  
  1252. var noRound = function noRound(v) {
  1253. return v;
  1254. };
  1255.  
  1256. var referenceWidth = round(reference.width);
  1257. var popperWidth = round(popper.width);
  1258.  
  1259. var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
  1260. var isVariation = data.placement.indexOf('-') !== -1;
  1261. var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
  1262. var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
  1263.  
  1264. var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
  1265. var verticalToInteger = !shouldRound ? noRound : round;
  1266.  
  1267. return {
  1268. left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
  1269. top: verticalToInteger(popper.top),
  1270. bottom: verticalToInteger(popper.bottom),
  1271. right: horizontalToInteger(popper.right)
  1272. };
  1273. }
  1274.  
  1275. var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
  1276.  
  1277. /**
  1278. * @function
  1279. * @memberof Modifiers
  1280. * @argument {Object} data - The data object generated by `update` method
  1281. * @argument {Object} options - Modifiers configuration and options
  1282. * @returns {Object} The data object, properly modified
  1283. */
  1284. function computeStyle(data, options) {
  1285. var x = options.x,
  1286. y = options.y;
  1287. var popper = data.offsets.popper;
  1288.  
  1289. // Remove this legacy support in Popper.js v2
  1290.  
  1291. var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
  1292. return modifier.name === 'applyStyle';
  1293. }).gpuAcceleration;
  1294. if (legacyGpuAccelerationOption !== undefined) {
  1295. console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
  1296. }
  1297. var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
  1298.  
  1299. var offsetParent = getOffsetParent(data.instance.popper);
  1300. var offsetParentRect = getBoundingClientRect(offsetParent);
  1301.  
  1302. // Styles
  1303. var styles = {
  1304. position: popper.position
  1305. };
  1306.  
  1307. var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
  1308.  
  1309. var sideA = x === 'bottom' ? 'top' : 'bottom';
  1310. var sideB = y === 'right' ? 'left' : 'right';
  1311.  
  1312. // if gpuAcceleration is set to `true` and transform is supported,
  1313. // we use `translate3d` to apply the position to the popper we
  1314. // automatically use the supported prefixed version if needed
  1315. var prefixedProperty = getSupportedPropertyName('transform');
  1316.  
  1317. // now, let's make a step back and look at this code closely (wtf?)
  1318. // If the content of the popper grows once it's been positioned, it
  1319. // may happen that the popper gets misplaced because of the new content
  1320. // overflowing its reference element
  1321. // To avoid this problem, we provide two options (x and y), which allow
  1322. // the consumer to define the offset origin.
  1323. // If we position a popper on top of a reference element, we can set
  1324. // `x` to `top` to make the popper grow towards its top instead of
  1325. // its bottom.
  1326. var left = void 0,
  1327. top = void 0;
  1328. if (sideA === 'bottom') {
  1329. // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
  1330. // and not the bottom of the html element
  1331. if (offsetParent.nodeName === 'HTML') {
  1332. top = -offsetParent.clientHeight + offsets.bottom;
  1333. } else {
  1334. top = -offsetParentRect.height + offsets.bottom;
  1335. }
  1336. } else {
  1337. top = offsets.top;
  1338. }
  1339. if (sideB === 'right') {
  1340. if (offsetParent.nodeName === 'HTML') {
  1341. left = -offsetParent.clientWidth + offsets.right;
  1342. } else {
  1343. left = -offsetParentRect.width + offsets.right;
  1344. }
  1345. } else {
  1346. left = offsets.left;
  1347. }
  1348. if (gpuAcceleration && prefixedProperty) {
  1349. styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
  1350. styles[sideA] = 0;
  1351. styles[sideB] = 0;
  1352. styles.willChange = 'transform';
  1353. } else {
  1354. // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
  1355. var invertTop = sideA === 'bottom' ? -1 : 1;
  1356. var invertLeft = sideB === 'right' ? -1 : 1;
  1357. styles[sideA] = top * invertTop;
  1358. styles[sideB] = left * invertLeft;
  1359. styles.willChange = sideA + ', ' + sideB;
  1360. }
  1361.  
  1362. // Attributes
  1363. var attributes = {
  1364. 'x-placement': data.placement
  1365. };
  1366.  
  1367. // Update `data` attributes, styles and arrowStyles
  1368. data.attributes = _extends({}, attributes, data.attributes);
  1369. data.styles = _extends({}, styles, data.styles);
  1370. data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
  1371.  
  1372. return data;
  1373. }
  1374.  
  1375. /**
  1376. * Helper used to know if the given modifier depends from another one.<br />
  1377. * It checks if the needed modifier is listed and enabled.
  1378. * @method
  1379. * @memberof Popper.Utils
  1380. * @param {Array} modifiers - list of modifiers
  1381. * @param {String} requestingName - name of requesting modifier
  1382. * @param {String} requestedName - name of requested modifier
  1383. * @returns {Boolean}
  1384. */
  1385. function isModifierRequired(modifiers, requestingName, requestedName) {
  1386. var requesting = find(modifiers, function (_ref) {
  1387. var name = _ref.name;
  1388. return name === requestingName;
  1389. });
  1390.  
  1391. var isRequired = !!requesting && modifiers.some(function (modifier) {
  1392. return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
  1393. });
  1394.  
  1395. if (!isRequired) {
  1396. var _requesting = '`' + requestingName + '`';
  1397. var requested = '`' + requestedName + '`';
  1398. console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
  1399. }
  1400. return isRequired;
  1401. }
  1402.  
  1403. /**
  1404. * @function
  1405. * @memberof Modifiers
  1406. * @argument {Object} data - The data object generated by update method
  1407. * @argument {Object} options - Modifiers configuration and options
  1408. * @returns {Object} The data object, properly modified
  1409. */
  1410. function arrow(data, options) {
  1411. var _data$offsets$arrow;
  1412.  
  1413. // arrow depends on keepTogether in order to work
  1414. if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
  1415. return data;
  1416. }
  1417.  
  1418. var arrowElement = options.element;
  1419.  
  1420. // if arrowElement is a string, suppose it's a CSS selector
  1421. if (typeof arrowElement === 'string') {
  1422. arrowElement = data.instance.popper.querySelector(arrowElement);
  1423.  
  1424. // if arrowElement is not found, don't run the modifier
  1425. if (!arrowElement) {
  1426. return data;
  1427. }
  1428. } else {
  1429. // if the arrowElement isn't a query selector we must check that the
  1430. // provided DOM node is child of its popper node
  1431. if (!data.instance.popper.contains(arrowElement)) {
  1432. console.warn('WARNING: `arrow.element` must be child of its popper element!');
  1433. return data;
  1434. }
  1435. }
  1436.  
  1437. var placement = data.placement.split('-')[0];
  1438. var _data$offsets = data.offsets,
  1439. popper = _data$offsets.popper,
  1440. reference = _data$offsets.reference;
  1441.  
  1442. var isVertical = ['left', 'right'].indexOf(placement) !== -1;
  1443.  
  1444. var len = isVertical ? 'height' : 'width';
  1445. var sideCapitalized = isVertical ? 'Top' : 'Left';
  1446. var side = sideCapitalized.toLowerCase();
  1447. var altSide = isVertical ? 'left' : 'top';
  1448. var opSide = isVertical ? 'bottom' : 'right';
  1449. var arrowElementSize = getOuterSizes(arrowElement)[len];
  1450.  
  1451. //
  1452. // extends keepTogether behavior making sure the popper and its
  1453. // reference have enough pixels in conjunction
  1454. //
  1455.  
  1456. // top/left side
  1457. if (reference[opSide] - arrowElementSize < popper[side]) {
  1458. data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
  1459. }
  1460. // bottom/right side
  1461. if (reference[side] + arrowElementSize > popper[opSide]) {
  1462. data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
  1463. }
  1464. data.offsets.popper = getClientRect(data.offsets.popper);
  1465.  
  1466. // compute center of the popper
  1467. var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
  1468.  
  1469. // Compute the sideValue using the updated popper offsets
  1470. // take popper margin in account because we don't have this info available
  1471. var css = getStyleComputedProperty(data.instance.popper);
  1472. var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);
  1473. var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);
  1474. var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
  1475.  
  1476. // prevent arrowElement from being placed not contiguously to its popper
  1477. sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
  1478.  
  1479. data.arrowElement = arrowElement;
  1480. data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
  1481.  
  1482. return data;
  1483. }
  1484.  
  1485. /**
  1486. * Get the opposite placement variation of the given one
  1487. * @method
  1488. * @memberof Popper.Utils
  1489. * @argument {String} placement variation
  1490. * @returns {String} flipped placement variation
  1491. */
  1492. function getOppositeVariation(variation) {
  1493. if (variation === 'end') {
  1494. return 'start';
  1495. } else if (variation === 'start') {
  1496. return 'end';
  1497. }
  1498. return variation;
  1499. }
  1500.  
  1501. /**
  1502. * List of accepted placements to use as values of the `placement` option.<br />
  1503. * Valid placements are:
  1504. * - `auto`
  1505. * - `top`
  1506. * - `right`
  1507. * - `bottom`
  1508. * - `left`
  1509. *
  1510. * Each placement can have a variation from this list:
  1511. * - `-start`
  1512. * - `-end`
  1513. *
  1514. * Variations are interpreted easily if you think of them as the left to right
  1515. * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
  1516. * is right.<br />
  1517. * Vertically (`left` and `right`), `start` is top and `end` is bottom.
  1518. *
  1519. * Some valid examples are:
  1520. * - `top-end` (on top of reference, right aligned)
  1521. * - `right-start` (on right of reference, top aligned)
  1522. * - `bottom` (on bottom, centered)
  1523. * - `auto-end` (on the side with more space available, alignment depends by placement)
  1524. *
  1525. * @static
  1526. * @type {Array}
  1527. * @enum {String}
  1528. * @readonly
  1529. * @method placements
  1530. * @memberof Popper
  1531. */
  1532. var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
  1533.  
  1534. // Get rid of `auto` `auto-start` and `auto-end`
  1535. var validPlacements = placements.slice(3);
  1536.  
  1537. /**
  1538. * Given an initial placement, returns all the subsequent placements
  1539. * clockwise (or counter-clockwise).
  1540. *
  1541. * @method
  1542. * @memberof Popper.Utils
  1543. * @argument {String} placement - A valid placement (it accepts variations)
  1544. * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
  1545. * @returns {Array} placements including their variations
  1546. */
  1547. function clockwise(placement) {
  1548. var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1549.  
  1550. var index = validPlacements.indexOf(placement);
  1551. var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
  1552. return counter ? arr.reverse() : arr;
  1553. }
  1554.  
  1555. var BEHAVIORS = {
  1556. FLIP: 'flip',
  1557. CLOCKWISE: 'clockwise',
  1558. COUNTERCLOCKWISE: 'counterclockwise'
  1559. };
  1560.  
  1561. /**
  1562. * @function
  1563. * @memberof Modifiers
  1564. * @argument {Object} data - The data object generated by update method
  1565. * @argument {Object} options - Modifiers configuration and options
  1566. * @returns {Object} The data object, properly modified
  1567. */
  1568. function flip(data, options) {
  1569. // if `inner` modifier is enabled, we can't use the `flip` modifier
  1570. if (isModifierEnabled(data.instance.modifiers, 'inner')) {
  1571. return data;
  1572. }
  1573.  
  1574. if (data.flipped && data.placement === data.originalPlacement) {
  1575. // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
  1576. return data;
  1577. }
  1578.  
  1579. var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
  1580.  
  1581. var placement = data.placement.split('-')[0];
  1582. var placementOpposite = getOppositePlacement(placement);
  1583. var variation = data.placement.split('-')[1] || '';
  1584.  
  1585. var flipOrder = [];
  1586.  
  1587. switch (options.behavior) {
  1588. case BEHAVIORS.FLIP:
  1589. flipOrder = [placement, placementOpposite];
  1590. break;
  1591. case BEHAVIORS.CLOCKWISE:
  1592. flipOrder = clockwise(placement);
  1593. break;
  1594. case BEHAVIORS.COUNTERCLOCKWISE:
  1595. flipOrder = clockwise(placement, true);
  1596. break;
  1597. default:
  1598. flipOrder = options.behavior;
  1599. }
  1600.  
  1601. flipOrder.forEach(function (step, index) {
  1602. if (placement !== step || flipOrder.length === index + 1) {
  1603. return data;
  1604. }
  1605.  
  1606. placement = data.placement.split('-')[0];
  1607. placementOpposite = getOppositePlacement(placement);
  1608.  
  1609. var popperOffsets = data.offsets.popper;
  1610. var refOffsets = data.offsets.reference;
  1611.  
  1612. // using floor because the reference offsets may contain decimals we are not going to consider here
  1613. var floor = Math.floor;
  1614. var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
  1615.  
  1616. var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
  1617. var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
  1618. var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
  1619. var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
  1620.  
  1621. var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
  1622.  
  1623. // flip the variation if required
  1624. var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
  1625.  
  1626. // flips variation if reference element overflows boundaries
  1627. var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
  1628.  
  1629. // flips variation if popper content overflows boundaries
  1630. var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
  1631.  
  1632. var flippedVariation = flippedVariationByRef || flippedVariationByContent;
  1633.  
  1634. if (overlapsRef || overflowsBoundaries || flippedVariation) {
  1635. // this boolean to detect any flip loop
  1636. data.flipped = true;
  1637.  
  1638. if (overlapsRef || overflowsBoundaries) {
  1639. placement = flipOrder[index + 1];
  1640. }
  1641.  
  1642. if (flippedVariation) {
  1643. variation = getOppositeVariation(variation);
  1644. }
  1645.  
  1646. data.placement = placement + (variation ? '-' + variation : '');
  1647.  
  1648. // this object contains `position`, we want to preserve it along with
  1649. // any additional property we may add in the future
  1650. data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
  1651.  
  1652. data = runModifiers(data.instance.modifiers, data, 'flip');
  1653. }
  1654. });
  1655. return data;
  1656. }
  1657.  
  1658. /**
  1659. * @function
  1660. * @memberof Modifiers
  1661. * @argument {Object} data - The data object generated by update method
  1662. * @argument {Object} options - Modifiers configuration and options
  1663. * @returns {Object} The data object, properly modified
  1664. */
  1665. function keepTogether(data) {
  1666. var _data$offsets = data.offsets,
  1667. popper = _data$offsets.popper,
  1668. reference = _data$offsets.reference;
  1669.  
  1670. var placement = data.placement.split('-')[0];
  1671. var floor = Math.floor;
  1672. var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
  1673. var side = isVertical ? 'right' : 'bottom';
  1674. var opSide = isVertical ? 'left' : 'top';
  1675. var measurement = isVertical ? 'width' : 'height';
  1676.  
  1677. if (popper[side] < floor(reference[opSide])) {
  1678. data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
  1679. }
  1680. if (popper[opSide] > floor(reference[side])) {
  1681. data.offsets.popper[opSide] = floor(reference[side]);
  1682. }
  1683.  
  1684. return data;
  1685. }
  1686.  
  1687. /**
  1688. * Converts a string containing value + unit into a px value number
  1689. * @function
  1690. * @memberof {modifiers~offset}
  1691. * @private
  1692. * @argument {String} str - Value + unit string
  1693. * @argument {String} measurement - `height` or `width`
  1694. * @argument {Object} popperOffsets
  1695. * @argument {Object} referenceOffsets
  1696. * @returns {Number|String}
  1697. * Value in pixels, or original string if no values were extracted
  1698. */
  1699. function toValue(str, measurement, popperOffsets, referenceOffsets) {
  1700. // separate value from unit
  1701. var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
  1702. var value = +split[1];
  1703. var unit = split[2];
  1704.  
  1705. // If it's not a number it's an operator, I guess
  1706. if (!value) {
  1707. return str;
  1708. }
  1709.  
  1710. if (unit.indexOf('%') === 0) {
  1711. var element = void 0;
  1712. switch (unit) {
  1713. case '%p':
  1714. element = popperOffsets;
  1715. break;
  1716. case '%':
  1717. case '%r':
  1718. default:
  1719. element = referenceOffsets;
  1720. }
  1721.  
  1722. var rect = getClientRect(element);
  1723. return rect[measurement] / 100 * value;
  1724. } else if (unit === 'vh' || unit === 'vw') {
  1725. // if is a vh or vw, we calculate the size based on the viewport
  1726. var size = void 0;
  1727. if (unit === 'vh') {
  1728. size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  1729. } else {
  1730. size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  1731. }
  1732. return size / 100 * value;
  1733. } else {
  1734. // if is an explicit pixel unit, we get rid of the unit and keep the value
  1735. // if is an implicit unit, it's px, and we return just the value
  1736. return value;
  1737. }
  1738. }
  1739.  
  1740. /**
  1741. * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
  1742. * @function
  1743. * @memberof {modifiers~offset}
  1744. * @private
  1745. * @argument {String} offset
  1746. * @argument {Object} popperOffsets
  1747. * @argument {Object} referenceOffsets
  1748. * @argument {String} basePlacement
  1749. * @returns {Array} a two cells array with x and y offsets in numbers
  1750. */
  1751. function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
  1752. var offsets = [0, 0];
  1753.  
  1754. // Use height if placement is left or right and index is 0 otherwise use width
  1755. // in this way the first offset will use an axis and the second one
  1756. // will use the other one
  1757. var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
  1758.  
  1759. // Split the offset string to obtain a list of values and operands
  1760. // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
  1761. var fragments = offset.split(/(\+|\-)/).map(function (frag) {
  1762. return frag.trim();
  1763. });
  1764.  
  1765. // Detect if the offset string contains a pair of values or a single one
  1766. // they could be separated by comma or space
  1767. var divider = fragments.indexOf(find(fragments, function (frag) {
  1768. return frag.search(/,|\s/) !== -1;
  1769. }));
  1770.  
  1771. if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
  1772. console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
  1773. }
  1774.  
  1775. // If divider is found, we divide the list of values and operands to divide
  1776. // them by ofset X and Y.
  1777. var splitRegex = /\s*,\s*|\s+/;
  1778. var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
  1779.  
  1780. // Convert the values with units to absolute pixels to allow our computations
  1781. ops = ops.map(function (op, index) {
  1782. // Most of the units rely on the orientation of the popper
  1783. var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
  1784. var mergeWithPrevious = false;
  1785. return op
  1786. // This aggregates any `+` or `-` sign that aren't considered operators
  1787. // e.g.: 10 + +5 => [10, +, +5]
  1788. .reduce(function (a, b) {
  1789. if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
  1790. a[a.length - 1] = b;
  1791. mergeWithPrevious = true;
  1792. return a;
  1793. } else if (mergeWithPrevious) {
  1794. a[a.length - 1] += b;
  1795. mergeWithPrevious = false;
  1796. return a;
  1797. } else {
  1798. return a.concat(b);
  1799. }
  1800. }, [])
  1801. // Here we convert the string values into number values (in px)
  1802. .map(function (str) {
  1803. return toValue(str, measurement, popperOffsets, referenceOffsets);
  1804. });
  1805. });
  1806.  
  1807. // Loop trough the offsets arrays and execute the operations
  1808. ops.forEach(function (op, index) {
  1809. op.forEach(function (frag, index2) {
  1810. if (isNumeric(frag)) {
  1811. offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
  1812. }
  1813. });
  1814. });
  1815. return offsets;
  1816. }
  1817.  
  1818. /**
  1819. * @function
  1820. * @memberof Modifiers
  1821. * @argument {Object} data - The data object generated by update method
  1822. * @argument {Object} options - Modifiers configuration and options
  1823. * @argument {Number|String} options.offset=0
  1824. * The offset value as described in the modifier description
  1825. * @returns {Object} The data object, properly modified
  1826. */
  1827. function offset(data, _ref) {
  1828. var offset = _ref.offset;
  1829. var placement = data.placement,
  1830. _data$offsets = data.offsets,
  1831. popper = _data$offsets.popper,
  1832. reference = _data$offsets.reference;
  1833.  
  1834. var basePlacement = placement.split('-')[0];
  1835.  
  1836. var offsets = void 0;
  1837. if (isNumeric(+offset)) {
  1838. offsets = [+offset, 0];
  1839. } else {
  1840. offsets = parseOffset(offset, popper, reference, basePlacement);
  1841. }
  1842.  
  1843. if (basePlacement === 'left') {
  1844. popper.top += offsets[0];
  1845. popper.left -= offsets[1];
  1846. } else if (basePlacement === 'right') {
  1847. popper.top += offsets[0];
  1848. popper.left += offsets[1];
  1849. } else if (basePlacement === 'top') {
  1850. popper.left += offsets[0];
  1851. popper.top -= offsets[1];
  1852. } else if (basePlacement === 'bottom') {
  1853. popper.left += offsets[0];
  1854. popper.top += offsets[1];
  1855. }
  1856.  
  1857. data.popper = popper;
  1858. return data;
  1859. }
  1860.  
  1861. /**
  1862. * @function
  1863. * @memberof Modifiers
  1864. * @argument {Object} data - The data object generated by `update` method
  1865. * @argument {Object} options - Modifiers configuration and options
  1866. * @returns {Object} The data object, properly modified
  1867. */
  1868. function preventOverflow(data, options) {
  1869. var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
  1870.  
  1871. // If offsetParent is the reference element, we really want to
  1872. // go one step up and use the next offsetParent as reference to
  1873. // avoid to make this modifier completely useless and look like broken
  1874. if (data.instance.reference === boundariesElement) {
  1875. boundariesElement = getOffsetParent(boundariesElement);
  1876. }
  1877.  
  1878. // NOTE: DOM access here
  1879. // resets the popper's position so that the document size can be calculated excluding
  1880. // the size of the popper element itself
  1881. var transformProp = getSupportedPropertyName('transform');
  1882. var popperStyles = data.instance.popper.style; // assignment to help minification
  1883. var top = popperStyles.top,
  1884. left = popperStyles.left,
  1885. transform = popperStyles[transformProp];
  1886.  
  1887. popperStyles.top = '';
  1888. popperStyles.left = '';
  1889. popperStyles[transformProp] = '';
  1890.  
  1891. var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
  1892.  
  1893. // NOTE: DOM access here
  1894. // restores the original style properties after the offsets have been computed
  1895. popperStyles.top = top;
  1896. popperStyles.left = left;
  1897. popperStyles[transformProp] = transform;
  1898.  
  1899. options.boundaries = boundaries;
  1900.  
  1901. var order = options.priority;
  1902. var popper = data.offsets.popper;
  1903.  
  1904. var check = {
  1905. primary: function primary(placement) {
  1906. var value = popper[placement];
  1907. if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
  1908. value = Math.max(popper[placement], boundaries[placement]);
  1909. }
  1910. return defineProperty({}, placement, value);
  1911. },
  1912. secondary: function secondary(placement) {
  1913. var mainSide = placement === 'right' ? 'left' : 'top';
  1914. var value = popper[mainSide];
  1915. if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
  1916. value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
  1917. }
  1918. return defineProperty({}, mainSide, value);
  1919. }
  1920. };
  1921.  
  1922. order.forEach(function (placement) {
  1923. var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
  1924. popper = _extends({}, popper, check[side](placement));
  1925. });
  1926.  
  1927. data.offsets.popper = popper;
  1928.  
  1929. return data;
  1930. }
  1931.  
  1932. /**
  1933. * @function
  1934. * @memberof Modifiers
  1935. * @argument {Object} data - The data object generated by `update` method
  1936. * @argument {Object} options - Modifiers configuration and options
  1937. * @returns {Object} The data object, properly modified
  1938. */
  1939. function shift(data) {
  1940. var placement = data.placement;
  1941. var basePlacement = placement.split('-')[0];
  1942. var shiftvariation = placement.split('-')[1];
  1943.  
  1944. // if shift shiftvariation is specified, run the modifier
  1945. if (shiftvariation) {
  1946. var _data$offsets = data.offsets,
  1947. reference = _data$offsets.reference,
  1948. popper = _data$offsets.popper;
  1949.  
  1950. var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
  1951. var side = isVertical ? 'left' : 'top';
  1952. var measurement = isVertical ? 'width' : 'height';
  1953.  
  1954. var shiftOffsets = {
  1955. start: defineProperty({}, side, reference[side]),
  1956. end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
  1957. };
  1958.  
  1959. data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
  1960. }
  1961.  
  1962. return data;
  1963. }
  1964.  
  1965. /**
  1966. * @function
  1967. * @memberof Modifiers
  1968. * @argument {Object} data - The data object generated by update method
  1969. * @argument {Object} options - Modifiers configuration and options
  1970. * @returns {Object} The data object, properly modified
  1971. */
  1972. function hide(data) {
  1973. if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
  1974. return data;
  1975. }
  1976.  
  1977. var refRect = data.offsets.reference;
  1978. var bound = find(data.instance.modifiers, function (modifier) {
  1979. return modifier.name === 'preventOverflow';
  1980. }).boundaries;
  1981.  
  1982. if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
  1983. // Avoid unnecessary DOM access if visibility hasn't changed
  1984. if (data.hide === true) {
  1985. return data;
  1986. }
  1987.  
  1988. data.hide = true;
  1989. data.attributes['x-out-of-boundaries'] = '';
  1990. } else {
  1991. // Avoid unnecessary DOM access if visibility hasn't changed
  1992. if (data.hide === false) {
  1993. return data;
  1994. }
  1995.  
  1996. data.hide = false;
  1997. data.attributes['x-out-of-boundaries'] = false;
  1998. }
  1999.  
  2000. return data;
  2001. }
  2002.  
  2003. /**
  2004. * @function
  2005. * @memberof Modifiers
  2006. * @argument {Object} data - The data object generated by `update` method
  2007. * @argument {Object} options - Modifiers configuration and options
  2008. * @returns {Object} The data object, properly modified
  2009. */
  2010. function inner(data) {
  2011. var placement = data.placement;
  2012. var basePlacement = placement.split('-')[0];
  2013. var _data$offsets = data.offsets,
  2014. popper = _data$offsets.popper,
  2015. reference = _data$offsets.reference;
  2016.  
  2017. var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
  2018.  
  2019. var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
  2020.  
  2021. popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
  2022.  
  2023. data.placement = getOppositePlacement(placement);
  2024. data.offsets.popper = getClientRect(popper);
  2025.  
  2026. return data;
  2027. }
  2028.  
  2029. /**
  2030. * Modifier function, each modifier can have a function of this type assigned
  2031. * to its `fn` property.<br />
  2032. * These functions will be called on each update, this means that you must
  2033. * make sure they are performant enough to avoid performance bottlenecks.
  2034. *
  2035. * @function ModifierFn
  2036. * @argument {dataObject} data - The data object generated by `update` method
  2037. * @argument {Object} options - Modifiers configuration and options
  2038. * @returns {dataObject} The data object, properly modified
  2039. */
  2040.  
  2041. /**
  2042. * Modifiers are plugins used to alter the behavior of your poppers.<br />
  2043. * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
  2044. * needed by the library.
  2045. *
  2046. * Usually you don't want to override the `order`, `fn` and `onLoad` props.
  2047. * All the other properties are configurations that could be tweaked.
  2048. * @namespace modifiers
  2049. */
  2050. var modifiers = {
  2051. /**
  2052. * Modifier used to shift the popper on the start or end of its reference
  2053. * element.<br />
  2054. * It will read the variation of the `placement` property.<br />
  2055. * It can be one either `-end` or `-start`.
  2056. * @memberof modifiers
  2057. * @inner
  2058. */
  2059. shift: {
  2060. /** @prop {number} order=100 - Index used to define the order of execution */
  2061. order: 100,
  2062. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2063. enabled: true,
  2064. /** @prop {ModifierFn} */
  2065. fn: shift
  2066. },
  2067.  
  2068. /**
  2069. * The `offset` modifier can shift your popper on both its axis.
  2070. *
  2071. * It accepts the following units:
  2072. * - `px` or unit-less, interpreted as pixels
  2073. * - `%` or `%r`, percentage relative to the length of the reference element
  2074. * - `%p`, percentage relative to the length of the popper element
  2075. * - `vw`, CSS viewport width unit
  2076. * - `vh`, CSS viewport height unit
  2077. *
  2078. * For length is intended the main axis relative to the placement of the popper.<br />
  2079. * This means that if the placement is `top` or `bottom`, the length will be the
  2080. * `width`. In case of `left` or `right`, it will be the `height`.
  2081. *
  2082. * You can provide a single value (as `Number` or `String`), or a pair of values
  2083. * as `String` divided by a comma or one (or more) white spaces.<br />
  2084. * The latter is a deprecated method because it leads to confusion and will be
  2085. * removed in v2.<br />
  2086. * Additionally, it accepts additions and subtractions between different units.
  2087. * Note that multiplications and divisions aren't supported.
  2088. *
  2089. * Valid examples are:
  2090. * ```
  2091. * 10
  2092. * '10%'
  2093. * '10, 10'
  2094. * '10%, 10'
  2095. * '10 + 10%'
  2096. * '10 - 5vh + 3%'
  2097. * '-10px + 5vh, 5px - 6%'
  2098. * ```
  2099. * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
  2100. * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
  2101. * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
  2102. *
  2103. * @memberof modifiers
  2104. * @inner
  2105. */
  2106. offset: {
  2107. /** @prop {number} order=200 - Index used to define the order of execution */
  2108. order: 200,
  2109. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2110. enabled: true,
  2111. /** @prop {ModifierFn} */
  2112. fn: offset,
  2113. /** @prop {Number|String} offset=0
  2114. * The offset value as described in the modifier description
  2115. */
  2116. offset: 0
  2117. },
  2118.  
  2119. /**
  2120. * Modifier used to prevent the popper from being positioned outside the boundary.
  2121. *
  2122. * A scenario exists where the reference itself is not within the boundaries.<br />
  2123. * We can say it has "escaped the boundaries" — or just "escaped".<br />
  2124. * In this case we need to decide whether the popper should either:
  2125. *
  2126. * - detach from the reference and remain "trapped" in the boundaries, or
  2127. * - if it should ignore the boundary and "escape with its reference"
  2128. *
  2129. * When `escapeWithReference` is set to`true` and reference is completely
  2130. * outside its boundaries, the popper will overflow (or completely leave)
  2131. * the boundaries in order to remain attached to the edge of the reference.
  2132. *
  2133. * @memberof modifiers
  2134. * @inner
  2135. */
  2136. preventOverflow: {
  2137. /** @prop {number} order=300 - Index used to define the order of execution */
  2138. order: 300,
  2139. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2140. enabled: true,
  2141. /** @prop {ModifierFn} */
  2142. fn: preventOverflow,
  2143. /**
  2144. * @prop {Array} [priority=['left','right','top','bottom']]
  2145. * Popper will try to prevent overflow following these priorities by default,
  2146. * then, it could overflow on the left and on top of the `boundariesElement`
  2147. */
  2148. priority: ['left', 'right', 'top', 'bottom'],
  2149. /**
  2150. * @prop {number} padding=5
  2151. * Amount of pixel used to define a minimum distance between the boundaries
  2152. * and the popper. This makes sure the popper always has a little padding
  2153. * between the edges of its container
  2154. */
  2155. padding: 5,
  2156. /**
  2157. * @prop {String|HTMLElement} boundariesElement='scrollParent'
  2158. * Boundaries used by the modifier. Can be `scrollParent`, `window`,
  2159. * `viewport` or any DOM element.
  2160. */
  2161. boundariesElement: 'scrollParent'
  2162. },
  2163.  
  2164. /**
  2165. * Modifier used to make sure the reference and its popper stay near each other
  2166. * without leaving any gap between the two. Especially useful when the arrow is
  2167. * enabled and you want to ensure that it points to its reference element.
  2168. * It cares only about the first axis. You can still have poppers with margin
  2169. * between the popper and its reference element.
  2170. * @memberof modifiers
  2171. * @inner
  2172. */
  2173. keepTogether: {
  2174. /** @prop {number} order=400 - Index used to define the order of execution */
  2175. order: 400,
  2176. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2177. enabled: true,
  2178. /** @prop {ModifierFn} */
  2179. fn: keepTogether
  2180. },
  2181.  
  2182. /**
  2183. * This modifier is used to move the `arrowElement` of the popper to make
  2184. * sure it is positioned between the reference element and its popper element.
  2185. * It will read the outer size of the `arrowElement` node to detect how many
  2186. * pixels of conjunction are needed.
  2187. *
  2188. * It has no effect if no `arrowElement` is provided.
  2189. * @memberof modifiers
  2190. * @inner
  2191. */
  2192. arrow: {
  2193. /** @prop {number} order=500 - Index used to define the order of execution */
  2194. order: 500,
  2195. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2196. enabled: true,
  2197. /** @prop {ModifierFn} */
  2198. fn: arrow,
  2199. /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
  2200. element: '[x-arrow]'
  2201. },
  2202.  
  2203. /**
  2204. * Modifier used to flip the popper's placement when it starts to overlap its
  2205. * reference element.
  2206. *
  2207. * Requires the `preventOverflow` modifier before it in order to work.
  2208. *
  2209. * **NOTE:** this modifier will interrupt the current update cycle and will
  2210. * restart it if it detects the need to flip the placement.
  2211. * @memberof modifiers
  2212. * @inner
  2213. */
  2214. flip: {
  2215. /** @prop {number} order=600 - Index used to define the order of execution */
  2216. order: 600,
  2217. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2218. enabled: true,
  2219. /** @prop {ModifierFn} */
  2220. fn: flip,
  2221. /**
  2222. * @prop {String|Array} behavior='flip'
  2223. * The behavior used to change the popper's placement. It can be one of
  2224. * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
  2225. * placements (with optional variations)
  2226. */
  2227. behavior: 'flip',
  2228. /**
  2229. * @prop {number} padding=5
  2230. * The popper will flip if it hits the edges of the `boundariesElement`
  2231. */
  2232. padding: 5,
  2233. /**
  2234. * @prop {String|HTMLElement} boundariesElement='viewport'
  2235. * The element which will define the boundaries of the popper position.
  2236. * The popper will never be placed outside of the defined boundaries
  2237. * (except if `keepTogether` is enabled)
  2238. */
  2239. boundariesElement: 'viewport',
  2240. /**
  2241. * @prop {Boolean} flipVariations=false
  2242. * The popper will switch placement variation between `-start` and `-end` when
  2243. * the reference element overlaps its boundaries.
  2244. *
  2245. * The original placement should have a set variation.
  2246. */
  2247. flipVariations: false,
  2248. /**
  2249. * @prop {Boolean} flipVariationsByContent=false
  2250. * The popper will switch placement variation between `-start` and `-end` when
  2251. * the popper element overlaps its reference boundaries.
  2252. *
  2253. * The original placement should have a set variation.
  2254. */
  2255. flipVariationsByContent: false
  2256. },
  2257.  
  2258. /**
  2259. * Modifier used to make the popper flow toward the inner of the reference element.
  2260. * By default, when this modifier is disabled, the popper will be placed outside
  2261. * the reference element.
  2262. * @memberof modifiers
  2263. * @inner
  2264. */
  2265. inner: {
  2266. /** @prop {number} order=700 - Index used to define the order of execution */
  2267. order: 700,
  2268. /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
  2269. enabled: false,
  2270. /** @prop {ModifierFn} */
  2271. fn: inner
  2272. },
  2273.  
  2274. /**
  2275. * Modifier used to hide the popper when its reference element is outside of the
  2276. * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
  2277. * be used to hide with a CSS selector the popper when its reference is
  2278. * out of boundaries.
  2279. *
  2280. * Requires the `preventOverflow` modifier before it in order to work.
  2281. * @memberof modifiers
  2282. * @inner
  2283. */
  2284. hide: {
  2285. /** @prop {number} order=800 - Index used to define the order of execution */
  2286. order: 800,
  2287. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2288. enabled: true,
  2289. /** @prop {ModifierFn} */
  2290. fn: hide
  2291. },
  2292.  
  2293. /**
  2294. * Computes the style that will be applied to the popper element to gets
  2295. * properly positioned.
  2296. *
  2297. * Note that this modifier will not touch the DOM, it just prepares the styles
  2298. * so that `applyStyle` modifier can apply it. This separation is useful
  2299. * in case you need to replace `applyStyle` with a custom implementation.
  2300. *
  2301. * This modifier has `850` as `order` value to maintain backward compatibility
  2302. * with previous versions of Popper.js. Expect the modifiers ordering method
  2303. * to change in future major versions of the library.
  2304. *
  2305. * @memberof modifiers
  2306. * @inner
  2307. */
  2308. computeStyle: {
  2309. /** @prop {number} order=850 - Index used to define the order of execution */
  2310. order: 850,
  2311. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2312. enabled: true,
  2313. /** @prop {ModifierFn} */
  2314. fn: computeStyle,
  2315. /**
  2316. * @prop {Boolean} gpuAcceleration=true
  2317. * If true, it uses the CSS 3D transformation to position the popper.
  2318. * Otherwise, it will use the `top` and `left` properties
  2319. */
  2320. gpuAcceleration: true,
  2321. /**
  2322. * @prop {string} [x='bottom']
  2323. * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
  2324. * Change this if your popper should grow in a direction different from `bottom`
  2325. */
  2326. x: 'bottom',
  2327. /**
  2328. * @prop {string} [x='left']
  2329. * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
  2330. * Change this if your popper should grow in a direction different from `right`
  2331. */
  2332. y: 'right'
  2333. },
  2334.  
  2335. /**
  2336. * Applies the computed styles to the popper element.
  2337. *
  2338. * All the DOM manipulations are limited to this modifier. This is useful in case
  2339. * you want to integrate Popper.js inside a framework or view library and you
  2340. * want to delegate all the DOM manipulations to it.
  2341. *
  2342. * Note that if you disable this modifier, you must make sure the popper element
  2343. * has its position set to `absolute` before Popper.js can do its work!
  2344. *
  2345. * Just disable this modifier and define your own to achieve the desired effect.
  2346. *
  2347. * @memberof modifiers
  2348. * @inner
  2349. */
  2350. applyStyle: {
  2351. /** @prop {number} order=900 - Index used to define the order of execution */
  2352. order: 900,
  2353. /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
  2354. enabled: true,
  2355. /** @prop {ModifierFn} */
  2356. fn: applyStyle,
  2357. /** @prop {Function} */
  2358. onLoad: applyStyleOnLoad,
  2359. /**
  2360. * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
  2361. * @prop {Boolean} gpuAcceleration=true
  2362. * If true, it uses the CSS 3D transformation to position the popper.
  2363. * Otherwise, it will use the `top` and `left` properties
  2364. */
  2365. gpuAcceleration: undefined
  2366. }
  2367. };
  2368.  
  2369. /**
  2370. * The `dataObject` is an object containing all the information used by Popper.js.
  2371. * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
  2372. * @name dataObject
  2373. * @property {Object} data.instance The Popper.js instance
  2374. * @property {String} data.placement Placement applied to popper
  2375. * @property {String} data.originalPlacement Placement originally defined on init
  2376. * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
  2377. * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
  2378. * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
  2379. * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
  2380. * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
  2381. * @property {Object} data.boundaries Offsets of the popper boundaries
  2382. * @property {Object} data.offsets The measurements of popper, reference and arrow elements
  2383. * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
  2384. * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
  2385. * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
  2386. */
  2387.  
  2388. /**
  2389. * Default options provided to Popper.js constructor.<br />
  2390. * These can be overridden using the `options` argument of Popper.js.<br />
  2391. * To override an option, simply pass an object with the same
  2392. * structure of the `options` object, as the 3rd argument. For example:
  2393. * ```
  2394. * new Popper(ref, pop, {
  2395. * modifiers: {
  2396. * preventOverflow: { enabled: false }
  2397. * }
  2398. * })
  2399. * ```
  2400. * @type {Object}
  2401. * @static
  2402. * @memberof Popper
  2403. */
  2404. var Defaults = {
  2405. /**
  2406. * Popper's placement.
  2407. * @prop {Popper.placements} placement='bottom'
  2408. */
  2409. placement: 'bottom',
  2410.  
  2411. /**
  2412. * Set this to true if you want popper to position it self in 'fixed' mode
  2413. * @prop {Boolean} positionFixed=false
  2414. */
  2415. positionFixed: false,
  2416.  
  2417. /**
  2418. * Whether events (resize, scroll) are initially enabled.
  2419. * @prop {Boolean} eventsEnabled=true
  2420. */
  2421. eventsEnabled: true,
  2422.  
  2423. /**
  2424. * Set to true if you want to automatically remove the popper when
  2425. * you call the `destroy` method.
  2426. * @prop {Boolean} removeOnDestroy=false
  2427. */
  2428. removeOnDestroy: false,
  2429.  
  2430. /**
  2431. * Callback called when the popper is created.<br />
  2432. * By default, it is set to no-op.<br />
  2433. * Access Popper.js instance with `data.instance`.
  2434. * @prop {onCreate}
  2435. */
  2436. onCreate: function onCreate() {},
  2437.  
  2438. /**
  2439. * Callback called when the popper is updated. This callback is not called
  2440. * on the initialization/creation of the popper, but only on subsequent
  2441. * updates.<br />
  2442. * By default, it is set to no-op.<br />
  2443. * Access Popper.js instance with `data.instance`.
  2444. * @prop {onUpdate}
  2445. */
  2446. onUpdate: function onUpdate() {},
  2447.  
  2448. /**
  2449. * List of modifiers used to modify the offsets before they are applied to the popper.
  2450. * They provide most of the functionalities of Popper.js.
  2451. * @prop {modifiers}
  2452. */
  2453. modifiers: modifiers
  2454. };
  2455.  
  2456. /**
  2457. * @callback onCreate
  2458. * @param {dataObject} data
  2459. */
  2460.  
  2461. /**
  2462. * @callback onUpdate
  2463. * @param {dataObject} data
  2464. */
  2465.  
  2466. // Utils
  2467. // Methods
  2468. var Popper = function () {
  2469. /**
  2470. * Creates a new Popper.js instance.
  2471. * @class Popper
  2472. * @param {Element|referenceObject} reference - The reference element used to position the popper
  2473. * @param {Element} popper - The HTML / XML element used as the popper
  2474. * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
  2475. * @return {Object} instance - The generated Popper.js instance
  2476. */
  2477. function Popper(reference, popper) {
  2478. var _this = this;
  2479.  
  2480. var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  2481. classCallCheck(this, Popper);
  2482.  
  2483. this.scheduleUpdate = function () {
  2484. return requestAnimationFrame(_this.update);
  2485. };
  2486.  
  2487. // make update() debounced, so that it only runs at most once-per-tick
  2488. this.update = debounce(this.update.bind(this));
  2489.  
  2490. // with {} we create a new object with the options inside it
  2491. this.options = _extends({}, Popper.Defaults, options);
  2492.  
  2493. // init state
  2494. this.state = {
  2495. isDestroyed: false,
  2496. isCreated: false,
  2497. scrollParents: []
  2498. };
  2499.  
  2500. // get reference and popper elements (allow jQuery wrappers)
  2501. this.reference = reference && reference.jquery ? reference[0] : reference;
  2502. this.popper = popper && popper.jquery ? popper[0] : popper;
  2503.  
  2504. // Deep merge modifiers options
  2505. this.options.modifiers = {};
  2506. Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
  2507. _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
  2508. });
  2509.  
  2510. // Refactoring modifiers' list (Object => Array)
  2511. this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
  2512. return _extends({
  2513. name: name
  2514. }, _this.options.modifiers[name]);
  2515. })
  2516. // sort the modifiers by order
  2517. .sort(function (a, b) {
  2518. return a.order - b.order;
  2519. });
  2520.  
  2521. // modifiers have the ability to execute arbitrary code when Popper.js get inited
  2522. // such code is executed in the same order of its modifier
  2523. // they could add new properties to their options configuration
  2524. // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
  2525. this.modifiers.forEach(function (modifierOptions) {
  2526. if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
  2527. modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
  2528. }
  2529. });
  2530.  
  2531. // fire the first update to position the popper in the right place
  2532. this.update();
  2533.  
  2534. var eventsEnabled = this.options.eventsEnabled;
  2535. if (eventsEnabled) {
  2536. // setup event listeners, they will take care of update the position in specific situations
  2537. this.enableEventListeners();
  2538. }
  2539.  
  2540. this.state.eventsEnabled = eventsEnabled;
  2541. }
  2542.  
  2543. // We can't use class properties because they don't get listed in the
  2544. // class prototype and break stuff like Sinon stubs
  2545.  
  2546.  
  2547. createClass(Popper, [{
  2548. key: 'update',
  2549. value: function update$$1() {
  2550. return update.call(this);
  2551. }
  2552. }, {
  2553. key: 'destroy',
  2554. value: function destroy$$1() {
  2555. return destroy.call(this);
  2556. }
  2557. }, {
  2558. key: 'enableEventListeners',
  2559. value: function enableEventListeners$$1() {
  2560. return enableEventListeners.call(this);
  2561. }
  2562. }, {
  2563. key: 'disableEventListeners',
  2564. value: function disableEventListeners$$1() {
  2565. return disableEventListeners.call(this);
  2566. }
  2567.  
  2568. /**
  2569. * Schedules an update. It will run on the next UI update available.
  2570. * @method scheduleUpdate
  2571. * @memberof Popper
  2572. */
  2573.  
  2574.  
  2575. /**
  2576. * Collection of utilities useful when writing custom modifiers.
  2577. * Starting from version 1.7, this method is available only if you
  2578. * include `popper-utils.js` before `popper.js`.
  2579. *
  2580. * **DEPRECATION**: This way to access PopperUtils is deprecated
  2581. * and will be removed in v2! Use the PopperUtils module directly instead.
  2582. * Due to the high instability of the methods contained in Utils, we can't
  2583. * guarantee them to follow semver. Use them at your own risk!
  2584. * @static
  2585. * @private
  2586. * @type {Object}
  2587. * @deprecated since version 1.8
  2588. * @member Utils
  2589. * @memberof Popper
  2590. */
  2591.  
  2592. }]);
  2593. return Popper;
  2594. }();
  2595.  
  2596. /**
  2597. * The `referenceObject` is an object that provides an interface compatible with Popper.js
  2598. * and lets you use it as replacement of a real DOM node.<br />
  2599. * You can use this method to position a popper relatively to a set of coordinates
  2600. * in case you don't have a DOM node to use as reference.
  2601. *
  2602. * ```
  2603. * new Popper(referenceObject, popperNode);
  2604. * ```
  2605. *
  2606. * NB: This feature isn't supported in Internet Explorer 10.
  2607. * @name referenceObject
  2608. * @property {Function} data.getBoundingClientRect
  2609. * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
  2610. * @property {number} data.clientWidth
  2611. * An ES6 getter that will return the width of the virtual reference element.
  2612. * @property {number} data.clientHeight
  2613. * An ES6 getter that will return the height of the virtual reference element.
  2614. */
  2615.  
  2616.  
  2617. Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
  2618. Popper.placements = placements;
  2619. Popper.Defaults = Defaults;
  2620.  
  2621. return Popper;
  2622.  
  2623. })));
  2624. //# sourceMappingURL=popper.js.map
  2625.  
  2626. /**!
  2627. * tippy.js v5.2.1
  2628. * (c) 2017-2020 atomiks
  2629. * MIT License
  2630. */
  2631. var tippy = (function (Popper) {
  2632. 'use strict';
  2633.  
  2634. Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;
  2635.  
  2636. var css = ".tippy-tooltip[data-animation=fade][data-state=hidden]{opacity:0}.tippy-iOS{cursor:pointer!important;-webkit-tap-highlight-color:transparent}.tippy-popper{pointer-events:none;max-width:calc(100vw - 10px);transition-timing-function:cubic-bezier(.165,.84,.44,1);transition-property:transform}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;background-color:#333;transition-property:visibility,opacity,transform;outline:0}.tippy-tooltip[data-placement^=top]>.tippy-arrow{border-width:8px 8px 0;border-top-color:#333;margin:0 3px;transform-origin:50% 0;bottom:-7px}.tippy-tooltip[data-placement^=bottom]>.tippy-arrow{border-width:0 8px 8px;border-bottom-color:#333;margin:0 3px;transform-origin:50% 7px;top:-7px}.tippy-tooltip[data-placement^=left]>.tippy-arrow{border-width:8px 0 8px 8px;border-left-color:#333;margin:3px 0;transform-origin:0 50%;right:-7px}.tippy-tooltip[data-placement^=right]>.tippy-arrow{border-width:8px 8px 8px 0;border-right-color:#333;margin:3px 0;transform-origin:7px 50%;left:-7px}.tippy-tooltip[data-interactive][data-state=visible]{pointer-events:auto}.tippy-tooltip[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{position:absolute;border-color:transparent;border-style:solid}.tippy-content{padding:5px 9px}";
  2637.  
  2638. /**
  2639. * Injects a string of CSS styles to a style node in <head>
  2640. */
  2641. function injectCSS(css) {
  2642. var style = document.createElement('style');
  2643. style.textContent = css;
  2644. style.setAttribute('data-tippy-stylesheet', '');
  2645. var head = document.head;
  2646. var firstStyleOrLinkTag = document.querySelector('head>style,head>link');
  2647.  
  2648. if (firstStyleOrLinkTag) {
  2649. head.insertBefore(style, firstStyleOrLinkTag);
  2650. } else {
  2651. head.appendChild(style);
  2652. }
  2653. }
  2654.  
  2655. function _extends() {
  2656. _extends = Object.assign || function (target) {
  2657. for (var i = 1; i < arguments.length; i++) {
  2658. var source = arguments[i];
  2659.  
  2660. for (var key in source) {
  2661. if (Object.prototype.hasOwnProperty.call(source, key)) {
  2662. target[key] = source[key];
  2663. }
  2664. }
  2665. }
  2666.  
  2667. return target;
  2668. };
  2669.  
  2670. return _extends.apply(this, arguments);
  2671. }
  2672.  
  2673. var PASSIVE = {
  2674. passive: true
  2675. };
  2676. var ROUND_ARROW = '<svg viewBox="0 0 18 7" xmlns="http://www.w3.org/2000/svg"><path d="M0 7s2.021-.015 5.253-4.218C6.584 1.051 7.797.007 9 0c1.203-.007 2.416 1.035 3.761 2.782C16.012 7.005 18 7 18 7H0z"/></svg>';
  2677. var IOS_CLASS = "tippy-iOS";
  2678. var POPPER_CLASS = "tippy-popper";
  2679. var TOOLTIP_CLASS = "tippy-tooltip";
  2680. var CONTENT_CLASS = "tippy-content";
  2681. var BACKDROP_CLASS = "tippy-backdrop";
  2682. var ARROW_CLASS = "tippy-arrow";
  2683. var SVG_ARROW_CLASS = "tippy-svg-arrow";
  2684. var POPPER_SELECTOR = "." + POPPER_CLASS;
  2685. var TOOLTIP_SELECTOR = "." + TOOLTIP_CLASS;
  2686. var CONTENT_SELECTOR = "." + CONTENT_CLASS;
  2687. var ARROW_SELECTOR = "." + ARROW_CLASS;
  2688. var SVG_ARROW_SELECTOR = "." + SVG_ARROW_CLASS;
  2689.  
  2690. /**
  2691. * Triggers reflow
  2692. */
  2693. function reflow(element) {
  2694. void element.offsetHeight;
  2695. }
  2696. /**
  2697. * Sets the innerHTML of an element
  2698. */
  2699.  
  2700. function setInnerHTML(element, html) {
  2701. element[innerHTML()] = html;
  2702. }
  2703. /**
  2704. * Determines if the value is a reference element
  2705. */
  2706.  
  2707. function isReferenceElement(value) {
  2708. return !!(value && value._tippy && value._tippy.reference === value);
  2709. }
  2710. /**
  2711. * Safe .hasOwnProperty check, for prototype-less objects
  2712. */
  2713.  
  2714. function hasOwnProperty(obj, key) {
  2715. return {}.hasOwnProperty.call(obj, key);
  2716. }
  2717. /**
  2718. * Returns an array of elements based on the value
  2719. */
  2720.  
  2721. function getArrayOfElements(value) {
  2722. if (isElement(value)) {
  2723. return [value];
  2724. }
  2725.  
  2726. if (isNodeList(value)) {
  2727. return arrayFrom(value);
  2728. }
  2729.  
  2730. if (Array.isArray(value)) {
  2731. return value;
  2732. }
  2733.  
  2734. return arrayFrom(document.querySelectorAll(value));
  2735. }
  2736. /**
  2737. * Returns a value at a given index depending on if it's an array or number
  2738. */
  2739.  
  2740. function getValueAtIndexOrReturn(value, index, defaultValue) {
  2741. if (Array.isArray(value)) {
  2742. var v = value[index];
  2743. return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v;
  2744. }
  2745.  
  2746. return value;
  2747. }
  2748. /**
  2749. * Prevents errors from being thrown while accessing nested modifier objects
  2750. * in `popperOptions`
  2751. */
  2752.  
  2753. function getModifier(obj, key) {
  2754. return obj && obj.modifiers && obj.modifiers[key];
  2755. }
  2756. /**
  2757. * Determines if the value is of type
  2758. */
  2759.  
  2760. function isType(value, type) {
  2761. var str = {}.toString.call(value);
  2762. return str.indexOf('[object') === 0 && str.indexOf(type + "]") > -1;
  2763. }
  2764. /**
  2765. * Determines if the value is of type Element
  2766. */
  2767.  
  2768. function isElement(value) {
  2769. return isType(value, 'Element');
  2770. }
  2771. /**
  2772. * Determines if the value is of type NodeList
  2773. */
  2774.  
  2775. function isNodeList(value) {
  2776. return isType(value, 'NodeList');
  2777. }
  2778. /**
  2779. * Determines if the value is of type MouseEvent
  2780. */
  2781.  
  2782. function isMouseEvent(value) {
  2783. return isType(value, 'MouseEvent');
  2784. }
  2785. /**
  2786. * Firefox extensions don't allow setting .innerHTML directly, this will trick
  2787. * it
  2788. */
  2789.  
  2790. function innerHTML() {
  2791. return 'innerHTML';
  2792. }
  2793. /**
  2794. * Evaluates a function if one, or returns the value
  2795. */
  2796.  
  2797. function invokeWithArgsOrReturn(value, args) {
  2798. return typeof value === 'function' ? value.apply(void 0, args) : value;
  2799. }
  2800. /**
  2801. * Sets a popperInstance modifier's property to a value
  2802. */
  2803.  
  2804. function setModifierValue(modifiers, name, property, value) {
  2805. modifiers.filter(function (m) {
  2806. return m.name === name;
  2807. })[0][property] = value;
  2808. }
  2809. /**
  2810. * Returns a new `div` element
  2811. */
  2812.  
  2813. function div() {
  2814. return document.createElement('div');
  2815. }
  2816. /**
  2817. * Applies a transition duration to a list of elements
  2818. */
  2819.  
  2820. function setTransitionDuration(els, value) {
  2821. els.forEach(function (el) {
  2822. if (el) {
  2823. el.style.transitionDuration = value + "ms";
  2824. }
  2825. });
  2826. }
  2827. /**
  2828. * Sets the visibility state to elements so they can begin to transition
  2829. */
  2830.  
  2831. function setVisibilityState(els, state) {
  2832. els.forEach(function (el) {
  2833. if (el) {
  2834. el.setAttribute('data-state', state);
  2835. }
  2836. });
  2837. }
  2838. /**
  2839. * Debounce utility. To avoid bloating bundle size, we're only passing 1
  2840. * argument here, a more generic function would pass all arguments. Only
  2841. * `onMouseMove` uses this which takes the event object for now.
  2842. */
  2843.  
  2844. function debounce(fn, ms) {
  2845. // Avoid wrapping in `setTimeout` if ms is 0 anyway
  2846. if (ms === 0) {
  2847. return fn;
  2848. }
  2849.  
  2850. var timeout;
  2851. return function (arg) {
  2852. clearTimeout(timeout);
  2853. timeout = setTimeout(function () {
  2854. fn(arg);
  2855. }, ms);
  2856. };
  2857. }
  2858. /**
  2859. * Preserves the original function invocation when another function replaces it
  2860. */
  2861.  
  2862. function preserveInvocation(originalFn, currentFn, args) {
  2863. if (originalFn && originalFn !== currentFn) {
  2864. originalFn.apply(void 0, args);
  2865. }
  2866. }
  2867. /**
  2868. * Deletes properties from an object (pure)
  2869. */
  2870.  
  2871. function removeProperties(obj, keys) {
  2872. var clone = _extends({}, obj);
  2873.  
  2874. keys.forEach(function (key) {
  2875. delete clone[key];
  2876. });
  2877. return clone;
  2878. }
  2879. /**
  2880. * Ponyfill for Array.from - converts iterable values to an array
  2881. */
  2882.  
  2883. function arrayFrom(value) {
  2884. return [].slice.call(value);
  2885. }
  2886. /**
  2887. * Works like Element.prototype.closest, but uses a callback instead
  2888. */
  2889.  
  2890. function closestCallback(element, callback) {
  2891. while (element) {
  2892. if (callback(element)) {
  2893. return element;
  2894. }
  2895.  
  2896. element = element.parentElement;
  2897. }
  2898.  
  2899. return null;
  2900. }
  2901. /**
  2902. * Determines if an array or string includes a string
  2903. */
  2904.  
  2905. function includes(a, b) {
  2906. return a.indexOf(b) > -1;
  2907. }
  2908. /**
  2909. * Creates an array from string of values separated by whitespace
  2910. */
  2911.  
  2912. function splitBySpaces(value) {
  2913. return value.split(/\s+/).filter(Boolean);
  2914. }
  2915. /**
  2916. * Returns the `nextValue` if `nextValue` is not `undefined`, otherwise returns
  2917. * `currentValue`
  2918. */
  2919.  
  2920. function useIfDefined(nextValue, currentValue) {
  2921. return nextValue !== undefined ? nextValue : currentValue;
  2922. }
  2923. /**
  2924. * Converts a value that's an array or single value to an array
  2925. */
  2926.  
  2927. function normalizeToArray(value) {
  2928. return [].concat(value);
  2929. }
  2930. /**
  2931. * Returns the ownerDocument of the first available element, otherwise global
  2932. * document
  2933. */
  2934.  
  2935. function getOwnerDocument(elementOrElements) {
  2936. var _normalizeToArray = normalizeToArray(elementOrElements),
  2937. element = _normalizeToArray[0];
  2938.  
  2939. return element ? element.ownerDocument || document : document;
  2940. }
  2941. /**
  2942. * Adds item to array if array does not contain it
  2943. */
  2944.  
  2945. function pushIfUnique(arr, value) {
  2946. if (arr.indexOf(value) === -1) {
  2947. arr.push(value);
  2948. }
  2949. }
  2950. /**
  2951. * Adds `px` if value is a number, or returns it directly
  2952. */
  2953.  
  2954. function appendPxIfNumber(value) {
  2955. return typeof value === 'number' ? value + "px" : value;
  2956. }
  2957. /**
  2958. * Filters out duplicate elements in an array
  2959. */
  2960.  
  2961. function unique(arr) {
  2962. return arr.filter(function (item, index) {
  2963. return arr.indexOf(item) === index;
  2964. });
  2965. }
  2966. /**
  2967. * Returns number from number or CSS units string
  2968. */
  2969.  
  2970. function getNumber(value) {
  2971. return typeof value === 'number' ? value : parseFloat(value);
  2972. }
  2973. /**
  2974. * Gets number or CSS string units in pixels (e.g. `1rem` -> 16)
  2975. */
  2976.  
  2977. function getUnitsInPx(doc, value) {
  2978. var isRem = typeof value === 'string' && includes(value, 'rem');
  2979. var html = doc.documentElement;
  2980. var rootFontSize = 16;
  2981.  
  2982. if (html && isRem) {
  2983. return parseFloat(getComputedStyle(html).fontSize || String(rootFontSize)) * getNumber(value);
  2984. }
  2985.  
  2986. return getNumber(value);
  2987. }
  2988. /**
  2989. * Adds the `distancePx` value to the placement of a Popper.Padding object
  2990. */
  2991.  
  2992. function getComputedPadding(basePlacement, padding, distancePx) {
  2993. if (padding === void 0) {
  2994. padding = 5;
  2995. }
  2996.  
  2997. var freshPaddingObject = {
  2998. top: 0,
  2999. right: 0,
  3000. bottom: 0,
  3001. left: 0
  3002. };
  3003. var keys = Object.keys(freshPaddingObject);
  3004. return keys.reduce(function (obj, key) {
  3005. obj[key] = typeof padding === 'number' ? padding : padding[key];
  3006.  
  3007. if (basePlacement === key) {
  3008. obj[key] = typeof padding === 'number' ? padding + distancePx : padding[basePlacement] + distancePx;
  3009. }
  3010.  
  3011. return obj;
  3012. }, freshPaddingObject);
  3013. }
  3014.  
  3015. var currentInput = {
  3016. isTouch: false
  3017. };
  3018. var lastMouseMoveTime = 0;
  3019. /**
  3020. * When a `touchstart` event is fired, it's assumed the user is using touch
  3021. * input. We'll bind a `mousemove` event listener to listen for mouse input in
  3022. * the future. This way, the `isTouch` property is fully dynamic and will handle
  3023. * hybrid devices that use a mix of touch + mouse input.
  3024. */
  3025.  
  3026. function onDocumentTouchStart() {
  3027. if (currentInput.isTouch) {
  3028. return;
  3029. }
  3030.  
  3031. currentInput.isTouch = true;
  3032.  
  3033. if (window.performance) {
  3034. document.addEventListener('mousemove', onDocumentMouseMove);
  3035. }
  3036. }
  3037. /**
  3038. * When two `mousemove` event are fired consecutively within 20ms, it's assumed
  3039. * the user is using mouse input again. `mousemove` can fire on touch devices as
  3040. * well, but very rarely that quickly.
  3041. */
  3042.  
  3043. function onDocumentMouseMove() {
  3044. var now = performance.now();
  3045.  
  3046. if (now - lastMouseMoveTime < 20) {
  3047. currentInput.isTouch = false;
  3048. document.removeEventListener('mousemove', onDocumentMouseMove);
  3049. }
  3050.  
  3051. lastMouseMoveTime = now;
  3052. }
  3053. /**
  3054. * When an element is in focus and has a tippy, leaving the tab/window and
  3055. * returning causes it to show again. For mouse users this is unexpected, but
  3056. * for keyboard use it makes sense.
  3057. * TODO: find a better technique to solve this problem
  3058. */
  3059.  
  3060. function onWindowBlur() {
  3061. var activeElement = document.activeElement;
  3062.  
  3063. if (isReferenceElement(activeElement)) {
  3064. var instance = activeElement._tippy;
  3065.  
  3066. if (activeElement.blur && !instance.state.isVisible) {
  3067. activeElement.blur();
  3068. }
  3069. }
  3070. }
  3071. /**
  3072. * Adds the needed global event listeners
  3073. */
  3074.  
  3075. function bindGlobalEventListeners() {
  3076. document.addEventListener('touchstart', onDocumentTouchStart, _extends({}, PASSIVE, {
  3077. capture: true
  3078. }));
  3079. window.addEventListener('blur', onWindowBlur);
  3080. }
  3081.  
  3082. var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
  3083. var ua = isBrowser ? navigator.userAgent : '';
  3084. var isIE = /MSIE |Trident\//.test(ua);
  3085. var isIOS = isBrowser && /iPhone|iPad|iPod/.test(navigator.platform);
  3086. function updateIOSClass(isAdd) {
  3087. var shouldAdd = isAdd && isIOS && currentInput.isTouch;
  3088. document.body.classList[shouldAdd ? 'add' : 'remove'](IOS_CLASS);
  3089. }
  3090.  
  3091. var version = "5.2.1";
  3092.  
  3093. function createMemoryLeakWarning(method) {
  3094. var txt = method === 'destroy' ? 'n already-' : ' ';
  3095. return "\n " + method + "() was called on a" + txt + "destroyed instance. This is a no-op but\n indicates a potential memory leak.\n ";
  3096. }
  3097. function clean(value) {
  3098. var spacesAndTabs = /[ \t]{2,}/g;
  3099. var lineStartWithSpaces = /^[ \t]*/gm;
  3100. return value.replace(spacesAndTabs, ' ').replace(lineStartWithSpaces, '').trim();
  3101. }
  3102.  
  3103. function getDevMessage(message) {
  3104. return clean("\n %ctippy.js\n\n %c" + clean(message) + "\n\n %c\uD83D\uDC77\u200D This is a development-only message. It will be removed in production.\n ");
  3105. }
  3106.  
  3107. function getFormattedMessage(message) {
  3108. return [getDevMessage(message), // title
  3109. 'color: #00C584; font-size: 1.3em; font-weight: bold;', // message
  3110. 'line-height: 1.5', // footer
  3111. 'color: #a6a095;'];
  3112. }
  3113. /**
  3114. * Helpful wrapper around `console.warn()`.
  3115. * TODO: Should we use a cache so it only warns a single time and not spam the
  3116. * console? (Need to consider hot reloading and invalidation though). Chrome
  3117. * already batches warnings as well.
  3118. */
  3119.  
  3120. function warnWhen(condition, message) {
  3121. if (condition) {
  3122. var _console;
  3123.  
  3124. (_console = console).warn.apply(_console, getFormattedMessage(message));
  3125. }
  3126. }
  3127. /**
  3128. * Helpful wrapper around `console.error()`
  3129. */
  3130.  
  3131. function errorWhen(condition, message) {
  3132. if (condition) {
  3133. var _console2;
  3134.  
  3135. (_console2 = console).error.apply(_console2, getFormattedMessage(message));
  3136. }
  3137. }
  3138. /**
  3139. * Validates the `targets` value passed to `tippy()`
  3140. */
  3141.  
  3142. function validateTargets(targets) {
  3143. var didPassFalsyValue = !targets;
  3144. var didPassPlainObject = Object.prototype.toString.call(targets) === '[object Object]' && !targets.addEventListener;
  3145. errorWhen(didPassFalsyValue, ['tippy() was passed', '`' + String(targets) + '`', 'as its targets (first) argument. Valid types are: String, Element, Element[],', 'or NodeList.'].join(' '));
  3146. errorWhen(didPassPlainObject, ['tippy() was passed a plain object which is no longer supported as an argument.', 'See: https://atomiks.github.io/tippyjs/misc/#custom-position'].join(' '));
  3147. }
  3148.  
  3149. var pluginProps = {
  3150. animateFill: false,
  3151. followCursor: false,
  3152. inlinePositioning: false,
  3153. sticky: false
  3154. };
  3155. var defaultProps = _extends({
  3156. allowHTML: true,
  3157. animation: 'fade',
  3158. appendTo: function appendTo() {
  3159. return document.body;
  3160. },
  3161. aria: 'describedby',
  3162. arrow: true,
  3163. boundary: 'scrollParent',
  3164. content: '',
  3165. delay: 0,
  3166. distance: 10,
  3167. duration: [300, 250],
  3168. flip: true,
  3169. flipBehavior: 'flip',
  3170. flipOnUpdate: false,
  3171. hideOnClick: true,
  3172. ignoreAttributes: false,
  3173. inertia: false,
  3174. interactive: false,
  3175. interactiveBorder: 2,
  3176. interactiveDebounce: 0,
  3177. lazy: true,
  3178. maxWidth: 350,
  3179. multiple: false,
  3180. offset: 0,
  3181. onAfterUpdate: function onAfterUpdate() {},
  3182. onBeforeUpdate: function onBeforeUpdate() {},
  3183. onCreate: function onCreate() {},
  3184. onDestroy: function onDestroy() {},
  3185. onHidden: function onHidden() {},
  3186. onHide: function onHide() {},
  3187. onMount: function onMount() {},
  3188. onShow: function onShow() {},
  3189. onShown: function onShown() {},
  3190. onTrigger: function onTrigger() {},
  3191. onUntrigger: function onUntrigger() {},
  3192. placement: 'top',
  3193. plugins: [],
  3194. popperOptions: {},
  3195. role: 'tooltip',
  3196. showOnCreate: false,
  3197. theme: '',
  3198. touch: true,
  3199. trigger: 'mouseenter focus',
  3200. triggerTarget: null,
  3201. updateDuration: 0,
  3202. zIndex: 9999
  3203. }, pluginProps);
  3204. var defaultKeys = Object.keys(defaultProps);
  3205. /**
  3206. * If the setProps() method encounters one of these, the popperInstance must be
  3207. * recreated
  3208. */
  3209.  
  3210. var POPPER_INSTANCE_DEPENDENCIES = ['arrow', 'boundary', 'distance', 'flip', 'flipBehavior', 'flipOnUpdate', 'offset', 'placement', 'popperOptions'];
  3211. /**
  3212. * Mutates the defaultProps object by setting the props specified
  3213. */
  3214.  
  3215. var setDefaultProps = function setDefaultProps(partialProps) {
  3216. {
  3217. validateProps(partialProps, []);
  3218. }
  3219.  
  3220. var keys = Object.keys(partialProps);
  3221. keys.forEach(function (key) {
  3222. defaultProps[key] = partialProps[key];
  3223. });
  3224. };
  3225. /**
  3226. * Returns an extended props object including plugin props
  3227. */
  3228.  
  3229. function getExtendedPassedProps(passedProps) {
  3230. var plugins = passedProps.plugins || [];
  3231. var pluginProps = plugins.reduce(function (acc, plugin) {
  3232. var name = plugin.name,
  3233. defaultValue = plugin.defaultValue;
  3234.  
  3235. if (name) {
  3236. acc[name] = passedProps[name] !== undefined ? passedProps[name] : defaultValue;
  3237. }
  3238.  
  3239. return acc;
  3240. }, {});
  3241. return _extends({}, passedProps, {}, pluginProps);
  3242. }
  3243. /**
  3244. * Returns an object of optional props from data-tippy-* attributes
  3245. */
  3246.  
  3247. function getDataAttributeProps(reference, plugins) {
  3248. var propKeys = plugins ? Object.keys(getExtendedPassedProps(_extends({}, defaultProps, {
  3249. plugins: plugins
  3250. }))) : defaultKeys;
  3251. var props = propKeys.reduce(function (acc, key) {
  3252. var valueAsString = (reference.getAttribute("data-tippy-" + key) || '').trim();
  3253.  
  3254. if (!valueAsString) {
  3255. return acc;
  3256. }
  3257.  
  3258. if (key === 'content') {
  3259. acc[key] = valueAsString;
  3260. } else {
  3261. try {
  3262. acc[key] = JSON.parse(valueAsString);
  3263. } catch (e) {
  3264. acc[key] = valueAsString;
  3265. }
  3266. }
  3267.  
  3268. return acc;
  3269. }, {});
  3270. return props;
  3271. }
  3272. /**
  3273. * Evaluates the props object by merging data attributes and disabling
  3274. * conflicting props where necessary
  3275. */
  3276.  
  3277. function evaluateProps(reference, props) {
  3278. var out = _extends({}, props, {
  3279. content: invokeWithArgsOrReturn(props.content, [reference])
  3280. }, props.ignoreAttributes ? {} : getDataAttributeProps(reference, props.plugins));
  3281.  
  3282. if (out.interactive) {
  3283. out.aria = null;
  3284. }
  3285.  
  3286. return out;
  3287. }
  3288. /**
  3289. * Validates props with the valid `defaultProps` object
  3290. */
  3291.  
  3292. function validateProps(partialProps, plugins) {
  3293. if (partialProps === void 0) {
  3294. partialProps = {};
  3295. }
  3296.  
  3297. if (plugins === void 0) {
  3298. plugins = [];
  3299. }
  3300.  
  3301. var keys = Object.keys(partialProps);
  3302. keys.forEach(function (prop) {
  3303. var value = partialProps[prop];
  3304. var didSpecifyPlacementInPopperOptions = prop === 'popperOptions' && value !== null && typeof value === 'object' && hasOwnProperty(value, 'placement');
  3305. var nonPluginProps = removeProperties(defaultProps, ['animateFill', 'followCursor', 'inlinePositioning', 'sticky']); // These props have custom warnings
  3306.  
  3307. var customWarningProps = ['a11y', 'arrowType', 'showOnInit', 'size', 'target', 'touchHold'];
  3308. var didPassUnknownProp = !hasOwnProperty(nonPluginProps, prop) && !includes(customWarningProps, prop); // Check if the prop exists in `plugins`
  3309.  
  3310. if (didPassUnknownProp) {
  3311. didPassUnknownProp = plugins.filter(function (plugin) {
  3312. return plugin.name === prop;
  3313. }).length === 0;
  3314. }
  3315.  
  3316. warnWhen(prop === 'target', ['The `target` prop was removed in v5 and replaced with the delegate() addon', 'in order to conserve bundle size.', 'See: https://atomiks.github.io/tippyjs/addons/#event-delegation'].join(' '));
  3317. warnWhen(prop === 'a11y', ['The `a11y` prop was removed in v5. Make sure the element you are giving a', 'tippy to is natively focusable, such as <button> or <input>, not <div>', 'or <span>.'].join(' '));
  3318. warnWhen(prop === 'showOnInit', 'The `showOnInit` prop was renamed to `showOnCreate` in v5.');
  3319. warnWhen(prop === 'arrowType', ['The `arrowType` prop was removed in v5 in favor of overloading the `arrow`', 'prop.', '\n\n', '"round" string was replaced with importing the string from the package.', '\n\n', "* import {roundArrow} from 'tippy.js'; (ESM version)\n", '* const {roundArrow} = tippy; (IIFE CDN version)', '\n\n', 'Before: {arrow: true, arrowType: "round"}\n', 'After: {arrow: roundArrow}`'].join(' '));
  3320. warnWhen(prop === 'touchHold', ['The `touchHold` prop was removed in v5 in favor of overloading the `touch`', 'prop.', '\n\n', 'Before: {touchHold: true}\n', 'After: {touch: "hold"}'].join(' '));
  3321. warnWhen(prop === 'size', ['The `size` prop was removed in v5. Instead, use a theme that specifies', 'CSS padding and font-size properties.'].join(' '));
  3322. warnWhen(prop === 'theme' && value === 'google', 'The included theme "google" was renamed to "material" in v5.');
  3323. warnWhen(didSpecifyPlacementInPopperOptions, ['Specifying placement in `popperOptions` is not supported. Use the base-level', '`placement` prop instead.', '\n\n', 'Before: {popperOptions: {placement: "bottom"}}\n', 'After: {placement: "bottom"}'].join(' '));
  3324. warnWhen(didPassUnknownProp, ["`" + prop + "`", "is not a valid prop. You may have spelled it incorrectly, or if it's a", 'plugin, forgot to pass it in an array as props.plugins.', '\n\n', 'In v5, the following props were turned into plugins:', '\n\n', '* animateFill\n', '* followCursor\n', '* sticky', '\n\n', 'All props: https://atomiks.github.io/tippyjs/all-props/\n', 'Plugins: https://atomiks.github.io/tippyjs/plugins/'].join(' '));
  3325. });
  3326. }
  3327.  
  3328. /**
  3329. * Returns the popper's placement, ignoring shifting (top-start, etc)
  3330. */
  3331.  
  3332. function getBasePlacement(placement) {
  3333. return placement.split('-')[0];
  3334. }
  3335. /**
  3336. * Adds `data-inertia` attribute
  3337. */
  3338.  
  3339. function addInertia(tooltip) {
  3340. tooltip.setAttribute('data-inertia', '');
  3341. }
  3342. /**
  3343. * Removes `data-inertia` attribute
  3344. */
  3345.  
  3346. function removeInertia(tooltip) {
  3347. tooltip.removeAttribute('data-inertia');
  3348. }
  3349. /**
  3350. * Adds interactive-related attributes
  3351. */
  3352.  
  3353. function addInteractive(tooltip) {
  3354. tooltip.setAttribute('data-interactive', '');
  3355. }
  3356. /**
  3357. * Removes interactive-related attributes
  3358. */
  3359.  
  3360. function removeInteractive(tooltip) {
  3361. tooltip.removeAttribute('data-interactive');
  3362. }
  3363. /**
  3364. * Sets the content of a tooltip
  3365. */
  3366.  
  3367. function setContent(contentEl, props) {
  3368. if (isElement(props.content)) {
  3369. setInnerHTML(contentEl, '');
  3370. contentEl.appendChild(props.content);
  3371. } else if (typeof props.content !== 'function') {
  3372. var key = props.allowHTML ? 'innerHTML' : 'textContent';
  3373. contentEl[key] = props.content;
  3374. }
  3375. }
  3376. /**
  3377. * Returns the child elements of a popper element
  3378. */
  3379.  
  3380. function getChildren(popper) {
  3381. return {
  3382. tooltip: popper.querySelector(TOOLTIP_SELECTOR),
  3383. content: popper.querySelector(CONTENT_SELECTOR),
  3384. arrow: popper.querySelector(ARROW_SELECTOR) || popper.querySelector(SVG_ARROW_SELECTOR)
  3385. };
  3386. }
  3387. /**
  3388. * Creates an arrow element and returns it
  3389. */
  3390.  
  3391. function createArrowElement(arrow) {
  3392. var arrowElement = div();
  3393.  
  3394. if (arrow === true) {
  3395. arrowElement.className = ARROW_CLASS;
  3396. } else {
  3397. arrowElement.className = SVG_ARROW_CLASS;
  3398.  
  3399. if (isElement(arrow)) {
  3400. arrowElement.appendChild(arrow);
  3401. } else {
  3402. setInnerHTML(arrowElement, arrow);
  3403. }
  3404. }
  3405.  
  3406. return arrowElement;
  3407. }
  3408. /**
  3409. * Constructs the popper element and returns it
  3410. */
  3411.  
  3412. function createPopperElement(id, props) {
  3413. var popper = div();
  3414. popper.className = POPPER_CLASS;
  3415. popper.style.position = 'absolute';
  3416. popper.style.top = '0';
  3417. popper.style.left = '0';
  3418. var tooltip = div();
  3419. tooltip.className = TOOLTIP_CLASS;
  3420. tooltip.id = "tippy-" + id;
  3421. tooltip.setAttribute('data-state', 'hidden');
  3422. tooltip.setAttribute('tabindex', '-1');
  3423. updateTheme(tooltip, 'add', props.theme);
  3424. var content = div();
  3425. content.className = CONTENT_CLASS;
  3426. content.setAttribute('data-state', 'hidden');
  3427.  
  3428. if (props.interactive) {
  3429. addInteractive(tooltip);
  3430. }
  3431.  
  3432. if (props.arrow) {
  3433. tooltip.setAttribute('data-arrow', '');
  3434. tooltip.appendChild(createArrowElement(props.arrow));
  3435. }
  3436.  
  3437. if (props.inertia) {
  3438. addInertia(tooltip);
  3439. }
  3440.  
  3441. setContent(content, props);
  3442. tooltip.appendChild(content);
  3443. popper.appendChild(tooltip);
  3444. updatePopperElement(popper, props, props);
  3445. return popper;
  3446. }
  3447. /**
  3448. * Updates the popper element based on the new props
  3449. */
  3450.  
  3451. function updatePopperElement(popper, prevProps, nextProps) {
  3452. var _getChildren = getChildren(popper),
  3453. tooltip = _getChildren.tooltip,
  3454. content = _getChildren.content,
  3455. arrow = _getChildren.arrow;
  3456.  
  3457. popper.style.zIndex = '' + nextProps.zIndex;
  3458. tooltip.setAttribute('data-animation', nextProps.animation);
  3459. tooltip.style.maxWidth = appendPxIfNumber(nextProps.maxWidth);
  3460.  
  3461. if (nextProps.role) {
  3462. tooltip.setAttribute('role', nextProps.role);
  3463. } else {
  3464. tooltip.removeAttribute('role');
  3465. }
  3466.  
  3467. if (prevProps.content !== nextProps.content) {
  3468. setContent(content, nextProps);
  3469. } // arrow
  3470.  
  3471.  
  3472. if (!prevProps.arrow && nextProps.arrow) {
  3473. // false to true
  3474. tooltip.appendChild(createArrowElement(nextProps.arrow));
  3475. tooltip.setAttribute('data-arrow', '');
  3476. } else if (prevProps.arrow && !nextProps.arrow) {
  3477. // true to false
  3478. tooltip.removeChild(arrow);
  3479. tooltip.removeAttribute('data-arrow');
  3480. } else if (prevProps.arrow !== nextProps.arrow) {
  3481. // true to 'round' or vice-versa
  3482. tooltip.removeChild(arrow);
  3483. tooltip.appendChild(createArrowElement(nextProps.arrow));
  3484. } // interactive
  3485.  
  3486.  
  3487. if (!prevProps.interactive && nextProps.interactive) {
  3488. addInteractive(tooltip);
  3489. } else if (prevProps.interactive && !nextProps.interactive) {
  3490. removeInteractive(tooltip);
  3491. } // inertia
  3492.  
  3493.  
  3494. if (!prevProps.inertia && nextProps.inertia) {
  3495. addInertia(tooltip);
  3496. } else if (prevProps.inertia && !nextProps.inertia) {
  3497. removeInertia(tooltip);
  3498. } // theme
  3499.  
  3500.  
  3501. if (prevProps.theme !== nextProps.theme) {
  3502. updateTheme(tooltip, 'remove', prevProps.theme);
  3503. updateTheme(tooltip, 'add', nextProps.theme);
  3504. }
  3505. }
  3506. /**
  3507. * Add/remove transitionend listener from tooltip
  3508. */
  3509.  
  3510. function updateTransitionEndListener(tooltip, action, listener) {
  3511. ['transitionend', 'webkitTransitionEnd'].forEach(function (event) {
  3512. tooltip[action + 'EventListener'](event, listener);
  3513. });
  3514. }
  3515. /**
  3516. * Adds/removes theme from tooltip's classList
  3517. */
  3518.  
  3519. function updateTheme(tooltip, action, theme) {
  3520. splitBySpaces(theme).forEach(function (name) {
  3521. tooltip.classList[action](name + "-theme");
  3522. });
  3523. }
  3524. /**
  3525. * Determines if the mouse cursor is outside of the popper's interactive border
  3526. * region
  3527. */
  3528.  
  3529. function isCursorOutsideInteractiveBorder(popperTreeData, event) {
  3530. var clientX = event.clientX,
  3531. clientY = event.clientY;
  3532. return popperTreeData.every(function (_ref) {
  3533. var popperRect = _ref.popperRect,
  3534. tooltipRect = _ref.tooltipRect,
  3535. interactiveBorder = _ref.interactiveBorder;
  3536. // Get min/max bounds of both the popper and tooltip rects due to
  3537. // `distance` offset
  3538. var mergedRect = {
  3539. top: Math.min(popperRect.top, tooltipRect.top),
  3540. right: Math.max(popperRect.right, tooltipRect.right),
  3541. bottom: Math.max(popperRect.bottom, tooltipRect.bottom),
  3542. left: Math.min(popperRect.left, tooltipRect.left)
  3543. };
  3544. var exceedsTop = mergedRect.top - clientY > interactiveBorder;
  3545. var exceedsBottom = clientY - mergedRect.bottom > interactiveBorder;
  3546. var exceedsLeft = mergedRect.left - clientX > interactiveBorder;
  3547. var exceedsRight = clientX - mergedRect.right > interactiveBorder;
  3548. return exceedsTop || exceedsBottom || exceedsLeft || exceedsRight;
  3549. });
  3550. }
  3551.  
  3552. var idCounter = 1;
  3553. var mouseMoveListeners = [];
  3554. /**
  3555. * Used by `hideAll()`
  3556. */
  3557.  
  3558. var mountedInstances = [];
  3559. /**
  3560. * Creates and returns a Tippy object. We're using a closure pattern instead of
  3561. * a class so that the exposed object API is clean without private members
  3562. * prefixed with `_`.
  3563. */
  3564.  
  3565. function createTippy(reference, passedProps) {
  3566. var props = evaluateProps(reference, _extends({}, defaultProps, {}, getExtendedPassedProps(passedProps))); // If the reference shouldn't have multiple tippys, return null early
  3567.  
  3568. if (!props.multiple && reference._tippy) {
  3569. return null;
  3570. }
  3571. /* ======================= 🔒 Private members 🔒 ======================= */
  3572.  
  3573.  
  3574. var showTimeout;
  3575. var hideTimeout;
  3576. var scheduleHideAnimationFrame;
  3577. var isBeingDestroyed = false;
  3578. var isVisibleFromClick = false;
  3579. var didHideDueToDocumentMouseDown = false;
  3580. var popperUpdates = 0;
  3581. var lastTriggerEvent;
  3582. var currentMountCallback;
  3583. var currentTransitionEndListener;
  3584. var listeners = [];
  3585. var debouncedOnMouseMove = debounce(onMouseMove, props.interactiveDebounce);
  3586. var currentTarget; // Support iframe contexts
  3587. // Static check that assumes any of the `triggerTarget` or `reference`
  3588. // nodes will never change documents, even when they are updated
  3589.  
  3590. var doc = getOwnerDocument(props.triggerTarget || reference);
  3591. /* ======================= 🔑 Public members 🔑 ======================= */
  3592.  
  3593. var id = idCounter++;
  3594. var popper = createPopperElement(id, props);
  3595. var popperChildren = getChildren(popper);
  3596. var popperInstance = null;
  3597. var plugins = unique(props.plugins); // These two elements are static
  3598.  
  3599. var tooltip = popperChildren.tooltip,
  3600. content = popperChildren.content;
  3601. var transitionableElements = [tooltip, content];
  3602. var state = {
  3603. // The current real placement (`data-placement` attribute)
  3604. currentPlacement: null,
  3605. // Is the instance currently enabled?
  3606. isEnabled: true,
  3607. // Is the tippy currently showing and not transitioning out?
  3608. isVisible: false,
  3609. // Has the instance been destroyed?
  3610. isDestroyed: false,
  3611. // Is the tippy currently mounted to the DOM?
  3612. isMounted: false,
  3613. // Has the tippy finished transitioning in?
  3614. isShown: false
  3615. };
  3616. var instance = {
  3617. // properties
  3618. id: id,
  3619. reference: reference,
  3620. popper: popper,
  3621. popperChildren: popperChildren,
  3622. popperInstance: popperInstance,
  3623. props: props,
  3624. state: state,
  3625. plugins: plugins,
  3626. // methods
  3627. clearDelayTimeouts: clearDelayTimeouts,
  3628. setProps: setProps,
  3629. setContent: setContent,
  3630. show: show,
  3631. hide: hide,
  3632. enable: enable,
  3633. disable: disable,
  3634. destroy: destroy
  3635. };
  3636. /* ==================== Initial instance mutations =================== */
  3637.  
  3638. reference._tippy = instance;
  3639. popper._tippy = instance;
  3640. var pluginsHooks = plugins.map(function (plugin) {
  3641. return plugin.fn(instance);
  3642. });
  3643. var hadAriaExpandedAttributeOnCreate = reference.hasAttribute('aria-expanded');
  3644. addListenersToTriggerTarget();
  3645. handleAriaExpandedAttribute();
  3646.  
  3647. if (!props.lazy) {
  3648. createPopperInstance();
  3649. }
  3650.  
  3651. invokeHook('onCreate', [instance]);
  3652.  
  3653. if (props.showOnCreate) {
  3654. scheduleShow();
  3655. } // Prevent a tippy with a delay from hiding if the cursor left then returned
  3656. // before it started hiding
  3657.  
  3658.  
  3659. popper.addEventListener('mouseenter', function () {
  3660. if (instance.props.interactive && instance.state.isVisible) {
  3661. instance.clearDelayTimeouts();
  3662. }
  3663. });
  3664. popper.addEventListener('mouseleave', function (event) {
  3665. if (instance.props.interactive && includes(instance.props.trigger, 'mouseenter')) {
  3666. debouncedOnMouseMove(event);
  3667. doc.addEventListener('mousemove', debouncedOnMouseMove);
  3668. }
  3669. });
  3670. return instance;
  3671. /* ======================= 🔒 Private methods 🔒 ======================= */
  3672.  
  3673. function getNormalizedTouchSettings() {
  3674. var touch = instance.props.touch;
  3675. return Array.isArray(touch) ? touch : [touch, 0];
  3676. }
  3677.  
  3678. function getIsCustomTouchBehavior() {
  3679. return getNormalizedTouchSettings()[0] === 'hold';
  3680. }
  3681.  
  3682. function getCurrentTarget() {
  3683. return currentTarget || reference;
  3684. }
  3685.  
  3686. function getDelay(isShow) {
  3687. // For touch or keyboard input, force `0` delay for UX reasons
  3688. // Also if the instance is mounted but not visible (transitioning out),
  3689. // ignore delay
  3690. if (instance.state.isMounted && !instance.state.isVisible || currentInput.isTouch || lastTriggerEvent && lastTriggerEvent.type === 'focus') {
  3691. return 0;
  3692. }
  3693.  
  3694. return getValueAtIndexOrReturn(instance.props.delay, isShow ? 0 : 1, defaultProps.delay);
  3695. }
  3696.  
  3697. function invokeHook(hook, args, shouldInvokePropsHook) {
  3698. if (shouldInvokePropsHook === void 0) {
  3699. shouldInvokePropsHook = true;
  3700. }
  3701.  
  3702. pluginsHooks.forEach(function (pluginHooks) {
  3703. if (hasOwnProperty(pluginHooks, hook)) {
  3704. // @ts-ignore
  3705. pluginHooks[hook].apply(pluginHooks, args);
  3706. }
  3707. });
  3708.  
  3709. if (shouldInvokePropsHook) {
  3710. var _instance$props;
  3711.  
  3712. // @ts-ignore
  3713. (_instance$props = instance.props)[hook].apply(_instance$props, args);
  3714. }
  3715. }
  3716.  
  3717. function handleAriaDescribedByAttribute() {
  3718. var aria = instance.props.aria;
  3719.  
  3720. if (!aria) {
  3721. return;
  3722. }
  3723.  
  3724. var attr = "aria-" + aria;
  3725. var id = tooltip.id;
  3726. var nodes = normalizeToArray(instance.props.triggerTarget || reference);
  3727. nodes.forEach(function (node) {
  3728. var currentValue = node.getAttribute(attr);
  3729.  
  3730. if (instance.state.isVisible) {
  3731. node.setAttribute(attr, currentValue ? currentValue + " " + id : id);
  3732. } else {
  3733. var nextValue = currentValue && currentValue.replace(id, '').trim();
  3734.  
  3735. if (nextValue) {
  3736. node.setAttribute(attr, nextValue);
  3737. } else {
  3738. node.removeAttribute(attr);
  3739. }
  3740. }
  3741. });
  3742. }
  3743.  
  3744. function handleAriaExpandedAttribute() {
  3745. // If the user has specified `aria-expanded` on their reference when the
  3746. // instance was created, we have to assume they're controlling it externally
  3747. // themselves
  3748. if (hadAriaExpandedAttributeOnCreate) {
  3749. return;
  3750. }
  3751.  
  3752. var nodes = normalizeToArray(instance.props.triggerTarget || reference);
  3753. nodes.forEach(function (node) {
  3754. if (instance.props.interactive) {
  3755. node.setAttribute('aria-expanded', instance.state.isVisible && node === getCurrentTarget() ? 'true' : 'false');
  3756. } else {
  3757. node.removeAttribute('aria-expanded');
  3758. }
  3759. });
  3760. }
  3761.  
  3762. function cleanupInteractiveMouseListeners() {
  3763. doc.body.removeEventListener('mouseleave', scheduleHide);
  3764. doc.removeEventListener('mousemove', debouncedOnMouseMove);
  3765. mouseMoveListeners = mouseMoveListeners.filter(function (listener) {
  3766. return listener !== debouncedOnMouseMove;
  3767. });
  3768. }
  3769.  
  3770. function onDocumentMouseDown(event) {
  3771. // Clicked on interactive popper
  3772. if (instance.props.interactive && popper.contains(event.target)) {
  3773. return;
  3774. } // Clicked on the event listeners target
  3775.  
  3776.  
  3777. if (getCurrentTarget().contains(event.target)) {
  3778. if (currentInput.isTouch) {
  3779. return;
  3780. }
  3781.  
  3782. if (instance.state.isVisible && includes(instance.props.trigger, 'click')) {
  3783. return;
  3784. }
  3785. }
  3786.  
  3787. if (instance.props.hideOnClick === true) {
  3788. isVisibleFromClick = false;
  3789. instance.clearDelayTimeouts();
  3790. instance.hide(); // `mousedown` event is fired right before `focus` if pressing the
  3791. // currentTarget. This lets a tippy with `focus` trigger know that it
  3792. // should not show
  3793.  
  3794. didHideDueToDocumentMouseDown = true;
  3795. setTimeout(function () {
  3796. didHideDueToDocumentMouseDown = false;
  3797. }); // The listener gets added in `scheduleShow()`, but this may be hiding it
  3798. // before it shows, and hide()'s early bail-out behavior can prevent it
  3799. // from being cleaned up
  3800.  
  3801. if (!instance.state.isMounted) {
  3802. removeDocumentMouseDownListener();
  3803. }
  3804. }
  3805. }
  3806.  
  3807. function addDocumentMouseDownListener() {
  3808. doc.addEventListener('mousedown', onDocumentMouseDown, true);
  3809. }
  3810.  
  3811. function removeDocumentMouseDownListener() {
  3812. doc.removeEventListener('mousedown', onDocumentMouseDown, true);
  3813. }
  3814.  
  3815. function onTransitionedOut(duration, callback) {
  3816. onTransitionEnd(duration, function () {
  3817. if (!instance.state.isVisible && popper.parentNode && popper.parentNode.contains(popper)) {
  3818. callback();
  3819. }
  3820. });
  3821. }
  3822.  
  3823. function onTransitionedIn(duration, callback) {
  3824. onTransitionEnd(duration, callback);
  3825. }
  3826.  
  3827. function onTransitionEnd(duration, callback) {
  3828. function listener(event) {
  3829. if (event.target === tooltip) {
  3830. updateTransitionEndListener(tooltip, 'remove', listener);
  3831. callback();
  3832. }
  3833. } // Make callback synchronous if duration is 0
  3834. // `transitionend` won't fire otherwise
  3835.  
  3836.  
  3837. if (duration === 0) {
  3838. return callback();
  3839. }
  3840.  
  3841. updateTransitionEndListener(tooltip, 'remove', currentTransitionEndListener);
  3842. updateTransitionEndListener(tooltip, 'add', listener);
  3843. currentTransitionEndListener = listener;
  3844. }
  3845.  
  3846. function on(eventType, handler, options) {
  3847. if (options === void 0) {
  3848. options = false;
  3849. }
  3850.  
  3851. var nodes = normalizeToArray(instance.props.triggerTarget || reference);
  3852. nodes.forEach(function (node) {
  3853. node.addEventListener(eventType, handler, options);
  3854. listeners.push({
  3855. node: node,
  3856. eventType: eventType,
  3857. handler: handler,
  3858. options: options
  3859. });
  3860. });
  3861. }
  3862.  
  3863. function addListenersToTriggerTarget() {
  3864. if (getIsCustomTouchBehavior()) {
  3865. on('touchstart', onTrigger, PASSIVE);
  3866. on('touchend', onMouseLeave, PASSIVE);
  3867. }
  3868.  
  3869. splitBySpaces(instance.props.trigger).forEach(function (eventType) {
  3870. if (eventType === 'manual') {
  3871. return;
  3872. }
  3873.  
  3874. on(eventType, onTrigger);
  3875.  
  3876. switch (eventType) {
  3877. case 'mouseenter':
  3878. on('mouseleave', onMouseLeave);
  3879. break;
  3880.  
  3881. case 'focus':
  3882. on(isIE ? 'focusout' : 'blur', onBlurOrFocusOut);
  3883. break;
  3884.  
  3885. case 'focusin':
  3886. on('focusout', onBlurOrFocusOut);
  3887. break;
  3888. }
  3889. });
  3890. }
  3891.  
  3892. function removeListenersFromTriggerTarget() {
  3893. listeners.forEach(function (_ref) {
  3894. var node = _ref.node,
  3895. eventType = _ref.eventType,
  3896. handler = _ref.handler,
  3897. options = _ref.options;
  3898. node.removeEventListener(eventType, handler, options);
  3899. });
  3900. listeners = [];
  3901. }
  3902.  
  3903. function onTrigger(event) {
  3904. var shouldScheduleClickHide = false;
  3905.  
  3906. if (!instance.state.isEnabled || isEventListenerStopped(event) || didHideDueToDocumentMouseDown) {
  3907. return;
  3908. }
  3909.  
  3910. lastTriggerEvent = event;
  3911. currentTarget = event.currentTarget;
  3912. handleAriaExpandedAttribute();
  3913.  
  3914. if (!instance.state.isVisible && isMouseEvent(event)) {
  3915. // If scrolling, `mouseenter` events can be fired if the cursor lands
  3916. // over a new target, but `mousemove` events don't get fired. This
  3917. // causes interactive tooltips to get stuck open until the cursor is
  3918. // moved
  3919. mouseMoveListeners.forEach(function (listener) {
  3920. return listener(event);
  3921. });
  3922. } // Toggle show/hide when clicking click-triggered tooltips
  3923.  
  3924.  
  3925. if (event.type === 'click' && (!includes(instance.props.trigger, 'mouseenter') || isVisibleFromClick) && instance.props.hideOnClick !== false && instance.state.isVisible) {
  3926. shouldScheduleClickHide = true;
  3927. } else {
  3928. var _getNormalizedTouchSe = getNormalizedTouchSettings(),
  3929. value = _getNormalizedTouchSe[0],
  3930. duration = _getNormalizedTouchSe[1];
  3931.  
  3932. if (currentInput.isTouch && value === 'hold' && duration) {
  3933. // We can hijack the show timeout here, it will be cleared by
  3934. // `scheduleHide()` when necessary
  3935. showTimeout = setTimeout(function () {
  3936. scheduleShow(event);
  3937. }, duration);
  3938. } else {
  3939. scheduleShow(event);
  3940. }
  3941. }
  3942.  
  3943. if (event.type === 'click') {
  3944. isVisibleFromClick = !shouldScheduleClickHide;
  3945. }
  3946.  
  3947. if (shouldScheduleClickHide) {
  3948. scheduleHide(event);
  3949. }
  3950. }
  3951.  
  3952. function onMouseMove(event) {
  3953. var isCursorOverReferenceOrPopper = closestCallback(event.target, function (el) {
  3954. return el === reference || el === popper;
  3955. });
  3956.  
  3957. if (event.type === 'mousemove' && isCursorOverReferenceOrPopper) {
  3958. return;
  3959. }
  3960.  
  3961. var popperTreeData = arrayFrom(popper.querySelectorAll(POPPER_SELECTOR)).concat(popper).map(function (popper) {
  3962. var instance = popper._tippy;
  3963. var tooltip = instance.popperChildren.tooltip;
  3964. var interactiveBorder = instance.props.interactiveBorder;
  3965. return {
  3966. popperRect: popper.getBoundingClientRect(),
  3967. tooltipRect: tooltip.getBoundingClientRect(),
  3968. interactiveBorder: interactiveBorder
  3969. };
  3970. });
  3971.  
  3972. if (isCursorOutsideInteractiveBorder(popperTreeData, event)) {
  3973. cleanupInteractiveMouseListeners();
  3974. scheduleHide(event);
  3975. }
  3976. }
  3977.  
  3978. function onMouseLeave(event) {
  3979. if (isEventListenerStopped(event)) {
  3980. return;
  3981. }
  3982.  
  3983. if (includes(instance.props.trigger, 'click') && isVisibleFromClick) {
  3984. return;
  3985. }
  3986.  
  3987. if (instance.props.interactive) {
  3988. doc.body.addEventListener('mouseleave', scheduleHide);
  3989. doc.addEventListener('mousemove', debouncedOnMouseMove);
  3990. pushIfUnique(mouseMoveListeners, debouncedOnMouseMove);
  3991. debouncedOnMouseMove(event);
  3992. return;
  3993. }
  3994.  
  3995. scheduleHide(event);
  3996. }
  3997.  
  3998. function onBlurOrFocusOut(event) {
  3999. if (!includes(instance.props.trigger, 'focusin') && event.target !== getCurrentTarget()) {
  4000. return;
  4001. } // If focus was moved to within the popper
  4002.  
  4003.  
  4004. if (instance.props.interactive && event.relatedTarget && popper.contains(event.relatedTarget)) {
  4005. return;
  4006. }
  4007.  
  4008. scheduleHide(event);
  4009. }
  4010.  
  4011. function isEventListenerStopped(event) {
  4012. var supportsTouch = 'ontouchstart' in window;
  4013. var isTouchEvent = includes(event.type, 'touch');
  4014. var isCustomTouch = getIsCustomTouchBehavior();
  4015. return supportsTouch && currentInput.isTouch && isCustomTouch && !isTouchEvent || currentInput.isTouch && !isCustomTouch && isTouchEvent;
  4016. }
  4017.  
  4018. function createPopperInstance() {
  4019. var popperOptions = instance.props.popperOptions;
  4020. var arrow = instance.popperChildren.arrow;
  4021. var flipModifier = getModifier(popperOptions, 'flip');
  4022. var preventOverflowModifier = getModifier(popperOptions, 'preventOverflow');
  4023. var distancePx;
  4024.  
  4025. function applyMutations(data) {
  4026. var prevPlacement = instance.state.currentPlacement;
  4027. instance.state.currentPlacement = data.placement;
  4028.  
  4029. if (instance.props.flip && !instance.props.flipOnUpdate) {
  4030. if (data.flipped) {
  4031. instance.popperInstance.options.placement = data.placement;
  4032. }
  4033.  
  4034. setModifierValue(instance.popperInstance.modifiers, 'flip', 'enabled', false);
  4035. }
  4036.  
  4037. tooltip.setAttribute('data-placement', data.placement);
  4038.  
  4039. if (data.attributes['x-out-of-boundaries'] !== false) {
  4040. tooltip.setAttribute('data-out-of-boundaries', '');
  4041. } else {
  4042. tooltip.removeAttribute('data-out-of-boundaries');
  4043. }
  4044.  
  4045. var basePlacement = getBasePlacement(data.placement);
  4046. var isVerticalPlacement = includes(['top', 'bottom'], basePlacement);
  4047. var isSecondaryPlacement = includes(['bottom', 'right'], basePlacement); // Apply `distance` prop
  4048.  
  4049. tooltip.style.top = '0';
  4050. tooltip.style.left = '0';
  4051. tooltip.style[isVerticalPlacement ? 'top' : 'left'] = (isSecondaryPlacement ? 1 : -1) * distancePx + 'px'; // Careful not to cause an infinite loop here
  4052. // Fixes https://github.com/FezVrasta/popper.js/issues/784
  4053.  
  4054. if (prevPlacement && prevPlacement !== data.placement) {
  4055. instance.popperInstance.update();
  4056. }
  4057. }
  4058.  
  4059. var config = _extends({
  4060. eventsEnabled: false,
  4061. placement: instance.props.placement
  4062. }, popperOptions, {
  4063. modifiers: _extends({}, popperOptions && popperOptions.modifiers, {
  4064. // We can't use `padding` on the popper el because of these bugs when
  4065. // flipping from a vertical to horizontal placement or vice-versa,
  4066. // there is severe flickering.
  4067. // https://github.com/FezVrasta/popper.js/issues/720
  4068. // This workaround increases bundle size by 250B minzip unfortunately,
  4069. // due to need to custom compute the distance (since Popper rect does
  4070. // not get affected by the inner tooltip's distance offset)
  4071. tippyDistance: {
  4072. enabled: true,
  4073. order: 0,
  4074. fn: function fn(data) {
  4075. // `html` fontSize may change while `popperInstance` is alive
  4076. // e.g. on resize in media queries
  4077. distancePx = getUnitsInPx(doc, instance.props.distance);
  4078. var basePlacement = getBasePlacement(data.placement);
  4079. var computedPreventOverflowPadding = getComputedPadding(basePlacement, preventOverflowModifier && preventOverflowModifier.padding, distancePx);
  4080. var computedFlipPadding = getComputedPadding(basePlacement, flipModifier && flipModifier.padding, distancePx);
  4081. var instanceModifiers = instance.popperInstance.modifiers;
  4082. setModifierValue(instanceModifiers, 'preventOverflow', 'padding', computedPreventOverflowPadding);
  4083. setModifierValue(instanceModifiers, 'flip', 'padding', computedFlipPadding);
  4084. return data;
  4085. }
  4086. },
  4087. preventOverflow: _extends({
  4088. boundariesElement: instance.props.boundary
  4089. }, preventOverflowModifier),
  4090. flip: _extends({
  4091. enabled: instance.props.flip,
  4092. behavior: instance.props.flipBehavior
  4093. }, flipModifier),
  4094. arrow: _extends({
  4095. element: arrow,
  4096. enabled: !!arrow
  4097. }, getModifier(popperOptions, 'arrow')),
  4098. offset: _extends({
  4099. offset: instance.props.offset
  4100. }, getModifier(popperOptions, 'offset'))
  4101. }),
  4102. onCreate: function onCreate(data) {
  4103. applyMutations(data);
  4104. preserveInvocation(popperOptions && popperOptions.onCreate, config.onCreate, [data]);
  4105. runMountCallback();
  4106. },
  4107. onUpdate: function onUpdate(data) {
  4108. applyMutations(data);
  4109. preserveInvocation(popperOptions && popperOptions.onUpdate, config.onUpdate, [data]);
  4110. runMountCallback();
  4111. }
  4112. });
  4113.  
  4114. instance.popperInstance = new Popper(reference, popper, config);
  4115. }
  4116.  
  4117. function runMountCallback() {
  4118. // Only invoke currentMountCallback after 2 updates
  4119. // This fixes some bugs in Popper.js (TODO: aim for only 1 update)
  4120. if (popperUpdates === 0) {
  4121. popperUpdates++; // 1
  4122.  
  4123. instance.popperInstance.update();
  4124. } else if (currentMountCallback && popperUpdates === 1) {
  4125. popperUpdates++; // 2
  4126.  
  4127. reflow(popper);
  4128. currentMountCallback();
  4129. }
  4130. }
  4131.  
  4132. function mount() {
  4133. // The mounting callback (`currentMountCallback`) is only run due to a
  4134. // popperInstance update/create
  4135. popperUpdates = 0;
  4136. var appendTo = instance.props.appendTo;
  4137. var parentNode; // By default, we'll append the popper to the triggerTargets's parentNode so
  4138. // it's directly after the reference element so the elements inside the
  4139. // tippy can be tabbed to
  4140. // If there are clipping issues, the user can specify a different appendTo
  4141. // and ensure focus management is handled correctly manually
  4142.  
  4143. var node = getCurrentTarget();
  4144.  
  4145. if (instance.props.interactive && appendTo === defaultProps.appendTo || appendTo === 'parent') {
  4146. parentNode = node.parentNode;
  4147. } else {
  4148. parentNode = invokeWithArgsOrReturn(appendTo, [node]);
  4149. } // The popper element needs to exist on the DOM before its position can be
  4150. // updated as Popper.js needs to read its dimensions
  4151.  
  4152.  
  4153. if (!parentNode.contains(popper)) {
  4154. parentNode.appendChild(popper);
  4155. }
  4156.  
  4157. {
  4158. // Accessibility check
  4159. warnWhen(instance.props.interactive && appendTo === defaultProps.appendTo && node.nextElementSibling !== popper, ['Interactive tippy element may not be accessible via keyboard navigation', 'because it is not directly after the reference element in the DOM source', 'order.', '\n\n', 'Using a wrapper <div> or <span> tag around the reference element solves', 'this by creating a new parentNode context.', '\n\n', 'Specifying `appendTo: document.body` silences this warning, but it', 'assumes you are using a focus management solution to handle keyboard', 'navigation.', '\n\n', 'See: https://atomiks.github.io/tippyjs/accessibility/#interactivity'].join(' '));
  4160. }
  4161.  
  4162. setModifierValue(instance.popperInstance.modifiers, 'flip', 'enabled', instance.props.flip);
  4163. instance.popperInstance.enableEventListeners(); // Mounting callback invoked in `onUpdate`
  4164.  
  4165. instance.popperInstance.update();
  4166. }
  4167.  
  4168. function scheduleShow(event) {
  4169. instance.clearDelayTimeouts();
  4170.  
  4171. if (!instance.popperInstance) {
  4172. createPopperInstance();
  4173. }
  4174.  
  4175. if (event) {
  4176. invokeHook('onTrigger', [instance, event]);
  4177. }
  4178.  
  4179. addDocumentMouseDownListener();
  4180. var delay = getDelay(true);
  4181.  
  4182. if (delay) {
  4183. showTimeout = setTimeout(function () {
  4184. instance.show();
  4185. }, delay);
  4186. } else {
  4187. instance.show();
  4188. }
  4189. }
  4190.  
  4191. function scheduleHide(event) {
  4192. instance.clearDelayTimeouts();
  4193. invokeHook('onUntrigger', [instance, event]);
  4194.  
  4195. if (!instance.state.isVisible) {
  4196. removeDocumentMouseDownListener();
  4197. return;
  4198. } // For interactive tippies, scheduleHide is added to a document.body handler
  4199. // from onMouseLeave so must intercept scheduled hides from mousemove/leave
  4200. // events when trigger contains mouseenter and click, and the tip is
  4201. // currently shown as a result of a click.
  4202.  
  4203.  
  4204. if (includes(instance.props.trigger, 'mouseenter') && includes(instance.props.trigger, 'click') && includes(['mouseleave', 'mousemove'], event.type) && isVisibleFromClick) {
  4205. return;
  4206. }
  4207.  
  4208. var delay = getDelay(false);
  4209.  
  4210. if (delay) {
  4211. hideTimeout = setTimeout(function () {
  4212. if (instance.state.isVisible) {
  4213. instance.hide();
  4214. }
  4215. }, delay);
  4216. } else {
  4217. // Fixes a `transitionend` problem when it fires 1 frame too
  4218. // late sometimes, we don't want hide() to be called.
  4219. scheduleHideAnimationFrame = requestAnimationFrame(function () {
  4220. instance.hide();
  4221. });
  4222. }
  4223. }
  4224. /* ======================= 🔑 Public methods 🔑 ======================= */
  4225.  
  4226.  
  4227. function enable() {
  4228. instance.state.isEnabled = true;
  4229. }
  4230.  
  4231. function disable() {
  4232. // Disabling the instance should also hide it
  4233. // https://github.com/atomiks/tippy.js-react/issues/106
  4234. instance.hide();
  4235. instance.state.isEnabled = false;
  4236. }
  4237.  
  4238. function clearDelayTimeouts() {
  4239. clearTimeout(showTimeout);
  4240. clearTimeout(hideTimeout);
  4241. cancelAnimationFrame(scheduleHideAnimationFrame);
  4242. }
  4243.  
  4244. function setProps(partialProps) {
  4245. {
  4246. warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('setProps'));
  4247. }
  4248.  
  4249. if (instance.state.isDestroyed) {
  4250. return;
  4251. }
  4252.  
  4253. {
  4254. validateProps(partialProps, plugins);
  4255. warnWhen(partialProps.plugins ? partialProps.plugins.length !== plugins.length || plugins.some(function (p, i) {
  4256. if (partialProps.plugins && partialProps.plugins[i]) {
  4257. return p !== partialProps.plugins[i];
  4258. } else {
  4259. return true;
  4260. }
  4261. }) : false, "Cannot update plugins");
  4262. }
  4263.  
  4264. invokeHook('onBeforeUpdate', [instance, partialProps]);
  4265. removeListenersFromTriggerTarget();
  4266. var prevProps = instance.props;
  4267. var nextProps = evaluateProps(reference, _extends({}, instance.props, {}, partialProps, {
  4268. ignoreAttributes: true
  4269. }));
  4270. nextProps.ignoreAttributes = useIfDefined(partialProps.ignoreAttributes, prevProps.ignoreAttributes);
  4271. instance.props = nextProps;
  4272. addListenersToTriggerTarget();
  4273.  
  4274. if (prevProps.interactiveDebounce !== nextProps.interactiveDebounce) {
  4275. cleanupInteractiveMouseListeners();
  4276. debouncedOnMouseMove = debounce(onMouseMove, nextProps.interactiveDebounce);
  4277. }
  4278.  
  4279. updatePopperElement(popper, prevProps, nextProps);
  4280. instance.popperChildren = getChildren(popper); // Ensure stale aria-expanded attributes are removed
  4281.  
  4282. if (prevProps.triggerTarget && !nextProps.triggerTarget) {
  4283. normalizeToArray(prevProps.triggerTarget).forEach(function (node) {
  4284. node.removeAttribute('aria-expanded');
  4285. });
  4286. } else if (nextProps.triggerTarget) {
  4287. reference.removeAttribute('aria-expanded');
  4288. }
  4289.  
  4290. handleAriaExpandedAttribute();
  4291.  
  4292. if (instance.popperInstance) {
  4293. if (POPPER_INSTANCE_DEPENDENCIES.some(function (prop) {
  4294. return hasOwnProperty(partialProps, prop) && partialProps[prop] !== prevProps[prop];
  4295. })) {
  4296. var currentReference = instance.popperInstance.reference;
  4297. instance.popperInstance.destroy();
  4298. createPopperInstance();
  4299. instance.popperInstance.reference = currentReference;
  4300.  
  4301. if (instance.state.isVisible) {
  4302. instance.popperInstance.enableEventListeners();
  4303. }
  4304. } else {
  4305. instance.popperInstance.update();
  4306. }
  4307. }
  4308.  
  4309. invokeHook('onAfterUpdate', [instance, partialProps]);
  4310. }
  4311.  
  4312. function setContent(content) {
  4313. instance.setProps({
  4314. content: content
  4315. });
  4316. }
  4317.  
  4318. function show(duration) {
  4319. if (duration === void 0) {
  4320. duration = getValueAtIndexOrReturn(instance.props.duration, 0, defaultProps.duration);
  4321. }
  4322.  
  4323. {
  4324. warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('show'));
  4325. } // Early bail-out
  4326.  
  4327.  
  4328. var isAlreadyVisible = instance.state.isVisible;
  4329. var isDestroyed = instance.state.isDestroyed;
  4330. var isDisabled = !instance.state.isEnabled;
  4331. var isTouchAndTouchDisabled = currentInput.isTouch && !instance.props.touch;
  4332.  
  4333. if (isAlreadyVisible || isDestroyed || isDisabled || isTouchAndTouchDisabled) {
  4334. return;
  4335. } // Normalize `disabled` behavior across browsers.
  4336. // Firefox allows events on disabled elements, but Chrome doesn't.
  4337. // Using a wrapper element (i.e. <span>) is recommended.
  4338.  
  4339.  
  4340. if (getCurrentTarget().hasAttribute('disabled')) {
  4341. return;
  4342. }
  4343.  
  4344. if (!instance.popperInstance) {
  4345. createPopperInstance();
  4346. }
  4347.  
  4348. invokeHook('onShow', [instance], false);
  4349.  
  4350. if (instance.props.onShow(instance) === false) {
  4351. return;
  4352. }
  4353.  
  4354. addDocumentMouseDownListener();
  4355. popper.style.visibility = 'visible';
  4356. instance.state.isVisible = true; // Prevent a transition of the popper from its previous position and of the
  4357. // elements at a different placement
  4358. // Check if the tippy was fully unmounted before `show()` was called, to
  4359. // allow for smooth transition for `createSingleton()`
  4360.  
  4361. if (!instance.state.isMounted) {
  4362. setTransitionDuration(transitionableElements.concat(popper), 0);
  4363. }
  4364.  
  4365. currentMountCallback = function currentMountCallback() {
  4366. if (!instance.state.isVisible) {
  4367. return;
  4368. }
  4369.  
  4370. setTransitionDuration([popper], instance.props.updateDuration);
  4371. setTransitionDuration(transitionableElements, duration);
  4372. setVisibilityState(transitionableElements, 'visible');
  4373. handleAriaDescribedByAttribute();
  4374. handleAriaExpandedAttribute();
  4375. pushIfUnique(mountedInstances, instance);
  4376. updateIOSClass(true);
  4377. instance.state.isMounted = true;
  4378. invokeHook('onMount', [instance]);
  4379. onTransitionedIn(duration, function () {
  4380. instance.state.isShown = true;
  4381. invokeHook('onShown', [instance]);
  4382. });
  4383. };
  4384.  
  4385. mount();
  4386. }
  4387.  
  4388. function hide(duration) {
  4389. if (duration === void 0) {
  4390. duration = getValueAtIndexOrReturn(instance.props.duration, 1, defaultProps.duration);
  4391. }
  4392.  
  4393. {
  4394. warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('hide'));
  4395. } // Early bail-out
  4396.  
  4397.  
  4398. var isAlreadyHidden = !instance.state.isVisible && !isBeingDestroyed;
  4399. var isDestroyed = instance.state.isDestroyed;
  4400. var isDisabled = !instance.state.isEnabled && !isBeingDestroyed;
  4401.  
  4402. if (isAlreadyHidden || isDestroyed || isDisabled) {
  4403. return;
  4404. }
  4405.  
  4406. invokeHook('onHide', [instance], false);
  4407.  
  4408. if (instance.props.onHide(instance) === false && !isBeingDestroyed) {
  4409. return;
  4410. }
  4411.  
  4412. removeDocumentMouseDownListener();
  4413. popper.style.visibility = 'hidden';
  4414. instance.state.isVisible = false;
  4415. instance.state.isShown = false;
  4416. setTransitionDuration(transitionableElements, duration);
  4417. setVisibilityState(transitionableElements, 'hidden');
  4418. handleAriaDescribedByAttribute();
  4419. handleAriaExpandedAttribute();
  4420. onTransitionedOut(duration, function () {
  4421. instance.popperInstance.disableEventListeners();
  4422. instance.popperInstance.options.placement = instance.props.placement;
  4423. popper.parentNode.removeChild(popper);
  4424. mountedInstances = mountedInstances.filter(function (i) {
  4425. return i !== instance;
  4426. });
  4427.  
  4428. if (mountedInstances.length === 0) {
  4429. updateIOSClass(false);
  4430. }
  4431.  
  4432. instance.state.isMounted = false;
  4433. invokeHook('onHidden', [instance]);
  4434. });
  4435. }
  4436.  
  4437. function destroy() {
  4438. {
  4439. warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('destroy'));
  4440. }
  4441.  
  4442. if (instance.state.isDestroyed) {
  4443. return;
  4444. }
  4445.  
  4446. isBeingDestroyed = true;
  4447. instance.clearDelayTimeouts();
  4448. instance.hide(0);
  4449. removeListenersFromTriggerTarget();
  4450. delete reference._tippy;
  4451.  
  4452. if (instance.popperInstance) {
  4453. instance.popperInstance.destroy();
  4454. }
  4455.  
  4456. isBeingDestroyed = false;
  4457. instance.state.isDestroyed = true;
  4458. invokeHook('onDestroy', [instance]);
  4459. }
  4460. }
  4461.  
  4462. function tippy(targets, optionalProps,
  4463. /** @deprecated use Props.plugins */
  4464. plugins) {
  4465. if (optionalProps === void 0) {
  4466. optionalProps = {};
  4467. }
  4468.  
  4469. if (plugins === void 0) {
  4470. plugins = [];
  4471. }
  4472.  
  4473. plugins = defaultProps.plugins.concat(optionalProps.plugins || plugins);
  4474.  
  4475. {
  4476. validateTargets(targets);
  4477. validateProps(optionalProps, plugins);
  4478. }
  4479.  
  4480. bindGlobalEventListeners();
  4481.  
  4482. var passedProps = _extends({}, optionalProps, {
  4483. plugins: plugins
  4484. });
  4485.  
  4486. var elements = getArrayOfElements(targets);
  4487.  
  4488. {
  4489. var isSingleContentElement = isElement(passedProps.content);
  4490. var isMoreThanOneReferenceElement = elements.length > 1;
  4491. warnWhen(isSingleContentElement && isMoreThanOneReferenceElement, ['tippy() was passed an Element as the `content` prop, but more than one tippy', 'instance was created by this invocation. This means the content element will', 'only be appended to the last tippy instance.', '\n\n', 'Instead, pass the .innerHTML of the element, or use a function that returns a', 'cloned version of the element instead.', '\n\n', '1) content: element.innerHTML\n', '2) content: () => element.cloneNode(true)'].join(' '));
  4492. }
  4493.  
  4494. var instances = elements.reduce(function (acc, reference) {
  4495. var instance = reference && createTippy(reference, passedProps);
  4496.  
  4497. if (instance) {
  4498. acc.push(instance);
  4499. }
  4500.  
  4501. return acc;
  4502. }, []);
  4503. return isElement(targets) ? instances[0] : instances;
  4504. }
  4505.  
  4506. tippy.version = version;
  4507. tippy.defaultProps = defaultProps;
  4508. tippy.setDefaultProps = setDefaultProps;
  4509. tippy.currentInput = currentInput;
  4510. /**
  4511. * Hides all visible poppers on the document
  4512. */
  4513.  
  4514. var hideAll = function hideAll(_temp) {
  4515. var _ref = _temp === void 0 ? {} : _temp,
  4516. excludedReferenceOrInstance = _ref.exclude,
  4517. duration = _ref.duration;
  4518.  
  4519. mountedInstances.forEach(function (instance) {
  4520. var isExcluded = false;
  4521.  
  4522. if (excludedReferenceOrInstance) {
  4523. isExcluded = isReferenceElement(excludedReferenceOrInstance) ? instance.reference === excludedReferenceOrInstance : instance.popper === excludedReferenceOrInstance.popper;
  4524. }
  4525.  
  4526. if (!isExcluded) {
  4527. instance.hide(duration);
  4528. }
  4529. });
  4530. };
  4531.  
  4532. /**
  4533. * Re-uses a single tippy element for many different tippy instances.
  4534. * Replaces v4's `tippy.group()`.
  4535. */
  4536.  
  4537. var createSingleton = function createSingleton(tippyInstances, optionalProps,
  4538. /** @deprecated use Props.plugins */
  4539. plugins) {
  4540. if (optionalProps === void 0) {
  4541. optionalProps = {};
  4542. }
  4543.  
  4544. if (plugins === void 0) {
  4545. plugins = [];
  4546. }
  4547.  
  4548. {
  4549. errorWhen(!Array.isArray(tippyInstances), ['The first argument passed to createSingleton() must be an array of tippy', 'instances. The passed value was', String(tippyInstances)].join(' '));
  4550. }
  4551.  
  4552. plugins = optionalProps.plugins || plugins;
  4553. tippyInstances.forEach(function (instance) {
  4554. instance.disable();
  4555. });
  4556.  
  4557. var userAria = _extends({}, defaultProps, {}, optionalProps).aria;
  4558.  
  4559. var currentAria;
  4560. var currentTarget;
  4561. var shouldSkipUpdate = false;
  4562. var references = tippyInstances.map(function (instance) {
  4563. return instance.reference;
  4564. });
  4565. var singleton = {
  4566. fn: function fn(instance) {
  4567. function handleAriaDescribedByAttribute(isShow) {
  4568. if (!currentAria) {
  4569. return;
  4570. }
  4571.  
  4572. var attr = "aria-" + currentAria;
  4573.  
  4574. if (isShow && !instance.props.interactive) {
  4575. currentTarget.setAttribute(attr, instance.popperChildren.tooltip.id);
  4576. } else {
  4577. currentTarget.removeAttribute(attr);
  4578. }
  4579. }
  4580.  
  4581. return {
  4582. onAfterUpdate: function onAfterUpdate(_, _ref) {
  4583. var aria = _ref.aria;
  4584.  
  4585. // Ensure `aria` for the singleton instance stays `null`, while
  4586. // changing the `userAria` value
  4587. if (aria !== undefined && aria !== userAria) {
  4588. if (!shouldSkipUpdate) {
  4589. userAria = aria;
  4590. } else {
  4591. shouldSkipUpdate = true;
  4592. instance.setProps({
  4593. aria: null
  4594. });
  4595. shouldSkipUpdate = false;
  4596. }
  4597. }
  4598. },
  4599. onDestroy: function onDestroy() {
  4600. tippyInstances.forEach(function (instance) {
  4601. instance.enable();
  4602. });
  4603. },
  4604. onMount: function onMount() {
  4605. handleAriaDescribedByAttribute(true);
  4606. },
  4607. onUntrigger: function onUntrigger() {
  4608. handleAriaDescribedByAttribute(false);
  4609. },
  4610. onTrigger: function onTrigger(_, event) {
  4611. var target = event.currentTarget;
  4612. var index = references.indexOf(target); // bail-out
  4613.  
  4614. if (target === currentTarget) {
  4615. return;
  4616. }
  4617.  
  4618. currentTarget = target;
  4619. currentAria = userAria;
  4620.  
  4621. if (instance.state.isVisible) {
  4622. handleAriaDescribedByAttribute(true);
  4623. }
  4624.  
  4625. instance.popperInstance.reference = target;
  4626. instance.setContent(tippyInstances[index].props.content);
  4627. }
  4628. };
  4629. }
  4630. };
  4631. return tippy(div(), _extends({}, optionalProps, {
  4632. plugins: [singleton].concat(plugins),
  4633. aria: null,
  4634. triggerTarget: references
  4635. }));
  4636. };
  4637.  
  4638. var BUBBLING_EVENTS_MAP = {
  4639. mouseover: 'mouseenter',
  4640. focusin: 'focus',
  4641. click: 'click'
  4642. };
  4643. /**
  4644. * Creates a delegate instance that controls the creation of tippy instances
  4645. * for child elements (`target` CSS selector).
  4646. */
  4647.  
  4648. function delegate(targets, props,
  4649. /** @deprecated use Props.plugins */
  4650. plugins) {
  4651. if (plugins === void 0) {
  4652. plugins = [];
  4653. }
  4654.  
  4655. {
  4656. errorWhen(!(props && props.target), ['You must specity a `target` prop indicating a CSS selector string matching', 'the target elements that should receive a tippy.'].join(' '));
  4657. }
  4658.  
  4659. plugins = props.plugins || plugins;
  4660. var listeners = [];
  4661. var childTippyInstances = [];
  4662. var target = props.target;
  4663. var nativeProps = removeProperties(props, ['target']);
  4664.  
  4665. var parentProps = _extends({}, nativeProps, {
  4666. plugins: plugins,
  4667. trigger: 'manual'
  4668. });
  4669.  
  4670. var childProps = _extends({}, nativeProps, {
  4671. plugins: plugins,
  4672. showOnCreate: true
  4673. });
  4674.  
  4675. var returnValue = tippy(targets, parentProps);
  4676. var normalizedReturnValue = normalizeToArray(returnValue);
  4677.  
  4678. function onTrigger(event) {
  4679. if (!event.target) {
  4680. return;
  4681. }
  4682.  
  4683. var targetNode = event.target.closest(target);
  4684.  
  4685. if (!targetNode) {
  4686. return;
  4687. } // Get relevant trigger with fallbacks:
  4688. // 1. Check `data-tippy-trigger` attribute on target node
  4689. // 2. Fallback to `trigger` passed to `delegate()`
  4690. // 3. Fallback to `defaultProps.trigger`
  4691.  
  4692.  
  4693. var trigger = targetNode.getAttribute('data-tippy-trigger') || props.trigger || defaultProps.trigger; // Only create the instance if the bubbling event matches the trigger type
  4694.  
  4695. if (!includes(trigger, BUBBLING_EVENTS_MAP[event.type])) {
  4696. return;
  4697. }
  4698.  
  4699. var instance = tippy(targetNode, childProps);
  4700.  
  4701. if (instance) {
  4702. childTippyInstances = childTippyInstances.concat(instance);
  4703. }
  4704. }
  4705.  
  4706. function on(node, eventType, handler, options) {
  4707. if (options === void 0) {
  4708. options = false;
  4709. }
  4710.  
  4711. node.addEventListener(eventType, handler, options);
  4712. listeners.push({
  4713. node: node,
  4714. eventType: eventType,
  4715. handler: handler,
  4716. options: options
  4717. });
  4718. }
  4719.  
  4720. function addEventListeners(instance) {
  4721. var reference = instance.reference;
  4722. on(reference, 'mouseover', onTrigger);
  4723. on(reference, 'focusin', onTrigger);
  4724. on(reference, 'click', onTrigger);
  4725. }
  4726.  
  4727. function removeEventListeners() {
  4728. listeners.forEach(function (_ref) {
  4729. var node = _ref.node,
  4730. eventType = _ref.eventType,
  4731. handler = _ref.handler,
  4732. options = _ref.options;
  4733. node.removeEventListener(eventType, handler, options);
  4734. });
  4735. listeners = [];
  4736. }
  4737.  
  4738. function applyMutations(instance) {
  4739. var originalDestroy = instance.destroy;
  4740.  
  4741. instance.destroy = function (shouldDestroyChildInstances) {
  4742. if (shouldDestroyChildInstances === void 0) {
  4743. shouldDestroyChildInstances = true;
  4744. }
  4745.  
  4746. if (shouldDestroyChildInstances) {
  4747. childTippyInstances.forEach(function (instance) {
  4748. instance.destroy();
  4749. });
  4750. }
  4751.  
  4752. childTippyInstances = [];
  4753. removeEventListeners();
  4754. originalDestroy();
  4755. };
  4756.  
  4757. addEventListeners(instance);
  4758. }
  4759.  
  4760. normalizedReturnValue.forEach(applyMutations);
  4761. return returnValue;
  4762. }
  4763.  
  4764. var animateFill = {
  4765. name: 'animateFill',
  4766. defaultValue: false,
  4767. fn: function fn(instance) {
  4768. var _instance$popperChild = instance.popperChildren,
  4769. tooltip = _instance$popperChild.tooltip,
  4770. content = _instance$popperChild.content;
  4771. var backdrop = instance.props.animateFill ? createBackdropElement() : null;
  4772.  
  4773. function addBackdropToPopperChildren() {
  4774. instance.popperChildren.backdrop = backdrop;
  4775. }
  4776.  
  4777. return {
  4778. onCreate: function onCreate() {
  4779. if (backdrop) {
  4780. addBackdropToPopperChildren();
  4781. tooltip.insertBefore(backdrop, tooltip.firstElementChild);
  4782. tooltip.setAttribute('data-animatefill', '');
  4783. tooltip.style.overflow = 'hidden';
  4784. instance.setProps({
  4785. animation: 'shift-away',
  4786. arrow: false
  4787. });
  4788. }
  4789. },
  4790. onMount: function onMount() {
  4791. if (backdrop) {
  4792. var transitionDuration = tooltip.style.transitionDuration;
  4793. var duration = Number(transitionDuration.replace('ms', '')); // The content should fade in after the backdrop has mostly filled the
  4794. // tooltip element. `clip-path` is the other alternative but is not
  4795. // well-supported and is buggy on some devices.
  4796.  
  4797. content.style.transitionDelay = Math.round(duration / 10) + "ms";
  4798. backdrop.style.transitionDuration = transitionDuration;
  4799. setVisibilityState([backdrop], 'visible'); // Warn if the stylesheets are not loaded
  4800.  
  4801. {
  4802. warnWhen(getComputedStyle(backdrop).position !== 'absolute', "The `tippy.js/dist/backdrop.css` stylesheet has not been\n imported!\n \n The `animateFill` plugin requires this stylesheet to work.");
  4803. warnWhen(getComputedStyle(tooltip).transform === 'none', "The `tippy.js/animations/shift-away.css` stylesheet has not\n been imported!\n \n The `animateFill` plugin requires this stylesheet to work.");
  4804. }
  4805. }
  4806. },
  4807. onShow: function onShow() {
  4808. if (backdrop) {
  4809. backdrop.style.transitionDuration = '0ms';
  4810. }
  4811. },
  4812. onHide: function onHide() {
  4813. if (backdrop) {
  4814. setVisibilityState([backdrop], 'hidden');
  4815. }
  4816. },
  4817. onAfterUpdate: function onAfterUpdate() {
  4818. // With this type of prop, it's highly unlikely it will be changed
  4819. // dynamically. We'll leave out the diff/update logic it to save bytes.
  4820. // `popperChildren` is assigned a new object onAfterUpdate
  4821. addBackdropToPopperChildren();
  4822. }
  4823. };
  4824. }
  4825. };
  4826.  
  4827. function createBackdropElement() {
  4828. var backdrop = div();
  4829. backdrop.className = BACKDROP_CLASS;
  4830. setVisibilityState([backdrop], 'hidden');
  4831. return backdrop;
  4832. }
  4833.  
  4834. var followCursor = {
  4835. name: 'followCursor',
  4836. defaultValue: false,
  4837. fn: function fn(instance) {
  4838. var reference = instance.reference,
  4839. popper = instance.popper;
  4840. var originalReference = null; // Support iframe contexts
  4841. // Static check that assumes any of the `triggerTarget` or `reference`
  4842. // nodes will never change documents, even when they are updated
  4843.  
  4844. var doc = getOwnerDocument(instance.props.triggerTarget || reference); // Internal state
  4845.  
  4846. var lastMouseMoveEvent;
  4847. var mouseCoords = null;
  4848. var isInternallySettingControlledProp = false; // These are controlled by this plugin, so we need to store the user's
  4849. // original prop value
  4850.  
  4851. var userProps = instance.props;
  4852.  
  4853. function setUserProps(props) {
  4854. var keys = Object.keys(props);
  4855. keys.forEach(function (prop) {
  4856. userProps[prop] = useIfDefined(props[prop], userProps[prop]);
  4857. });
  4858. }
  4859.  
  4860. function getIsManual() {
  4861. return instance.props.trigger.trim() === 'manual';
  4862. }
  4863.  
  4864. function getIsEnabled() {
  4865. // #597
  4866. var isValidMouseEvent = getIsManual() ? true : // Check if a keyboard "click"
  4867. mouseCoords !== null && !(mouseCoords.clientX === 0 && mouseCoords.clientY === 0);
  4868. return instance.props.followCursor && isValidMouseEvent;
  4869. }
  4870.  
  4871. function getIsInitialBehavior() {
  4872. return currentInput.isTouch || instance.props.followCursor === 'initial' && instance.state.isVisible;
  4873. }
  4874.  
  4875. function resetReference() {
  4876. if (instance.popperInstance && originalReference) {
  4877. instance.popperInstance.reference = originalReference;
  4878. }
  4879. }
  4880.  
  4881. function handlePlacement() {
  4882. // Due to `getVirtualOffsets()`, we need to reverse the placement if it's
  4883. // shifted (start -> end, and vice-versa)
  4884. // Early bail-out
  4885. if (!getIsEnabled() && instance.props.placement === userProps.placement) {
  4886. return;
  4887. }
  4888.  
  4889. var placement = userProps.placement;
  4890. var shift = placement.split('-')[1];
  4891. isInternallySettingControlledProp = true;
  4892. instance.setProps({
  4893. placement: getIsEnabled() && shift ? placement.replace(shift, shift === 'start' ? 'end' : 'start') : placement
  4894. });
  4895. isInternallySettingControlledProp = false;
  4896. }
  4897.  
  4898. function handlePopperListeners() {
  4899. if (!instance.popperInstance) {
  4900. return;
  4901. } // Popper's scroll listeners make sense for `true` only. TODO: work out
  4902. // how to only listen horizontal scroll for "horizontal" and vertical
  4903. // scroll for "vertical"
  4904.  
  4905.  
  4906. if (getIsEnabled() && getIsInitialBehavior()) {
  4907. instance.popperInstance.disableEventListeners();
  4908. }
  4909. }
  4910.  
  4911. function handleMouseMoveListener() {
  4912. if (getIsEnabled()) {
  4913. addListener();
  4914. } else {
  4915. resetReference();
  4916. }
  4917. }
  4918.  
  4919. function triggerLastMouseMove() {
  4920. if (getIsEnabled()) {
  4921. onMouseMove(lastMouseMoveEvent);
  4922. }
  4923. }
  4924.  
  4925. function addListener() {
  4926. doc.addEventListener('mousemove', onMouseMove);
  4927. }
  4928.  
  4929. function removeListener() {
  4930. doc.removeEventListener('mousemove', onMouseMove);
  4931. }
  4932.  
  4933. function onMouseMove(event) {
  4934. var _lastMouseMoveEvent = lastMouseMoveEvent = event,
  4935. clientX = _lastMouseMoveEvent.clientX,
  4936. clientY = _lastMouseMoveEvent.clientY;
  4937.  
  4938. if (!instance.popperInstance || !instance.state.currentPlacement) {
  4939. return;
  4940. } // If the instance is interactive, avoid updating the position unless it's
  4941. // over the reference element
  4942.  
  4943.  
  4944. var isCursorOverReference = closestCallback(event.target, function (el) {
  4945. return el === reference;
  4946. });
  4947. var followCursor = instance.props.followCursor;
  4948. var isHorizontal = followCursor === 'horizontal';
  4949. var isVertical = followCursor === 'vertical';
  4950. var isVerticalPlacement = includes(['top', 'bottom'], getBasePlacement(instance.state.currentPlacement)); // The virtual reference needs some size to prevent itself from overflowing
  4951.  
  4952. var _getVirtualOffsets = getVirtualOffsets(popper, isVerticalPlacement),
  4953. size = _getVirtualOffsets.size,
  4954. x = _getVirtualOffsets.x,
  4955. y = _getVirtualOffsets.y;
  4956.  
  4957. if (isCursorOverReference || !instance.props.interactive) {
  4958. // Preserve custom position ReferenceObjects, which may not be the
  4959. // original targets reference passed as an argument
  4960. if (originalReference === null) {
  4961. originalReference = instance.popperInstance.reference;
  4962. }
  4963.  
  4964. instance.popperInstance.reference = {
  4965. referenceNode: reference,
  4966. // These `client` values don't get used by Popper.js if they are 0
  4967. clientWidth: 0,
  4968. clientHeight: 0,
  4969. getBoundingClientRect: function getBoundingClientRect() {
  4970. var rect = reference.getBoundingClientRect();
  4971. return {
  4972. width: isVerticalPlacement ? size : 0,
  4973. height: isVerticalPlacement ? 0 : size,
  4974. top: (isHorizontal ? rect.top : clientY) - y,
  4975. bottom: (isHorizontal ? rect.bottom : clientY) + y,
  4976. left: (isVertical ? rect.left : clientX) - x,
  4977. right: (isVertical ? rect.right : clientX) + x
  4978. };
  4979. }
  4980. };
  4981. instance.popperInstance.update();
  4982. }
  4983.  
  4984. if (getIsInitialBehavior()) {
  4985. removeListener();
  4986. }
  4987. }
  4988.  
  4989. return {
  4990. onAfterUpdate: function onAfterUpdate(_, partialProps) {
  4991. if (!isInternallySettingControlledProp) {
  4992. setUserProps(partialProps);
  4993.  
  4994. if (partialProps.placement) {
  4995. handlePlacement();
  4996. }
  4997. } // A new placement causes the popperInstance to be recreated
  4998.  
  4999.  
  5000. if (partialProps.placement) {
  5001. handlePopperListeners();
  5002. } // Wait for `.update()` to set `instance.state.currentPlacement` to
  5003. // the new placement
  5004.  
  5005.  
  5006. requestAnimationFrame(triggerLastMouseMove);
  5007. },
  5008. onMount: function onMount() {
  5009. triggerLastMouseMove();
  5010. handlePopperListeners();
  5011. },
  5012. onShow: function onShow() {
  5013. if (getIsManual()) {
  5014. // Since there's no trigger event to use, we have to use these as
  5015. // baseline coords
  5016. mouseCoords = {
  5017. clientX: 0,
  5018. clientY: 0
  5019. }; // Ensure `lastMouseMoveEvent` doesn't access any other properties
  5020. // of a MouseEvent here
  5021.  
  5022. lastMouseMoveEvent = mouseCoords;
  5023. handlePlacement();
  5024. handleMouseMoveListener();
  5025. }
  5026. },
  5027. onTrigger: function onTrigger(_, event) {
  5028. // Tapping on touch devices can trigger `mouseenter` then `focus`
  5029. if (mouseCoords) {
  5030. return;
  5031. }
  5032.  
  5033. if (isMouseEvent(event)) {
  5034. mouseCoords = {
  5035. clientX: event.clientX,
  5036. clientY: event.clientY
  5037. };
  5038. lastMouseMoveEvent = event;
  5039. }
  5040.  
  5041. handlePlacement();
  5042. handleMouseMoveListener();
  5043. },
  5044. onUntrigger: function onUntrigger() {
  5045. // If untriggered before showing (`onHidden` will never be invoked)
  5046. if (!instance.state.isVisible) {
  5047. removeListener();
  5048. mouseCoords = null;
  5049. }
  5050. },
  5051. onHidden: function onHidden() {
  5052. removeListener();
  5053. resetReference();
  5054. mouseCoords = null;
  5055. }
  5056. };
  5057. }
  5058. };
  5059. function getVirtualOffsets(popper, isVerticalPlacement) {
  5060. var size = isVerticalPlacement ? popper.offsetWidth : popper.offsetHeight;
  5061. return {
  5062. size: size,
  5063. x: isVerticalPlacement ? size : 0,
  5064. y: isVerticalPlacement ? 0 : size
  5065. };
  5066. }
  5067.  
  5068. // position. This will require the `followCursor` plugin's fixes for overflow
  5069. // due to using event.clientX/Y values. (normalizedPlacement, getVirtualOffsets)
  5070.  
  5071. var inlinePositioning = {
  5072. name: 'inlinePositioning',
  5073. defaultValue: false,
  5074. fn: function fn(instance) {
  5075. var reference = instance.reference;
  5076.  
  5077. function getIsEnabled() {
  5078. return !!instance.props.inlinePositioning;
  5079. }
  5080.  
  5081. return {
  5082. onHidden: function onHidden() {
  5083. if (getIsEnabled()) {
  5084. instance.popperInstance.reference = reference;
  5085. }
  5086. },
  5087. onShow: function onShow() {
  5088. if (!getIsEnabled()) {
  5089. return;
  5090. }
  5091.  
  5092. instance.popperInstance.reference = {
  5093. referenceNode: reference,
  5094. // These `client` values don't get used by Popper.js if they are 0
  5095. clientWidth: 0,
  5096. clientHeight: 0,
  5097. getBoundingClientRect: function getBoundingClientRect() {
  5098. return getInlineBoundingClientRect(instance.state.currentPlacement && getBasePlacement(instance.state.currentPlacement), reference.getBoundingClientRect(), arrayFrom(reference.getClientRects()));
  5099. }
  5100. };
  5101. }
  5102. };
  5103. }
  5104. };
  5105. function getInlineBoundingClientRect(currentBasePlacement, boundingRect, clientRects) {
  5106. // Not an inline element, or placement is not yet known
  5107. if (clientRects.length < 2 || currentBasePlacement === null) {
  5108. return boundingRect;
  5109. }
  5110.  
  5111. switch (currentBasePlacement) {
  5112. case 'top':
  5113. case 'bottom':
  5114. {
  5115. var firstRect = clientRects[0];
  5116. var lastRect = clientRects[clientRects.length - 1];
  5117. var isTop = currentBasePlacement === 'top';
  5118. var top = firstRect.top;
  5119. var bottom = lastRect.bottom;
  5120. var left = isTop ? firstRect.left : lastRect.left;
  5121. var right = isTop ? firstRect.right : lastRect.right;
  5122. var width = right - left;
  5123. var height = bottom - top;
  5124. return {
  5125. top: top,
  5126. bottom: bottom,
  5127. left: left,
  5128. right: right,
  5129. width: width,
  5130. height: height
  5131. };
  5132. }
  5133.  
  5134. case 'left':
  5135. case 'right':
  5136. {
  5137. var minLeft = Math.min.apply(Math, clientRects.map(function (rects) {
  5138. return rects.left;
  5139. }));
  5140. var maxRight = Math.max.apply(Math, clientRects.map(function (rects) {
  5141. return rects.right;
  5142. }));
  5143. var measureRects = clientRects.filter(function (rect) {
  5144. return currentBasePlacement === 'left' ? rect.left === minLeft : rect.right === maxRight;
  5145. });
  5146. var _top = measureRects[0].top;
  5147. var _bottom = measureRects[measureRects.length - 1].bottom;
  5148. var _left = minLeft;
  5149. var _right = maxRight;
  5150.  
  5151. var _width = _right - _left;
  5152.  
  5153. var _height = _bottom - _top;
  5154.  
  5155. return {
  5156. top: _top,
  5157. bottom: _bottom,
  5158. left: _left,
  5159. right: _right,
  5160. width: _width,
  5161. height: _height
  5162. };
  5163. }
  5164.  
  5165. default:
  5166. {
  5167. return boundingRect;
  5168. }
  5169. }
  5170. }
  5171.  
  5172. var sticky = {
  5173. name: 'sticky',
  5174. defaultValue: false,
  5175. fn: function fn(instance) {
  5176. var reference = instance.reference,
  5177. popper = instance.popper;
  5178.  
  5179. function getReference() {
  5180. return instance.popperInstance ? instance.popperInstance.reference : reference;
  5181. }
  5182.  
  5183. function shouldCheck(value) {
  5184. return instance.props.sticky === true || instance.props.sticky === value;
  5185. }
  5186.  
  5187. var prevRefRect = null;
  5188. var prevPopRect = null;
  5189.  
  5190. function updatePosition() {
  5191. var currentRefRect = shouldCheck('reference') ? getReference().getBoundingClientRect() : null;
  5192. var currentPopRect = shouldCheck('popper') ? popper.getBoundingClientRect() : null;
  5193.  
  5194. if (currentRefRect && areRectsDifferent(prevRefRect, currentRefRect) || currentPopRect && areRectsDifferent(prevPopRect, currentPopRect)) {
  5195. instance.popperInstance.update();
  5196. }
  5197.  
  5198. prevRefRect = currentRefRect;
  5199. prevPopRect = currentPopRect;
  5200.  
  5201. if (instance.state.isMounted) {
  5202. requestAnimationFrame(updatePosition);
  5203. }
  5204. }
  5205.  
  5206. return {
  5207. onMount: function onMount() {
  5208. if (instance.props.sticky) {
  5209. updatePosition();
  5210. }
  5211. }
  5212. };
  5213. }
  5214. };
  5215.  
  5216. function areRectsDifferent(rectA, rectB) {
  5217. if (rectA && rectB) {
  5218. return rectA.top !== rectB.top || rectA.right !== rectB.right || rectA.bottom !== rectB.bottom || rectA.left !== rectB.left;
  5219. }
  5220.  
  5221. return true;
  5222. }
  5223.  
  5224. if (isBrowser) {
  5225. injectCSS(css);
  5226. }
  5227.  
  5228. tippy.setDefaultProps({
  5229. plugins: [animateFill, followCursor, inlinePositioning, sticky]
  5230. });
  5231. tippy.createSingleton = createSingleton;
  5232. tippy.delegate = delegate;
  5233. tippy.hideAll = hideAll;
  5234. tippy.roundArrow = ROUND_ARROW;
  5235.  
  5236. return tippy;
  5237.  
  5238. }(Popper));
  5239. //# sourceMappingURL=tippy-bundle.iife.js.map

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址