vendor: 4,678 bytes, lines 1-158
1/**! 2 * @fileOverview Kickass library to create and place poppers near their reference elements. 3 * @version 1.15.0 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 31var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; 32 33var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 34var timeoutDuration = 0; 35for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { 36 if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 37 timeoutDuration = 1; 38 break; 39 } 40} 41 42function microtaskDebounce(fn) { 43 var called = false; 44 return function () { 45 if (called) { 46 return; 47 } 48 called = true; 49 window.Promise.resolve().then(function () { 50 called = false; 51 fn(); 52 }); 53 }; 54} 55 56function taskDebounce(fn) { 57 var scheduled = false; 58 return function () { 59 if (!scheduled) { 60 scheduled = true; 61 setTimeout(function () { 62 scheduled = false; 63 fn(); 64 }, timeoutDuration); 65 } 66 }; 67} 68 69var supportsMicroTasks = isBrowser && window.Promise; 70 71/** 72* Create a debounced version of a method, that's asynchronously deferred 73* but called in the minimum time possible. 74* 75* @method 76* @memberof Popper.Utils 77* @argument {Function} fn 78* @returns {Function} 79*/ 80var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; 81 82/** 83 * Check if the given variable is a function 84 * @method 85 * @memberof Popper.Utils 86 * @argument {Any} functionToCheck - variable to check 87 * @returns {Boolean} answer to: is a function? 88 */ 89function isFunction(functionToCheck) { 90 var getType = {}; 91 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 92} 93 94/** 95 * Get CSS computed property of the given element 96 * @method 97 * @memberof Popper.Utils 98 * @argument {Eement} element 99 * @argument {String} property 100 */ 101function getStyleComputedProperty(element, property) { 102 if (element.nodeType !== 1) { 103 return []; 104 } 105 // NOTE: 1 DOM access here 106 var window = element.ownerDocument.defaultView; 107 var css = window.getComputedStyle(element, null); 108 return property ? css[property] : css; 109} 110 111/** 112 * Returns the parentNode or the host of the element 113 * @method 114 * @memberof Popper.Utils 115 * @argument {Element} element 116 * @returns {Element} parent 117 */ 118function getParentNode(element) { 119 if (element.nodeName === 'HTML') { 120 return element; 121 } 122 return element.parentNode || element.host; 123} 124 125/** 126 * Returns the scrolling parent of the given element 127 * @method 128 * @memberof Popper.Utils 129 * @argument {Element} element 130 * @returns {Element} scroll parent 131 */ 132function getScrollParent(element) { 133 // Return body, `getScroll` will take care to get the correct `scrollTop` from it 134 if (!element) { 135 return document.body; 136 } 137 138 switch (element.nodeName) { 139 case 'HTML': 140 case 'BODY': 141 return element.ownerDocument.body; 142 case '#document': 143 return element.body; 144 } 145 146 // Firefox want us to check `-x` and `-y` variations as well 147 148 var _getStyleComputedProp = getStyleComputedProperty(element), 149 overflow = _getStyleComputedProp.overflow, 150 overflowX = _getStyleComputedProp.overflowX, 151 overflowY = _getStyleComputedProp.overflowY; 152 153 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 154 return element; 155 } 156 157 return getScrollParent(getParentNode(element)); 158}
vendor: 5,677 bytes, lines 158-343
158 159 160var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 161var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); 162 163/** 164 * Determines if the browser is Internet Explorer 165 * @method 166 * @memberof Popper.Utils 167 * @param {Number} version to check 168 * @returns {Boolean} isIE 169 */ 170function isIE(version) { 171 if (version === 11) { 172 return isIE11; 173 } 174 if (version === 10) { 175 return isIE10; 176 } 177 return isIE11 || isIE10; 178} 179 180/** 181 * Returns the offset parent of the given element 182 * @method 183 * @memberof Popper.Utils 184 * @argument {Element} element 185 * @returns {Element} offset parent 186 */ 187function getOffsetParent(element) { 188 if (!element) { 189 return document.documentElement; 190 } 191 192 var noOffsetParent = isIE(10) ? document.body : null; 193 194 // NOTE: 1 DOM access here 195 var offsetParent = element.offsetParent || null; 196 // Skip hidden elements which don't have an offsetParent 197 while (offsetParent === noOffsetParent && element.nextElementSibling) { 198 offsetParent = (element = element.nextElementSibling).offsetParent; 199 } 200 201 var nodeName = offsetParent && offsetParent.nodeName; 202 203 if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 204 return element ? element.ownerDocument.documentElement : document.documentElement; 205 } 206 207 // .offsetParent will return the closest TH, TD or TABLE in case 208 // no offsetParent is present, I hate this job... 209 if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { 210 return getOffsetParent(offsetParent); 211 } 212 213 return offsetParent; 214} 215 216function isOffsetContainer(element) { 217 var nodeName = element.nodeName; 218 219 if (nodeName === 'BODY') { 220 return false; 221 } 222 return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; 223} 224 225/** 226 * Finds the root node (document, shadowDOM root) of the given element 227 * @method 228 * @memberof Popper.Utils 229 * @argument {Element} node 230 * @returns {Element} root node 231 */ 232function getRoot(node) { 233 if (node.parentNode !== null) { 234 return getRoot(node.parentNode); 235 } 236 237 return node; 238} 239 240/** 241 * Finds the offset parent common to the two provided nodes 242 * @method 243 * @memberof Popper.Utils 244 * @argument {Element} element1 245 * @argument {Element} element2 246 * @returns {Element} common offset parent 247 */ 248function findCommonOffsetParent(element1, element2) { 249 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 250 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 251 return document.documentElement; 252 } 253 254 // Here we make sure to give as "start" the element that comes first in the DOM 255 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 256 var start = order ? element1 : element2; 257 var end = order ? element2 : element1; 258 259 // Get common ancestor container 260 var range = document.createRange(); 261 range.setStart(start, 0); 262 range.setEnd(end, 0); 263 var commonAncestorContainer = range.commonAncestorContainer; 264 265 // Both nodes are inside #document 266 267 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 268 if (isOffsetContainer(commonAncestorContainer)) { 269 return commonAncestorContainer; 270 } 271 272 return getOffsetParent(commonAncestorContainer); 273 } 274 275 // one of the nodes is inside shadowDOM, find which one 276 var element1root = getRoot(element1); 277 if (element1root.host) { 278 return findCommonOffsetParent(element1root.host, element2); 279 } else { 280 return findCommonOffsetParent(element1, getRoot(element2).host); 281 } 282} 283 284/** 285 * Gets the scroll value of the given element in the given side (top and left) 286 * @method 287 * @memberof Popper.Utils 288 * @argument {Element} element 289 * @argument {String} side `top` or `left` 290 * @returns {number} amount of scrolled pixels 291 */ 292function getScroll(element) { 293 var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; 294 295 var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 296 var nodeName = element.nodeName; 297 298 if (nodeName === 'BODY' || nodeName === 'HTML') { 299 var html = element.ownerDocument.documentElement; 300 var scrollingElement = element.ownerDocument.scrollingElement || html; 301 return scrollingElement[upperSide]; 302 } 303 304 return element[upperSide]; 305} 306 307/* 308 * Sum or subtract the element scroll values (left and top) from a given rect object 309 * @method 310 * @memberof Popper.Utils 311 * @param {Object} rect - Rect object you want to change 312 * @param {HTMLElement} element - The element from the function reads the scroll values 313 * @param {Boolean} subtract - set to true if you want to subtract the scroll values 314 * @return {Object} rect - The modifier rect object 315 */ 316function includeScroll(rect, element) { 317 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 318 319 var scrollTop = getScroll(element, 'top'); 320 var scrollLeft = getScroll(element, 'left'); 321 var modifier = subtract ? -1 : 1; 322 rect.top += scrollTop * modifier; 323 rect.bottom += scrollTop * modifier; 324 rect.left += scrollLeft * modifier; 325 rect.right += scrollLeft * modifier; 326 return rect; 327} 328 329/* 330 * Helper to detect borders of a given element 331 * @method 332 * @memberof Popper.Utils 333 * @param {CSSStyleDeclaration} styles 334 * Result of `getStyleComputedProperty` on the given element 335 * @param {String} axis - `x` or `y` 336 * @return {number} borders - The borders size of the given axis 337 */ 338 339function getBordersSize(styles, axis) { 340 var sideA = axis === 'x' ? 'Left' : 'Top'; 341 var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 342 343 return parseFloat(styles['border' + sideA + 'Width']
vendor: 2,732 bytes, lines 343-442
343, 10) + parseFloat(styles['border' + sideB + 'Width'], 10); 344} 345 346function getSize(axis, body, html, computedStyle) { 347 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); 348} 349 350function getWindowSizes(document) { 351 var body = document.body; 352 var html = document.documentElement; 353 var computedStyle = isIE(10) && getComputedStyle(html); 354 355 return { 356 height: getSize('Height', body, html, computedStyle), 357 width: getSize('Width', body, html, computedStyle) 358 }; 359} 360 361var classCallCheck = function (instance, Constructor) { 362 if (!(instance instanceof Constructor)) { 363 throw new TypeError("Cannot call a class as a function"); 364 } 365}; 366 367var createClass = function () { 368 function defineProperties(target, props) { 369 for (var i = 0; i < props.length; i++) { 370 var descriptor = props[i]; 371 descriptor.enumerable = descriptor.enumerable || false; 372 descriptor.configurable = true; 373 if ("value" in descriptor) descriptor.writable = true; 374 Object.defineProperty(target, descriptor.key, descriptor); 375 } 376 } 377 378 return function (Constructor, protoProps, staticProps) { 379 if (protoProps) defineProperties(Constructor.prototype, protoProps); 380 if (staticProps) defineProperties(Constructor, staticProps); 381 return Constructor; 382 }; 383}(); 384 385 386 387 388 389var defineProperty = function (obj, key, value) { 390 if (key in obj) { 391 Object.defineProperty(obj, key, { 392 value: value, 393 enumerable: true, 394 configurable: true, 395 writable: true 396 }); 397 } else { 398 obj[key] = value; 399 } 400 401 return obj; 402}; 403 404var _extends = Object.assign || function (target) { 405 for (var i = 1; i < arguments.length; i++) { 406 var source = arguments[i]; 407 408 for (var key in source) { 409 if (Object.prototype.hasOwnProperty.call(source, key)) { 410 target[key] = source[key]; 411 } 412 } 413 } 414 415 return target; 416}; 417 418/** 419 * Given element offsets, generate an output similar to getBoundingClientRect 420 * @method 421 * @memberof Popper.Utils 422 * @argument {Object} offsets 423 * @returns {Object} ClientRect like output 424 */ 425function getClientRect(offsets) { 426 return _extends({}, offsets, { 427 right: offsets.left + offsets.width, 428 bottom: offsets.top + offsets.height 429 }); 430} 431 432/** 433 * Get bounding client rect of given element 434 * @method 435 * @memberof Popper.Utils 436 * @param {HTMLElement} element 437 * @return {Object} client rect 438 */ 439function getBoundingClientRect(element) { 440 var rect = {}; 441 442 // IE10 10 FIX: Please, don't ask, the element isn't
vendor: 4,668 bytes, lines 443-572
443 // considered in DOM in some circumstances... 444 // This isn't reproducible in IE10 compatibility mode of IE11 445 try { 446 if (isIE(10)) { 447 rect = element.getBoundingClientRect(); 448 var scrollTop = getScroll(element, 'top'); 449 var scrollLeft = getScroll(element, 'left'); 450 rect.top += scrollTop; 451 rect.left += scrollLeft; 452 rect.bottom += scrollTop; 453 rect.right += scrollLeft; 454 } else { 455 rect = element.getBoundingClientRect(); 456 } 457 } catch (e) {} 458 459 var result = { 460 left: rect.left, 461 top: rect.top, 462 width: rect.right - rect.left, 463 height: rect.bottom - rect.top 464 }; 465 466 // subtract scrollbar size from sizes 467 var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; 468 var width = sizes.width || element.clientWidth || result.right - result.left; 469 var height = sizes.height || element.clientHeight || result.bottom - result.top; 470 471 var horizScrollbar = element.offsetWidth - width; 472 var vertScrollbar = element.offsetHeight - height; 473 474 // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 475 // we make this check conditional for performance reasons 476 if (horizScrollbar || vertScrollbar) { 477 var styles = getStyleComputedProperty(element); 478 horizScrollbar -= getBordersSize(styles, 'x'); 479 vertScrollbar -= getBordersSize(styles, 'y'); 480 481 result.width -= horizScrollbar; 482 result.height -= vertScrollbar; 483 } 484 485 return getClientRect(result); 486} 487 488function getOffsetRectRelativeToArbitraryNode(children, parent) { 489 var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 490 491 var isIE10 = isIE(10); 492 var isHTML = parent.nodeName === 'HTML'; 493 var childrenRect = getBoundingClientRect(children); 494 var parentRect = getBoundingClientRect(parent); 495 var scrollParent = getScrollParent(children); 496 497 var styles = getStyleComputedProperty(parent); 498 var borderTopWidth = parseFloat(styles.borderTopWidth, 10); 499 var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); 500 501 // In cases where the parent is fixed, we must ignore negative scroll in offset calc 502 if (fixedPosition && isHTML) { 503 parentRect.top = Math.max(parentRect.top, 0); 504 parentRect.left = Math.max(parentRect.left, 0); 505 } 506 var offsets = getClientRect({ 507 top: childrenRect.top - parentRect.top - borderTopWidth, 508 left: childrenRect.left - parentRect.left - borderLeftWidth, 509 width: childrenRect.width, 510 height: childrenRect.height 511 }); 512 offsets.marginTop = 0; 513 offsets.marginLeft = 0; 514 515 // Subtract margins of documentElement in case it's being used as parent 516 // we do this only on HTML because it's the only element that behaves 517 // differently when margins are applied to it. The margins are included in 518 // the box of the documentElement, in the other cases not. 519 if (!isIE10 && isHTML) { 520 var marginTop = parseFloat(styles.marginTop, 10); 521 var marginLeft = parseFloat(styles.marginLeft, 10); 522 523 offsets.top -= borderTopWidth - marginTop; 524 offsets.bottom -= borderTopWidth - marginTop; 525 offsets.left -= borderLeftWidth - marginLeft; 526 offsets.right -= borderLeftWidth - marginLeft; 527 528 // Attach marginTop and marginLeft because in some circumstances we may need them 529 offsets.marginTop = marginTop; 530 offsets.marginLeft = marginLeft; 531 } 532 533 if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { 534 offsets = includeScroll(offsets, parent); 535 } 536 537 return offsets; 538} 539 540function getViewportOffsetRectRelativeToArtbitraryNode(element) { 541 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 542 543 var html = element.ownerDocument.documentElement; 544 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 545 var width = Math.max(html.clientWidth, window.innerWidth || 0); 546 var height = Math.max(html.clientHeight, window.innerHeight || 0); 547 548 var scrollTop = !excludeScroll ? getScroll(html) : 0; 549 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 550 551 var offset = { 552 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 553 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 554 width: width, 555 height: height 556 }; 557 558 return getClientRect(offset); 559} 560 561/** 562 * Check if the given element is fixed or is inside a fixed parent 563 * @method 564 * @memberof Popper.Utils 565 * @argument {Element} element 566 * @argument {Element} customContainer 567 * @returns {Boolean} answer to "isFixed?" 568 */ 569function isFixed(element) { 570 var nodeName = element.nodeName; 571 if (nodeName === 'BODY' || nodeName === 'HTML') { 572 return false;
vendor: 9,912 bytes, lines 573-880
573 } 574 if (getStyleComputedProperty(element, 'position') === 'fixed') { 575 return true; 576 } 577 var parentNode = getParentNode(element); 578 if (!parentNode) { 579 return false; 580 } 581 return isFixed(parentNode); 582} 583 584/** 585 * Finds the first parent of an element that has a transformed property defined 586 * @method 587 * @memberof Popper.Utils 588 * @argument {Element} element 589 * @returns {Element} first transformed parent or documentElement 590 */ 591 592function getFixedPositionOffsetParent(element) { 593 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 594 if (!element || !element.parentElement || isIE()) { 595 return document.documentElement; 596 } 597 var el = element.parentElement; 598 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 599 el = el.parentElement; 600 } 601 return el || document.documentElement; 602} 603 604/** 605 * Computed the boundaries limits and return them 606 * @method 607 * @memberof Popper.Utils 608 * @param {HTMLElement} popper 609 * @param {HTMLElement} reference 610 * @param {number} padding 611 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 612 * @param {Boolean} fixedPosition - Is in fixed position mode 613 * @returns {Object} Coordinates of the boundaries 614 */ 615function getBoundaries(popper, reference, padding, boundariesElement) { 616 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; 617 618 // NOTE: 1 DOM access here 619 620 var boundaries = { top: 0, left: 0 }; 621 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 622 623 // Handle viewport case 624 if (boundariesElement === 'viewport') { 625 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 626 } else { 627 // Handle other cases based on DOM element used as boundaries 628 var boundariesNode = void 0; 629 if (boundariesElement === 'scrollParent') { 630 boundariesNode = getScrollParent(getParentNode(reference)); 631 if (boundariesNode.nodeName === 'BODY') { 632 boundariesNode = popper.ownerDocument.documentElement; 633 } 634 } else if (boundariesElement === 'window') { 635 boundariesNode = popper.ownerDocument.documentElement; 636 } else { 637 boundariesNode = boundariesElement; 638 } 639 640 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); 641 642 // In case of HTML, we need a different computation 643 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 644 var _getWindowSizes = getWindowSizes(popper.ownerDocument), 645 height = _getWindowSizes.height, 646 width = _getWindowSizes.width; 647 648 boundaries.top += offsets.top - offsets.marginTop; 649 boundaries.bottom = height + offsets.top; 650 boundaries.left += offsets.left - offsets.marginLeft; 651 boundaries.right = width + offsets.left; 652 } else { 653 // for all the other DOM elements, this one is good 654 boundaries = offsets; 655 } 656 } 657 658 // Add paddings 659 padding = padding || 0; 660 var isPaddingNumber = typeof padding === 'number'; 661 boundaries.left += isPaddingNumber ? padding : padding.left || 0; 662 boundaries.top += isPaddingNumber ? padding : padding.top || 0; 663 boundaries.right -= isPaddingNumber ? padding : padding.right || 0; 664 boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; 665 666 return boundaries; 667} 668 669function getArea(_ref) { 670 var width = _ref.width, 671 height = _ref.height; 672 673 return width * height; 674} 675 676/** 677 * Utility used to transform the `auto` placement to the placement with more 678 * available space. 679 * @method 680 * @memberof Popper.Utils 681 * @argument {Object} data - The data object generated by update method 682 * @argument {Object} options - Modifiers configuration and options 683 * @returns {Object} The data object, properly modified 684 */ 685function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 686 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 687 688 if (placement.indexOf('auto') === -1) { 689 return placement; 690 } 691 692 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 693 694 var rects = { 695 top: { 696 width: boundaries.width, 697 height: refRect.top - boundaries.top 698 }, 699 right: { 700 width: boundaries.right - refRect.right, 701 height: boundaries.height 702 }, 703 bottom: { 704 width: boundaries.width, 705 height: boundaries.bottom - refRect.bottom 706 }, 707 left: { 708 width: refRect.left - boundaries.left, 709 height: boundaries.height 710 } 711 }; 712 713 var sortedAreas = Object.keys(rects).map(function (key) { 714 return _extends({ 715 key: key 716 }, rects[key], { 717 area: getArea(rects[key]) 718 }); 719 }).sort(function (a, b) { 720 return b.area - a.area; 721 }); 722 723 var filteredAreas = sortedAreas.filter(function (_ref2) { 724 var width = _ref2.width, 725 height = _ref2.height; 726 return width >= popper.clientWidth && height >= popper.clientHeight; 727 }); 728 729 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 730 731 var variation = placement.split('-')[1]; 732 733 return computedPlacement + (variation ? '-' + variation : ''); 734} 735 736/** 737 * Get offsets to the reference element 738 * @method 739 * @memberof Popper.Utils 740 * @param {Object} state 741 * @param {Element} popper - the popper element 742 * @param {Element} reference - the reference element (the popper will be relative to this) 743 * @param {Element} fixedPosition - is in fixed position mode 744 * @returns {Object} An object containing the offsets which will be applied to the popper 745 */ 746function getReferenceOffsets(state, popper, reference) { 747 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 748 749 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 750 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 751} 752 753/** 754 * Get the outer sizes of the given element (offset size + margins) 755 * @method 756 * @memberof Popper.Utils 757 * @argument {Element} element 758 * @returns {Object} object containing width and height properties 759 */ 760function getOuterSizes(element) { 761 var window = element.ownerDocument.defaultView; 762 var styles = window.getComputedStyle(element); 763 var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); 764 var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); 765 var result = { 766 width: element.offsetWidth + y, 767 height: element.offsetHeight + x 768 }; 769 return result; 770} 771 772/** 773 * Get the opposite placement of the given one 774 * @method 775 * @memberof Popper.Utils 776 * @argument {String} placement 777 * @returns {String} flipped placement 778 */ 779function getOppositePlacement(placement) { 780 var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 781 return placement.replace(/left|right|bottom|top/g, function (matched) { 782 return hash[matched]; 783 }); 784} 785 786/** 787 * Get offsets to the popper 788 * @method 789 * @memberof Popper.Utils 790 * @param {Object} position - CSS position the Popper will get applied 791 * @param {HTMLElement} popper - the popper element 792 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 793 * @param {String} placement - one of the valid placement options 794 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 795 */ 796function getPopperOffsets(popper, referenceOffsets, placement) { 797 placement = placement.split('-')[0]; 798 799 // Get popper node sizes 800 var popperRect = getOuterSizes(popper); 801 802 // Add position, width and height to our offsets object 803 var popperOffsets = { 804 width: popperRect.width, 805 height: popperRect.height 806 }; 807 808 // depending by the popper placement we have to compute its offsets slightly differently 809 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 810 var mainSide = isHoriz ? 'top' : 'left'; 811 var secondarySide = isHoriz ? 'left' : 'top'; 812 var measurement = isHoriz ? 'height' : 'width'; 813 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 814 815 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 816 if (placement === secondarySide) { 817 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 818 } else { 819 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 820 } 821 822 return popperOffsets; 823} 824 825/** 826 * Mimics the `find` method of Array 827 * @method 828 * @memberof Popper.Utils 829 * @argument {Array} arr 830 * @argument prop 831 * @argument value 832 * @returns index or -1 833 */ 834function find(arr, check) { 835 // use native find if supported 836 if (Array.prototype.find) { 837 return arr.find(check); 838 } 839 840 // use `filter` to obtain the same behavior of `find` 841 return arr.filter(check)[0]; 842} 843 844/** 845 * Return the index of the matching object 846 * @method 847 * @memberof Popper.Utils 848 * @argument {Array} arr 849 * @argument prop 850 * @argument value 851 * @returns index or -1 852 */ 853function findIndex(arr, prop, value) { 854 // use native findIndex if supported 855 if (Array.prototype.findIndex) { 856 return arr.findIndex(function (cur) { 857 return cur[prop] === value; 858 }); 859 } 860 861 // use `find` + `indexOf` if `findIndex` isn't supported 862 var match = find(arr, function (obj) { 863 return obj[prop] === value; 864 }); 865 return arr.indexOf(match); 866} 867 868/** 869 * Loop trough the list of modifiers and run them in order, 870 * each of them will then edit the data object. 871 * @method 872 * @memberof Popper.Utils 873 * @param {dataObject} data 874 * @param {Array} modifiers 875 * @param {String} ends - Optional modifier name used as stopper 876 * @returns {dataObject} 877 */ 878function runModifiers(modifiers, data, ends) { 879 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 880
vendor: 4,062 bytes, lines 881-1011
881 modifiersToRun.forEach(function (modifier) { 882 if (modifier['function']) { 883 // eslint-disable-line dot-notation 884 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 885 } 886 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 887 if (modifier.enabled && isFunction(fn)) { 888 // Add properties to offsets to make them a complete clientRect object 889 // we do this before each modifier to make sure the previous one doesn't 890 // mess with these values 891 data.offsets.popper = getClientRect(data.offsets.popper); 892 data.offsets.reference = getClientRect(data.offsets.reference); 893 894 data = fn(data, modifier); 895 } 896 }); 897 898 return data; 899} 900 901/** 902 * Updates the position of the popper, computing the new offsets and applying 903 * the new style.<br /> 904 * Prefer `scheduleUpdate` over `update` because of performance reasons. 905 * @method 906 * @memberof Popper 907 */ 908function update() { 909 // if popper is destroyed, don't perform any further update 910 if (this.state.isDestroyed) { 911 return; 912 } 913 914 var data = { 915 instance: this, 916 styles: {}, 917 arrowStyles: {}, 918 attributes: {}, 919 flipped: false, 920 offsets: {} 921 }; 922 923 // compute reference element offsets 924 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); 925 926 // compute auto placement, store placement inside the data object, 927 // modifiers will be able to edit `placement` if needed 928 // and refer to originalPlacement to know the original value 929 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); 930 931 // store the computed placement inside `originalPlacement` 932 data.originalPlacement = data.placement; 933 934 data.positionFixed = this.options.positionFixed; 935 936 // compute the popper offsets 937 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 938 939 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; 940 941 // run the modifiers 942 data = runModifiers(this.modifiers, data); 943 944 // the first `update` will call `onCreate` callback 945 // the other ones will call `onUpdate` callback 946 if (!this.state.isCreated) { 947 this.state.isCreated = true; 948 this.options.onCreate(data); 949 } else { 950 this.options.onUpdate(data); 951 } 952} 953 954/** 955 * Helper used to know if the given modifier is enabled. 956 * @method 957 * @memberof Popper.Utils 958 * @returns {Boolean} 959 */ 960function isModifierEnabled(modifiers, modifierName) { 961 return modifiers.some(function (_ref) { 962 var name = _ref.name, 963 enabled = _ref.enabled; 964 return enabled && name === modifierName; 965 }); 966} 967 968/** 969 * Get the prefixed supported property name 970 * @method 971 * @memberof Popper.Utils 972 * @argument {String} property (camelCase) 973 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 974 */ 975function getSupportedPropertyName(property) { 976 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 977 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 978 979 for (var i = 0; i < prefixes.length; i++) { 980 var prefix = prefixes[i]; 981 var toCheck = prefix ? '' + prefix + upperProp : property; 982 if (typeof document.body.style[toCheck] !== 'undefined') { 983 return toCheck; 984 } 985 } 986 return null; 987} 988 989/** 990 * Destroys the popper. 991 * @method 992 * @memberof Popper 993 */ 994function destroy() { 995 this.state.isDestroyed = true; 996 997 // touch DOM only if `applyStyle` modifier is enabled 998 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 999 this.popper.removeAttribute('x-placement'); 1000 this.popper.style.position = ''; 1001 this.popper.style.top = ''; 1002 this.popper.style.left = ''; 1003 this.popper.style.right = ''; 1004 this.popper.style.bottom = ''; 1005 this.popper.style.willChange = ''; 1006 this.popper.style[getSupportedPropertyName('transform')] = ''; 1007 } 1008 1009 this.disableEventListeners(); 1010 1011 // remove the popper if user explicit
vendor: 15,762 bytes, lines 1011-1460
1011y asked for the deletion on destroy 1012 // do not use `remove` because IE11 doesn't support it 1013 if (this.options.removeOnDestroy) { 1014 this.popper.parentNode.removeChild(this.popper); 1015 } 1016 return this; 1017} 1018 1019/** 1020 * Get the window associated with the element 1021 * @argument {Element} element 1022 * @returns {Window} 1023 */ 1024function getWindow(element) { 1025 var ownerDocument = element.ownerDocument; 1026 return ownerDocument ? ownerDocument.defaultView : window; 1027} 1028 1029function attachToScrollParents(scrollParent, event, callback, scrollParents) { 1030 var isBody = scrollParent.nodeName === 'BODY'; 1031 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 1032 target.addEventListener(event, callback, { passive: true }); 1033 1034 if (!isBody) { 1035 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 1036 } 1037 scrollParents.push(target); 1038} 1039 1040/** 1041 * Setup needed event listeners used to update the popper position 1042 * @method 1043 * @memberof Popper.Utils 1044 * @private 1045 */ 1046function setupEventListeners(reference, options, state, updateBound) { 1047 // Resize event listener on window 1048 state.updateBound = updateBound; 1049 getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 1050 1051 // Scroll event listener on scroll parents 1052 var scrollElement = getScrollParent(reference); 1053 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 1054 state.scrollElement = scrollElement; 1055 state.eventsEnabled = true; 1056 1057 return state; 1058} 1059 1060/** 1061 * It will add resize/scroll events and start recalculating 1062 * position of the popper element when they are triggered. 1063 * @method 1064 * @memberof Popper 1065 */ 1066function enableEventListeners() { 1067 if (!this.state.eventsEnabled) { 1068 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 1069 } 1070} 1071 1072/** 1073 * Remove event listeners used to update the popper position 1074 * @method 1075 * @memberof Popper.Utils 1076 * @private 1077 */ 1078function removeEventListeners(reference, state) { 1079 // Remove resize event listener on window 1080 getWindow(reference).removeEventListener('resize', state.updateBound); 1081 1082 // Remove scroll event listener on scroll parents 1083 state.scrollParents.forEach(function (target) { 1084 target.removeEventListener('scroll', state.updateBound); 1085 }); 1086 1087 // Reset state 1088 state.updateBound = null; 1089 state.scrollParents = []; 1090 state.scrollElement = null; 1091 state.eventsEnabled = false; 1092 return state; 1093} 1094 1095/** 1096 * It will remove resize/scroll events and won't recalculate popper position 1097 * when they are triggered. It also won't trigger `onUpdate` callback anymore, 1098 * unless you call `update` method manually. 1099 * @method 1100 * @memberof Popper 1101 */ 1102function disableEventListeners() { 1103 if (this.state.eventsEnabled) { 1104 cancelAnimationFrame(this.scheduleUpdate); 1105 this.state = removeEventListeners(this.reference, this.state); 1106 } 1107} 1108 1109/** 1110 * Tells if a given input is a number 1111 * @method 1112 * @memberof Popper.Utils 1113 * @param {*} input to check 1114 * @return {Boolean} 1115 */ 1116function isNumeric(n) { 1117 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 1118} 1119 1120/** 1121 * Set the style to the given popper 1122 * @method 1123 * @memberof Popper.Utils 1124 * @argument {Element} element - Element to apply the style to 1125 * @argument {Object} styles 1126 * Object with a list of properties and values which will be applied to the element 1127 */ 1128function setStyles(element, styles) { 1129 Object.keys(styles).forEach(function (prop) { 1130 var unit = ''; 1131 // add unit if the value is numeric and is one of the following 1132 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 1133 unit = 'px'; 1134 } 1135 element.style[prop] = styles[prop] + unit; 1136 }); 1137} 1138 1139/** 1140 * Set the attributes to the given popper 1141 * @method 1142 * @memberof Popper.Utils 1143 * @argument {Element} element - Element to apply the attributes to 1144 * @argument {Object} styles 1145 * Object with a list of properties and values which will be applied to the element 1146 */ 1147function setAttributes(element, attributes) { 1148 Object.keys(attributes).forEach(function (prop) { 1149 var value = attributes[prop]; 1150 if (value !== false) { 1151 element.setAttribute(prop, attributes[prop]); 1152 } else { 1153 element.removeAttribute(prop); 1154 } 1155 }); 1156} 1157 1158/** 1159 * @function 1160 * @memberof Modifiers 1161 * @argument {Object} data - The data object generated by `update` method 1162 * @argument {Object} data.styles - List of style properties - values to apply to popper element 1163 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 1164 * @argument {Object} options - Modifiers configuration and options 1165 * @returns {Object} The same data object 1166 */ 1167function applyStyle(data) { 1168 // any property present in `data.styles` will be applied to the popper, 1169 // in this way we can make the 3rd party modifiers add custom styles to it 1170 // Be aware, modifiers could override the properties defined in the previous 1171 // lines of this modifier! 1172 setStyles(data.instance.popper, data.styles); 1173 1174 // any property present in `data.attributes` will be applied to the popper, 1175 // they will be set as HTML attributes of the element 1176 setAttributes(data.instance.popper, data.attributes); 1177 1178 // if arrowElement is defined and arrowStyles has some properties 1179 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 1180 setStyles(data.arrowElement, data.arrowStyles); 1181 } 1182 1183 return data; 1184} 1185 1186/** 1187 * Set the x-placement attribute before everything else because it could be used 1188 * to add margins to the popper margins needs to be calculated to get the 1189 * correct popper offsets. 1190 * @method 1191 * @memberof Popper.modifiers 1192 * @param {HTMLElement} reference - The reference element used to position the popper 1193 * @param {HTMLElement} popper - The HTML element used as popper 1194 * @param {Object} options - Popper.js options 1195 */ 1196function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 1197 // compute reference element offsets 1198 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 1199 1200 // compute auto placement, store placement inside the data object, 1201 // modifiers will be able to edit `placement` if needed 1202 // and refer to originalPlacement to know the original value 1203 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 1204 1205 popper.setAttribute('x-placement', placement); 1206 1207 // Apply `position` to popper before anything else because 1208 // without the position applied we can't guarantee correct computations 1209 setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 1210 1211 return options; 1212} 1213 1214/** 1215 * @function 1216 * @memberof Popper.Utils 1217 * @argument {Object} data - The data object generated by `update` method 1218 * @argument {Boolean} shouldRound - If the offsets should be rounded at all 1219 * @returns {Object} The popper's position offsets rounded 1220 * 1221 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as 1222 * good as it can be within reason. 1223 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 1224 * 1225 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari 1226 * as well on High DPI screens). 1227 * 1228 * Firefox prefers no rounding for positioning and does not have blurriness on 1229 * high DPI screens. 1230 * 1231 * Only horizontal placement and left/right values need to be considered. 1232 */ 1233function getRoundedOffsets(data, shouldRound) { 1234 var _data$offsets = data.offsets, 1235 popper = _data$offsets.popper, 1236 reference = _data$offsets.reference; 1237 var round = Math.round, 1238 floor = Math.floor; 1239 1240 var noRound = function noRound(v) { 1241 return v; 1242 }; 1243 1244 var referenceWidth = round(reference.width); 1245 var popperWidth = round(popper.width); 1246 1247 var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; 1248 var isVariation = data.placement.indexOf('-') !== -1; 1249 var sameWidthParity = referenceWidth % 2 === popperWidth % 2; 1250 var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; 1251 1252 var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; 1253 var verticalToInteger = !shouldRound ? noRound : round; 1254 1255 return { 1256 left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), 1257 top: verticalToInteger(popper.top), 1258 bottom: verticalToInteger(popper.bottom), 1259 right: horizontalToInteger(popper.right) 1260 }; 1261} 1262 1263var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); 1264 1265/** 1266 * @function 1267 * @memberof Modifiers 1268 * @argument {Object} data - The data object generated by `update` method 1269 * @argument {Object} options - Modifiers configuration and options 1270 * @returns {Object} The data object, properly modified 1271 */ 1272function computeStyle(data, options) { 1273 var x = options.x, 1274 y = options.y; 1275 var popper = data.offsets.popper; 1276 1277 // Remove this legacy support in Popper.js v2 1278 1279 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 1280 return modifier.name === 'applyStyle'; 1281 }).gpuAcceleration; 1282 if (legacyGpuAccelerationOption !== undefined) { 1283 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 1284 } 1285 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 1286 1287 var offsetParent = getOffsetParent(data.instance.popper); 1288 var offsetParentRect = getBoundingClientRect(offsetParent); 1289 1290 // Styles 1291 var styles = { 1292 position: popper.position 1293 }; 1294 1295 var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); 1296 1297 var sideA = x === 'bottom' ? 'top' : 'bottom'; 1298 var sideB = y === 'right' ? 'left' : 'right'; 1299 1300 // if gpuAcceleration is set to `true` and transform is supported, 1301 // we use `translate3d` to apply the position to the popper we 1302 // automatically use the supported prefixed version if needed 1303 var prefixedProperty = getSupportedPropertyName('transform'); 1304 1305 // now, let's make a step back and look at this code closely (wtf?) 1306 // If the content of the popper grows once it's been positioned, it 1307 // may happen that the popper gets misplaced because of the new content 1308 // overflowing its reference element 1309 // To avoid this problem, we provide two options (x and y), which allow 1310 // the consumer to define the offset origin. 1311 // If we position a popper on top of a reference element, we can set 1312 // `x` to `top` to make the popper grow towards its top instead of 1313 // its bottom. 1314 var left = void 0, 1315 top = void 0; 1316 if (sideA === 'bottom') { 1317 // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar) 1318 // and not the bottom of the html element 1319 if (offsetParent.nodeName === 'HTML') { 1320 top = -offsetParent.clientHeight + offsets.bottom; 1321 } else { 1322 top = -offsetParentRect.height + offsets.bottom; 1323 } 1324 } else { 1325 top = offsets.top; 1326 } 1327 if (sideB === 'right') { 1328 if (offsetParent.nodeName === 'HTML') { 1329 left = -offsetParent.clientWidth + offsets.right; 1330 } else { 1331 left = -offsetParentRect.width + offsets.right; 1332 } 1333 } else { 1334 left = offsets.left; 1335 } 1336 if (gpuAcceleration && prefixedProperty) { 1337 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 1338 styles[sideA] = 0; 1339 styles[sideB] = 0; 1340 styles.willChange = 'transform'; 1341 } else { 1342 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 1343 var invertTop = sideA === 'bottom' ? -1 : 1; 1344 var invertLeft = sideB === 'right' ? -1 : 1; 1345 styles[sideA] = top * invertTop; 1346 styles[sideB] = left * invertLeft; 1347 styles.willChange = sideA + ', ' + sideB; 1348 } 1349 1350 // Attributes 1351 var attributes = { 1352 'x-placement': data.placement 1353 }; 1354 1355 // Update `data` attributes, styles and arrowStyles 1356 data.attributes = _extends({}, attributes, data.attributes); 1357 data.styles = _extends({}, styles, data.styles); 1358 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 1359 1360 return data; 1361} 1362 1363/** 1364 * Helper used to know if the given modifier depends from another one.<br /> 1365 * It checks if the needed modifier is listed and enabled. 1366 * @method 1367 * @memberof Popper.Utils 1368 * @param {Array} modifiers - list of modifiers 1369 * @param {String} requestingName - name of requesting modifier 1370 * @param {String} requestedName - name of requested modifier 1371 * @returns {Boolean} 1372 */ 1373function isModifierRequired(modifiers, requestingName, requestedName) { 1374 var requesting = find(modifiers, function (_ref) { 1375 var name = _ref.name; 1376 return name === requestingName; 1377 }); 1378 1379 var isRequired = !!requesting && modifiers.some(function (modifier) { 1380 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 1381 }); 1382 1383 if (!isRequired) { 1384 var _requesting = '`' + requestingName + '`'; 1385 var requested = '`' + requestedName + '`'; 1386 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 1387 } 1388 return isRequired; 1389} 1390 1391/** 1392 * @function 1393 * @memberof Modifiers 1394 * @argument {Object} data - The data object generated by update method 1395 * @argument {Object} options - Modifiers configuration and options 1396 * @returns {Object} The data object, properly modified 1397 */ 1398function arrow(data, options) { 1399 var _data$offsets$arrow; 1400 1401 // arrow depends on keepTogether in order to work 1402 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 1403 return data; 1404 } 1405 1406 var arrowElement = options.element; 1407 1408 // if arrowElement is a string, suppose it's a CSS selector 1409 if (typeof arrowElement === 'string') { 1410 arrowElement = data.instance.popper.querySelector(arrowElement); 1411 1412 // if arrowElement is not found, don't run the modifier 1413 if (!arrowElement) { 1414 return data; 1415 } 1416 } else { 1417 // if the arrowElement isn't a query selector we must check that the 1418 // provided DOM node is child of its popper node 1419 if (!data.instance.popper.contains(arrowElement)) { 1420 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 1421 return data; 1422 } 1423 } 1424 1425 var placement = data.placement.split('-')[0]; 1426 var _data$offsets = data.offsets, 1427 popper = _data$offsets.popper, 1428 reference = _data$offsets.reference; 1429 1430 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 1431 1432 var len = isVertical ? 'height' : 'width'; 1433 var sideCapitalized = isVertical ? 'Top' : 'Left'; 1434 var side = sideCapitalized.toLowerCase(); 1435 var altSide = isVertical ? 'left' : 'top'; 1436 var opSide = isVertical ? 'bottom' : 'right'; 1437 var arrowElementSize = getOuterSizes(arrowElement)[len]; 1438 1439 // 1440 // extends keepTogether behavior making sure the popper and its 1441 // reference have enough pixels in conjunction 1442 // 1443 1444 // top/left side 1445 if (reference[opSide] - arrowElementSize < popper[side]) { 1446 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 1447 } 1448 // bottom/right side 1449 if (reference[side] + arrowElementSize > popper[opSide]) { 1450 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 1451 } 1452 data.offsets.popper = getClientRect(data.offsets.popper); 1453 1454 // compute center of the popper 1455 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 1456 1457 // Compute the sideValue using the updated popper offsets 1458 // take popper margin in account because we don't have this info available 1459 var css = getStyleComputedProperty(data.instance.popper); 1460 var popperMarginSide = parseFloat(css['margin' + sideCapitalized]
1460, 10); 1461 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10
vendor: 21,597 bytes, lines 1461-2071
1461); 1462 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 1463 1464 // prevent arrowElement from being placed not contiguously to its popper 1465 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 1466 1467 data.arrowElement = arrowElement; 1468 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 1469 1470 return data; 1471} 1472 1473/** 1474 * Get the opposite placement variation of the given one 1475 * @method 1476 * @memberof Popper.Utils 1477 * @argument {String} placement variation 1478 * @returns {String} flipped placement variation 1479 */ 1480function getOppositeVariation(variation) { 1481 if (variation === 'end') { 1482 return 'start'; 1483 } else if (variation === 'start') { 1484 return 'end'; 1485 } 1486 return variation; 1487} 1488 1489/** 1490 * List of accepted placements to use as values of the `placement` option.<br /> 1491 * Valid placements are: 1492 * - `auto` 1493 * - `top` 1494 * - `right` 1495 * - `bottom` 1496 * - `left` 1497 * 1498 * Each placement can have a variation from this list: 1499 * - `-start` 1500 * - `-end` 1501 * 1502 * Variations are interpreted easily if you think of them as the left to right 1503 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 1504 * is right.<br /> 1505 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 1506 * 1507 * Some valid examples are: 1508 * - `top-end` (on top of reference, right aligned) 1509 * - `right-start` (on right of reference, top aligned) 1510 * - `bottom` (on bottom, centered) 1511 * - `auto-end` (on the side with more space available, alignment depends by placement) 1512 * 1513 * @static 1514 * @type {Array} 1515 * @enum {String} 1516 * @readonly 1517 * @method placements 1518 * @memberof Popper 1519 */ 1520var 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']; 1521 1522// Get rid of `auto` `auto-start` and `auto-end` 1523var validPlacements = placements.slice(3); 1524 1525/** 1526 * Given an initial placement, returns all the subsequent placements 1527 * clockwise (or counter-clockwise). 1528 * 1529 * @method 1530 * @memberof Popper.Utils 1531 * @argument {String} placement - A valid placement (it accepts variations) 1532 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 1533 * @returns {Array} placements including their variations 1534 */ 1535function clockwise(placement) { 1536 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 1537 1538 var index = validPlacements.indexOf(placement); 1539 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 1540 return counter ? arr.reverse() : arr; 1541} 1542 1543var BEHAVIORS = { 1544 FLIP: 'flip', 1545 CLOCKWISE: 'clockwise', 1546 COUNTERCLOCKWISE: 'counterclockwise' 1547}; 1548 1549/** 1550 * @function 1551 * @memberof Modifiers 1552 * @argument {Object} data - The data object generated by update method 1553 * @argument {Object} options - Modifiers configuration and options 1554 * @returns {Object} The data object, properly modified 1555 */ 1556function flip(data, options) { 1557 // if `inner` modifier is enabled, we can't use the `flip` modifier 1558 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 1559 return data; 1560 } 1561 1562 if (data.flipped && data.placement === data.originalPlacement) { 1563 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 1564 return data; 1565 } 1566 1567 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 1568 1569 var placement = data.placement.split('-')[0]; 1570 var placementOpposite = getOppositePlacement(placement); 1571 var variation = data.placement.split('-')[1] || ''; 1572 1573 var flipOrder = []; 1574 1575 switch (options.behavior) { 1576 case BEHAVIORS.FLIP: 1577 flipOrder = [placement, placementOpposite]; 1578 break; 1579 case BEHAVIORS.CLOCKWISE: 1580 flipOrder = clockwise(placement); 1581 break; 1582 case BEHAVIORS.COUNTERCLOCKWISE: 1583 flipOrder = clockwise(placement, true); 1584 break; 1585 default: 1586 flipOrder = options.behavior; 1587 } 1588 1589 flipOrder.forEach(function (step, index) { 1590 if (placement !== step || flipOrder.length === index + 1) { 1591 return data; 1592 } 1593 1594 placement = data.placement.split('-')[0]; 1595 placementOpposite = getOppositePlacement(placement); 1596 1597 var popperOffsets = data.offsets.popper; 1598 var refOffsets = data.offsets.reference; 1599 1600 // using floor because the reference offsets may contain decimals we are not going to consider here 1601 var floor = Math.floor; 1602 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); 1603 1604 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 1605 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 1606 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 1607 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 1608 1609 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 1610 1611 // flip the variation if required 1612 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1613 1614 // flips variation if reference element overflows boundaries 1615 var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 1616 1617 // flips variation if popper content overflows boundaries 1618 var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); 1619 1620 var flippedVariation = flippedVariationByRef || flippedVariationByContent; 1621 1622 if (overlapsRef || overflowsBoundaries || flippedVariation) { 1623 // this boolean to detect any flip loop 1624 data.flipped = true; 1625 1626 if (overlapsRef || overflowsBoundaries) { 1627 placement = flipOrder[index + 1]; 1628 } 1629 1630 if (flippedVariation) { 1631 variation = getOppositeVariation(variation); 1632 } 1633 1634 data.placement = placement + (variation ? '-' + variation : ''); 1635 1636 // this object contains `position`, we want to preserve it along with 1637 // any additional property we may add in the future 1638 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 1639 1640 data = runModifiers(data.instance.modifiers, data, 'flip'); 1641 } 1642 }); 1643 return data; 1644} 1645 1646/** 1647 * @function 1648 * @memberof Modifiers 1649 * @argument {Object} data - The data object generated by update method 1650 * @argument {Object} options - Modifiers configuration and options 1651 * @returns {Object} The data object, properly modified 1652 */ 1653function keepTogether(data) { 1654 var _data$offsets = data.offsets, 1655 popper = _data$offsets.popper, 1656 reference = _data$offsets.reference; 1657 1658 var placement = data.placement.split('-')[0]; 1659 var floor = Math.floor; 1660 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1661 var side = isVertical ? 'right' : 'bottom'; 1662 var opSide = isVertical ? 'left' : 'top'; 1663 var measurement = isVertical ? 'width' : 'height'; 1664 1665 if (popper[side] < floor(reference[opSide])) { 1666 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 1667 } 1668 if (popper[opSide] > floor(reference[side])) { 1669 data.offsets.popper[opSide] = floor(reference[side]); 1670 } 1671 1672 return data; 1673} 1674 1675/** 1676 * Converts a string containing value + unit into a px value number 1677 * @function 1678 * @memberof {modifiers~offset} 1679 * @private 1680 * @argument {String} str - Value + unit string 1681 * @argument {String} measurement - `height` or `width` 1682 * @argument {Object} popperOffsets 1683 * @argument {Object} referenceOffsets 1684 * @returns {Number|String} 1685 * Value in pixels, or original string if no values were extracted 1686 */ 1687function toValue(str, measurement, popperOffsets, referenceOffsets) { 1688 // separate value from unit 1689 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 1690 var value = +split[1]; 1691 var unit = split[2]; 1692 1693 // If it's not a number it's an operator, I guess 1694 if (!value) { 1695 return str; 1696 } 1697 1698 if (unit.indexOf('%') === 0) { 1699 var element = void 0; 1700 switch (unit) { 1701 case '%p': 1702 element = popperOffsets; 1703 break; 1704 case '%': 1705 case '%r': 1706 default: 1707 element = referenceOffsets; 1708 } 1709 1710 var rect = getClientRect(element); 1711 return rect[measurement] / 100 * value; 1712 } else if (unit === 'vh' || unit === 'vw') { 1713 // if is a vh or vw, we calculate the size based on the viewport 1714 var size = void 0; 1715 if (unit === 'vh') { 1716 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 1717 } else { 1718 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 1719 } 1720 return size / 100 * value; 1721 } else { 1722 // if is an explicit pixel unit, we get rid of the unit and keep the value 1723 // if is an implicit unit, it's px, and we return just the value 1724 return value; 1725 } 1726} 1727 1728/** 1729 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 1730 * @function 1731 * @memberof {modifiers~offset} 1732 * @private 1733 * @argument {String} offset 1734 * @argument {Object} popperOffsets 1735 * @argument {Object} referenceOffsets 1736 * @argument {String} basePlacement 1737 * @returns {Array} a two cells array with x and y offsets in numbers 1738 */ 1739function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 1740 var offsets = [0, 0]; 1741 1742 // Use height if placement is left or right and index is 0 otherwise use width 1743 // in this way the first offset will use an axis and the second one 1744 // will use the other one 1745 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 1746 1747 // Split the offset string to obtain a list of values and operands 1748 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 1749 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 1750 return frag.trim(); 1751 }); 1752 1753 // Detect if the offset string contains a pair of values or a single one 1754 // they could be separated by comma or space 1755 var divider = fragments.indexOf(find(fragments, function (frag) { 1756 return frag.search(/,|\s/) !== -1; 1757 })); 1758 1759 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 1760 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 1761 } 1762 1763 // If divider is found, we divide the list of values and operands to divide 1764 // them by ofset X and Y. 1765 var splitRegex = /\s*,\s*|\s+/; 1766 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]; 1767 1768 // Convert the values with units to absolute pixels to allow our computations 1769 ops = ops.map(function (op, index) { 1770 // Most of the units rely on the orientation of the popper 1771 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 1772 var mergeWithPrevious = false; 1773 return op 1774 // This aggregates any `+` or `-` sign that aren't considered operators 1775 // e.g.: 10 + +5 => [10, +, +5] 1776 .reduce(function (a, b) { 1777 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 1778 a[a.length - 1] = b; 1779 mergeWithPrevious = true; 1780 return a; 1781 } else if (mergeWithPrevious) { 1782 a[a.length - 1] += b; 1783 mergeWithPrevious = false; 1784 return a; 1785 } else { 1786 return a.concat(b); 1787 } 1788 }, []) 1789 // Here we convert the string values into number values (in px) 1790 .map(function (str) { 1791 return toValue(str, measurement, popperOffsets, referenceOffsets); 1792 }); 1793 }); 1794 1795 // Loop trough the offsets arrays and execute the operations 1796 ops.forEach(function (op, index) { 1797 op.forEach(function (frag, index2) { 1798 if (isNumeric(frag)) { 1799 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 1800 } 1801 }); 1802 }); 1803 return offsets; 1804} 1805 1806/** 1807 * @function 1808 * @memberof Modifiers 1809 * @argument {Object} data - The data object generated by update method 1810 * @argument {Object} options - Modifiers configuration and options 1811 * @argument {Number|String} options.offset=0 1812 * The offset value as described in the modifier description 1813 * @returns {Object} The data object, properly modified 1814 */ 1815function offset(data, _ref) { 1816 var offset = _ref.offset; 1817 var placement = data.placement, 1818 _data$offsets = data.offsets, 1819 popper = _data$offsets.popper, 1820 reference = _data$offsets.reference; 1821 1822 var basePlacement = placement.split('-')[0]; 1823 1824 var offsets = void 0; 1825 if (isNumeric(+offset)) { 1826 offsets = [+offset, 0]; 1827 } else { 1828 offsets = parseOffset(offset, popper, reference, basePlacement); 1829 } 1830 1831 if (basePlacement === 'left') { 1832 popper.top += offsets[0]; 1833 popper.left -= offsets[1]; 1834 } else if (basePlacement === 'right') { 1835 popper.top += offsets[0]; 1836 popper.left += offsets[1]; 1837 } else if (basePlacement === 'top') { 1838 popper.left += offsets[0]; 1839 popper.top -= offsets[1]; 1840 } else if (basePlacement === 'bottom') { 1841 popper.left += offsets[0]; 1842 popper.top += offsets[1]; 1843 } 1844 1845 data.popper = popper; 1846 return data; 1847} 1848 1849/** 1850 * @function 1851 * @memberof Modifiers 1852 * @argument {Object} data - The data object generated by `update` method 1853 * @argument {Object} options - Modifiers configuration and options 1854 * @returns {Object} The data object, properly modified 1855 */ 1856function preventOverflow(data, options) { 1857 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 1858 1859 // If offsetParent is the reference element, we really want to 1860 // go one step up and use the next offsetParent as reference to 1861 // avoid to make this modifier completely useless and look like broken 1862 if (data.instance.reference === boundariesElement) { 1863 boundariesElement = getOffsetParent(boundariesElement); 1864 } 1865 1866 // NOTE: DOM access here 1867 // resets the popper's position so that the document size can be calculated excluding 1868 // the size of the popper element itself 1869 var transformProp = getSupportedPropertyName('transform'); 1870 var popperStyles = data.instance.popper.style; // assignment to help minification 1871 var top = popperStyles.top, 1872 left = popperStyles.left, 1873 transform = popperStyles[transformProp]; 1874 1875 popperStyles.top = ''; 1876 popperStyles.left = ''; 1877 popperStyles[transformProp] = ''; 1878 1879 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 1880 1881 // NOTE: DOM access here 1882 // restores the original style properties after the offsets have been computed 1883 popperStyles.top = top; 1884 popperStyles.left = left; 1885 popperStyles[transformProp] = transform; 1886 1887 options.boundaries = boundaries; 1888 1889 var order = options.priority; 1890 var popper = data.offsets.popper; 1891 1892 var check = { 1893 primary: function primary(placement) { 1894 var value = popper[placement]; 1895 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 1896 value = Math.max(popper[placement], boundaries[placement]); 1897 } 1898 return defineProperty({}, placement, value); 1899 }, 1900 secondary: function secondary(placement) { 1901 var mainSide = placement === 'right' ? 'left' : 'top'; 1902 var value = popper[mainSide]; 1903 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 1904 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 1905 } 1906 return defineProperty({}, mainSide, value); 1907 } 1908 }; 1909 1910 order.forEach(function (placement) { 1911 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 1912 popper = _extends({}, popper, check[side](placement)); 1913 }); 1914 1915 data.offsets.popper = popper; 1916 1917 return data; 1918} 1919 1920/** 1921 * @function 1922 * @memberof Modifiers 1923 * @argument {Object} data - The data object generated by `update` method 1924 * @argument {Object} options - Modifiers configuration and options 1925 * @returns {Object} The data object, properly modified 1926 */ 1927function shift(data) { 1928 var placement = data.placement; 1929 var basePlacement = placement.split('-')[0]; 1930 var shiftvariation = placement.split('-')[1]; 1931 1932 // if shift shiftvariation is specified, run the modifier 1933 if (shiftvariation) { 1934 var _data$offsets = data.offsets, 1935 reference = _data$offsets.reference, 1936 popper = _data$offsets.popper; 1937 1938 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 1939 var side = isVertical ? 'left' : 'top'; 1940 var measurement = isVertical ? 'width' : 'height'; 1941 1942 var shiftOffsets = { 1943 start: defineProperty({}, side, reference[side]), 1944 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 1945 }; 1946 1947 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 1948 } 1949 1950 return data; 1951} 1952 1953/** 1954 * @function 1955 * @memberof Modifiers 1956 * @argument {Object} data - The data object generated by update method 1957 * @argument {Object} options - Modifiers configuration and options 1958 * @returns {Object} The data object, properly modified 1959 */ 1960function hide(data) { 1961 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 1962 return data; 1963 } 1964 1965 var refRect = data.offsets.reference; 1966 var bound = find(data.instance.modifiers, function (modifier) { 1967 return modifier.name === 'preventOverflow'; 1968 }).boundaries; 1969 1970 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 1971 // Avoid unnecessary DOM access if visibility hasn't changed 1972 if (data.hide === true) { 1973 return data; 1974 } 1975 1976 data.hide = true; 1977 data.attributes['x-out-of-boundaries'] = ''; 1978 } else { 1979 // Avoid unnecessary DOM access if visibility hasn't changed 1980 if (data.hide === false) { 1981 return data; 1982 } 1983 1984 data.hide = false; 1985 data.attributes['x-out-of-boundaries'] = false; 1986 } 1987 1988 return data; 1989} 1990 1991/** 1992 * @function 1993 * @memberof Modifiers 1994 * @argument {Object} data - The data object generated by `update` method 1995 * @argument {Object} options - Modifiers configuration and options 1996 * @returns {Object} The data object, properly modified 1997 */ 1998function inner(data) { 1999 var placement = data.placement; 2000 var basePlacement = placement.split('-')[0]; 2001 var _data$offsets = data.offsets, 2002 popper = _data$offsets.popper, 2003 reference = _data$offsets.reference; 2004 2005 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 2006 2007 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 2008 2009 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 2010 2011 data.placement = getOppositePlacement(placement); 2012 data.offsets.popper = getClientRect(popper); 2013 2014 return data; 2015} 2016 2017/** 2018 * Modifier function, each modifier can have a function of this type assigned 2019 * to its `fn` property.<br /> 2020 * These functions will be called on each update, this means that you must 2021 * make sure they are performant enough to avoid performance bottlenecks. 2022 * 2023 * @function ModifierFn 2024 * @argument {dataObject} data - The data object generated by `update` method 2025 * @argument {Object} options - Modifiers configuration and options 2026 * @returns {dataObject} The data object, properly modified 2027 */ 2028 2029/** 2030 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 2031 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 2032 * needed by the library. 2033 * 2034 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 2035 * All the other properties are configurations that could be tweaked. 2036 * @namespace modifiers 2037 */ 2038var modifiers = { 2039 /** 2040 * Modifier used to shift the popper on the start or end of its reference 2041 * element.<br /> 2042 * It will read the variation of the `placement` property.<br /> 2043 * It can be one either `-end` or `-start`. 2044 * @memberof modifiers 2045 * @inner 2046 */ 2047 shift: { 2048 /** @prop {number} order=100 - Index used to define the order of execution */ 2049 order: 100, 2050 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2051 enabled: true, 2052 /** @prop {ModifierFn} */ 2053 fn: shift 2054 }, 2055 2056 /** 2057 * The `offset` modifier can shift your popper on both its axis. 2058 * 2059 * It accepts the following units: 2060 * - `px` or unit-less, interpreted as pixels 2061 * - `%` or `%r`, percentage relative to the length of the reference element 2062 * - `%p`, percentage relative to the length of the popper element 2063 * - `vw`, CSS viewport width unit 2064 * - `vh`, CSS viewport height unit 2065 * 2066 * For length is intended the main axis relative to the placement of the popper.<br /> 2067 * This means that if the placement is `top` or `bottom`, the length will be the 2068 * `width`. In case of `left` or `right`, it will be the `height`. 2069 * 2070 * You can provide a single value (as `Number` or `String`), or a pair of values 2071 * as `String` divided by a comma or one (or more) white space
vendor: 9,957 bytes, lines 2071-2343
2071s.<br /> 2072 * The latter is a deprecated method because it leads to confusion and will be 2073 * removed in v2.<br /> 2074 * Additionally, it accepts additions and subtractions between different units. 2075 * Note that multiplications and divisions aren't supported. 2076 * 2077 * Valid examples are: 2078 * ``` 2079 * 10 2080 * '10%' 2081 * '10, 10' 2082 * '10%, 10' 2083 * '10 + 10%' 2084 * '10 - 5vh + 3%' 2085 * '-10px + 5vh, 5px - 6%' 2086 * ``` 2087 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 2088 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 2089 * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). 2090 * 2091 * @memberof modifiers 2092 * @inner 2093 */ 2094 offset: { 2095 /** @prop {number} order=200 - Index used to define the order of execution */ 2096 order: 200, 2097 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2098 enabled: true, 2099 /** @prop {ModifierFn} */ 2100 fn: offset, 2101 /** @prop {Number|String} offset=0 2102 * The offset value as described in the modifier description 2103 */ 2104 offset: 0 2105 }, 2106 2107 /** 2108 * Modifier used to prevent the popper from being positioned outside the boundary. 2109 * 2110 * A scenario exists where the reference itself is not within the boundaries.<br /> 2111 * We can say it has "escaped the boundaries" â or just "escaped".<br /> 2112 * In this case we need to decide whether the popper should either: 2113 * 2114 * - detach from the reference and remain "trapped" in the boundaries, or 2115 * - if it should ignore the boundary and "escape with its reference" 2116 * 2117 * When `escapeWithReference` is set to`true` and reference is completely 2118 * outside its boundaries, the popper will overflow (or completely leave) 2119 * the boundaries in order to remain attached to the edge of the reference. 2120 * 2121 * @memberof modifiers 2122 * @inner 2123 */ 2124 preventOverflow: { 2125 /** @prop {number} order=300 - Index used to define the order of execution */ 2126 order: 300, 2127 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2128 enabled: true, 2129 /** @prop {ModifierFn} */ 2130 fn: preventOverflow, 2131 /** 2132 * @prop {Array} [priority=['left','right','top','bottom']] 2133 * Popper will try to prevent overflow following these priorities by default, 2134 * then, it could overflow on the left and on top of the `boundariesElement` 2135 */ 2136 priority: ['left', 'right', 'top', 'bottom'], 2137 /** 2138 * @prop {number} padding=5 2139 * Amount of pixel used to define a minimum distance between the boundaries 2140 * and the popper. This makes sure the popper always has a little padding 2141 * between the edges of its container 2142 */ 2143 padding: 5, 2144 /** 2145 * @prop {String|HTMLElement} boundariesElement='scrollParent' 2146 * Boundaries used by the modifier. Can be `scrollParent`, `window`, 2147 * `viewport` or any DOM element. 2148 */ 2149 boundariesElement: 'scrollParent' 2150 }, 2151 2152 /** 2153 * Modifier used to make sure the reference and its popper stay near each other 2154 * without leaving any gap between the two. Especially useful when the arrow is 2155 * enabled and you want to ensure that it points to its reference element. 2156 * It cares only about the first axis. You can still have poppers with margin 2157 * between the popper and its reference element. 2158 * @memberof modifiers 2159 * @inner 2160 */ 2161 keepTogether: { 2162 /** @prop {number} order=400 - Index used to define the order of execution */ 2163 order: 400, 2164 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2165 enabled: true, 2166 /** @prop {ModifierFn} */ 2167 fn: keepTogether 2168 }, 2169 2170 /** 2171 * This modifier is used to move the `arrowElement` of the popper to make 2172 * sure it is positioned between the reference element and its popper element. 2173 * It will read the outer size of the `arrowElement` node to detect how many 2174 * pixels of conjunction are needed. 2175 * 2176 * It has no effect if no `arrowElement` is provided. 2177 * @memberof modifiers 2178 * @inner 2179 */ 2180 arrow: { 2181 /** @prop {number} order=500 - Index used to define the order of execution */ 2182 order: 500, 2183 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2184 enabled: true, 2185 /** @prop {ModifierFn} */ 2186 fn: arrow, 2187 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 2188 element: '[x-arrow]' 2189 }, 2190 2191 /** 2192 * Modifier used to flip the popper's placement when it starts to overlap its 2193 * reference element. 2194 * 2195 * Requires the `preventOverflow` modifier before it in order to work. 2196 * 2197 * **NOTE:** this modifier will interrupt the current update cycle and will 2198 * restart it if it detects the need to flip the placement. 2199 * @memberof modifiers 2200 * @inner 2201 */ 2202 flip: { 2203 /** @prop {number} order=600 - Index used to define the order of execution */ 2204 order: 600, 2205 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2206 enabled: true, 2207 /** @prop {ModifierFn} */ 2208 fn: flip, 2209 /** 2210 * @prop {String|Array} behavior='flip' 2211 * The behavior used to change the popper's placement. It can be one of 2212 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 2213 * placements (with optional variations) 2214 */ 2215 behavior: 'flip', 2216 /** 2217 * @prop {number} padding=5 2218 * The popper will flip if it hits the edges of the `boundariesElement` 2219 */ 2220 padding: 5, 2221 /** 2222 * @prop {String|HTMLElement} boundariesElement='viewport' 2223 * The element which will define the boundaries of the popper position. 2224 * The popper will never be placed outside of the defined boundaries 2225 * (except if `keepTogether` is enabled) 2226 */ 2227 boundariesElement: 'viewport', 2228 /** 2229 * @prop {Boolean} flipVariations=false 2230 * The popper will switch placement variation between `-start` and `-end` when 2231 * the reference element overlaps its boundaries. 2232 * 2233 * The original placement should have a set variation. 2234 */ 2235 flipVariations: false, 2236 /** 2237 * @prop {Boolean} flipVariationsByContent=false 2238 * The popper will switch placement variation between `-start` and `-end` when 2239 * the popper element overlaps its reference boundaries. 2240 * 2241 * The original placement should have a set variation. 2242 */ 2243 flipVariationsByContent: false 2244 }, 2245 2246 /** 2247 * Modifier used to make the popper flow toward the inner of the reference element. 2248 * By default, when this modifier is disabled, the popper will be placed outside 2249 * the reference element. 2250 * @memberof modifiers 2251 * @inner 2252 */ 2253 inner: { 2254 /** @prop {number} order=700 - Index used to define the order of execution */ 2255 order: 700, 2256 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 2257 enabled: false, 2258 /** @prop {ModifierFn} */ 2259 fn: inner 2260 }, 2261 2262 /** 2263 * Modifier used to hide the popper when its reference element is outside of the 2264 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 2265 * be used to hide with a CSS selector the popper when its reference is 2266 * out of boundaries. 2267 * 2268 * Requires the `preventOverflow` modifier before it in order to work. 2269 * @memberof modifiers 2270 * @inner 2271 */ 2272 hide: { 2273 /** @prop {number} order=800 - Index used to define the order of execution */ 2274 order: 800, 2275 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2276 enabled: true, 2277 /** @prop {ModifierFn} */ 2278 fn: hide 2279 }, 2280 2281 /** 2282 * Computes the style that will be applied to the popper element to gets 2283 * properly positioned. 2284 * 2285 * Note that this modifier will not touch the DOM, it just prepares the styles 2286 * so that `applyStyle` modifier can apply it. This separation is useful 2287 * in case you need to replace `applyStyle` with a custom implementation. 2288 * 2289 * This modifier has `850` as `order` value to maintain backward compatibility 2290 * with previous versions of Popper.js. Expect the modifiers ordering method 2291 * to change in future major versions of the library. 2292 * 2293 * @memberof modifiers 2294 * @inner 2295 */ 2296 computeStyle: { 2297 /** @prop {number} order=850 - Index used to define the order of execution */ 2298 order: 850, 2299 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2300 enabled: true, 2301 /** @prop {ModifierFn} */ 2302 fn: computeStyle, 2303 /** 2304 * @prop {Boolean} gpuAcceleration=true 2305 * If true, it uses the CSS 3D transformation to position the popper. 2306 * Otherwise, it will use the `top` and `left` properties 2307 */ 2308 gpuAcceleration: true, 2309 /** 2310 * @prop {string} [x='bottom'] 2311 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 2312 * Change this if your popper should grow in a direction different from `bottom` 2313 */ 2314 x: 'bottom', 2315 /** 2316 * @prop {string} [x='left'] 2317 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 2318 * Change this if your popper should grow in a direction different from `right` 2319 */ 2320 y: 'right' 2321 }, 2322 2323 /** 2324 * Applies the computed styles to the popper element. 2325 * 2326 * All the DOM manipulations are limited to this modifier. This is useful in case 2327 * you want to integrate Popper.js inside a framework or view library and you 2328 * want to delegate all the DOM manipulations to it. 2329 * 2330 * Note that if you disable this modifier, you must make sure the popper element 2331 * has its position set to `absolute` before Popper.js can do its work! 2332 * 2333 * Just disable this modifier and define your own to achieve the desired effect. 2334 * 2335 * @memberof modifiers 2336 * @inner 2337 */ 2338 applyStyle: { 2339 /** @prop {number} order=900 - Index used to define the order of execution */ 2340 order: 900, 2341 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2342 enabled: true, 2343 /** @prop {ModifierFn} */
vendor: 4,828 bytes, lines 2344-2482
2344 fn: applyStyle, 2345 /** @prop {Function} */ 2346 onLoad: applyStyleOnLoad, 2347 /** 2348 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 2349 * @prop {Boolean} gpuAcceleration=true 2350 * If true, it uses the CSS 3D transformation to position the popper. 2351 * Otherwise, it will use the `top` and `left` properties 2352 */ 2353 gpuAcceleration: undefined 2354 } 2355}; 2356 2357/** 2358 * The `dataObject` is an object containing all the information used by Popper.js. 2359 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 2360 * @name dataObject 2361 * @property {Object} data.instance The Popper.js instance 2362 * @property {String} data.placement Placement applied to popper 2363 * @property {String} data.originalPlacement Placement originally defined on init 2364 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 2365 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper 2366 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 2367 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) 2368 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) 2369 * @property {Object} data.boundaries Offsets of the popper boundaries 2370 * @property {Object} data.offsets The measurements of popper, reference and arrow elements 2371 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 2372 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 2373 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 2374 */ 2375 2376/** 2377 * Default options provided to Popper.js constructor.<br /> 2378 * These can be overridden using the `options` argument of Popper.js.<br /> 2379 * To override an option, simply pass an object with the same 2380 * structure of the `options` object, as the 3rd argument. For example: 2381 * ``` 2382 * new Popper(ref, pop, { 2383 * modifiers: { 2384 * preventOverflow: { enabled: false } 2385 * } 2386 * }) 2387 * ``` 2388 * @type {Object} 2389 * @static 2390 * @memberof Popper 2391 */ 2392var Defaults = { 2393 /** 2394 * Popper's placement. 2395 * @prop {Popper.placements} placement='bottom' 2396 */ 2397 placement: 'bottom', 2398 2399 /** 2400 * Set this to true if you want popper to position it self in 'fixed' mode 2401 * @prop {Boolean} positionFixed=false 2402 */ 2403 positionFixed: false, 2404 2405 /** 2406 * Whether events (resize, scroll) are initially enabled. 2407 * @prop {Boolean} eventsEnabled=true 2408 */ 2409 eventsEnabled: true, 2410 2411 /** 2412 * Set to true if you want to automatically remove the popper when 2413 * you call the `destroy` method. 2414 * @prop {Boolean} removeOnDestroy=false 2415 */ 2416 removeOnDestroy: false, 2417 2418 /** 2419 * Callback called when the popper is created.<br /> 2420 * By default, it is set to no-op.<br /> 2421 * Access Popper.js instance with `data.instance`. 2422 * @prop {onCreate} 2423 */ 2424 onCreate: function onCreate() {}, 2425 2426 /** 2427 * Callback called when the popper is updated. This callback is not called 2428 * on the initialization/creation of the popper, but only on subsequent 2429 * updates.<br /> 2430 * By default, it is set to no-op.<br /> 2431 * Access Popper.js instance with `data.instance`. 2432 * @prop {onUpdate} 2433 */ 2434 onUpdate: function onUpdate() {}, 2435 2436 /** 2437 * List of modifiers used to modify the offsets before they are applied to the popper. 2438 * They provide most of the functionalities of Popper.js. 2439 * @prop {modifiers} 2440 */ 2441 modifiers: modifiers 2442}; 2443 2444/** 2445 * @callback onCreate 2446 * @param {dataObject} data 2447 */ 2448 2449/** 2450 * @callback onUpdate 2451 * @param {dataObject} data 2452 */ 2453 2454// Utils 2455// Methods 2456var Popper = function () { 2457 /** 2458 * Creates a new Popper.js instance. 2459 * @class Popper 2460 * @param {Element|referenceObject} reference - The reference element used to position the popper 2461 * @param {Element} popper - The HTML / XML element used as the popper 2462 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 2463 * @return {Object} instance - The generated Popper.js instance 2464 */ 2465 function Popper(reference, popper) { 2466 var _this = this; 2467 2468 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 2469 classCallCheck(this, Popper); 2470 2471 this.scheduleUpdate = function () { 2472 return requestAnimationFrame(_this.update); 2473 }; 2474 2475 // make update() debounced, so that it only runs at most once-per-tick 2476 this.update = debounce(this.update.bind(this)); 2477 2478 // with {} we create a new object with the options inside it 2479 this.options = _extends({}, Popper.Defaults, options); 2480 2481 // init state 2482 this.state = {
vendor: 4,356 bytes, lines 2483-2612
2483 isDestroyed: false, 2484 isCreated: false, 2485 scrollParents: [] 2486 }; 2487 2488 // get reference and popper elements (allow jQuery wrappers) 2489 this.reference = reference && reference.jquery ? reference[0] : reference; 2490 this.popper = popper && popper.jquery ? popper[0] : popper; 2491 2492 // Deep merge modifiers options 2493 this.options.modifiers = {}; 2494 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 2495 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 2496 }); 2497 2498 // Refactoring modifiers' list (Object => Array) 2499 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 2500 return _extends({ 2501 name: name 2502 }, _this.options.modifiers[name]); 2503 }) 2504 // sort the modifiers by order 2505 .sort(function (a, b) { 2506 return a.order - b.order; 2507 }); 2508 2509 // modifiers have the ability to execute arbitrary code when Popper.js get inited 2510 // such code is executed in the same order of its modifier 2511 // they could add new properties to their options configuration 2512 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 2513 this.modifiers.forEach(function (modifierOptions) { 2514 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 2515 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 2516 } 2517 }); 2518 2519 // fire the first update to position the popper in the right place 2520 this.update(); 2521 2522 var eventsEnabled = this.options.eventsEnabled; 2523 if (eventsEnabled) { 2524 // setup event listeners, they will take care of update the position in specific situations 2525 this.enableEventListeners(); 2526 } 2527 2528 this.state.eventsEnabled = eventsEnabled; 2529 } 2530 2531 // We can't use class properties because they don't get listed in the 2532 // class prototype and break stuff like Sinon stubs 2533 2534 2535 createClass(Popper, [{ 2536 key: 'update', 2537 value: function update$$1() { 2538 return update.call(this); 2539 } 2540 }, { 2541 key: 'destroy', 2542 value: function destroy$$1() { 2543 return destroy.call(this); 2544 } 2545 }, { 2546 key: 'enableEventListeners', 2547 value: function enableEventListeners$$1() { 2548 return enableEventListeners.call(this); 2549 } 2550 }, { 2551 key: 'disableEventListeners', 2552 value: function disableEventListeners$$1() { 2553 return disableEventListeners.call(this); 2554 } 2555 2556 /** 2557 * Schedules an update. It will run on the next UI update available. 2558 * @method scheduleUpdate 2559 * @memberof Popper 2560 */ 2561 2562 2563 /** 2564 * Collection of utilities useful when writing custom modifiers. 2565 * Starting from version 1.7, this method is available only if you 2566 * include `popper-utils.js` before `popper.js`. 2567 * 2568 * **DEPRECATION**: This way to access PopperUtils is deprecated 2569 * and will be removed in v2! Use the PopperUtils module directly instead. 2570 * Due to the high instability of the methods contained in Utils, we can't 2571 * guarantee them to follow semver. Use them at your own risk! 2572 * @static 2573 * @private 2574 * @type {Object} 2575 * @deprecated since version 1.8 2576 * @member Utils 2577 * @memberof Popper 2578 */ 2579 2580 }]); 2581 return Popper; 2582}(); 2583 2584/** 2585 * The `referenceObject` is an object that provides an interface compatible with Popper.js 2586 * and lets you use it as replacement of a real DOM node.<br /> 2587 * You can use this method to position a popper relatively to a set of coordinates 2588 * in case you don't have a DOM node to use as reference. 2589 * 2590 * ``` 2591 * new Popper(referenceObject, popperNode); 2592 * ``` 2593 * 2594 * NB: This feature isn't supported in Internet Explorer 10. 2595 * @name referenceObject 2596 * @property {Function} data.getBoundingClientRect 2597 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 2598 * @property {number} data.clientWidth 2599 * An ES6 getter that will return the width of the virtual reference element. 2600 * @property {number} data.clientHeight 2601 * An ES6 getter that will return the height of the virtual reference element. 2602 */ 2603 2604 2605Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 2606Popper.placements = placements; 2607Popper.Defaults = Defaults; 2608 2609return Popper; 2610 2611}))); 2612//# sourceMappingURL=popper.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.