vendor: 5,940 bytes, lines 1-200
1/**! 2 * @fileOverview Kickass library to create and place poppers near their reference elements. 3 * @version 1.14.5 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} 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
vendor: 2,049 bytes, lines 201-264
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
vendor: 9,592 bytes, lines 265-546
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'], 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 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
vendor: 5,532 bytes, lines 546-714
546); 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; 573 } 574 if (getStyleComputedProperty(element, 'position') === 'fixed') { 575 return true; 576 } 577 return isFixed(getParentNode(element)); 578} 579 580/** 581 * Finds the first parent of an element that has a transformed property defined 582 * @method 583 * @memberof Popper.Utils 584 * @argument {Element} element 585 * @returns {Element} first transformed parent or documentElement 586 */ 587 588function getFixedPositionOffsetParent(element) { 589 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 590 if (!element || !element.parentElement || isIE()) { 591 return document.documentElement; 592 } 593 var el = element.parentElement; 594 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 595 el = el.parentElement; 596 } 597 return el || document.documentElement; 598} 599 600/** 601 * Computed the boundaries limits and return them 602 * @method 603 * @memberof Popper.Utils 604 * @param {HTMLElement} popper 605 * @param {HTMLElement} reference 606 * @param {number} padding 607 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 608 * @param {Boolean} fixedPosition - Is in fixed position mode 609 * @returns {Object} Coordinates of the boundaries 610 */ 611function getBoundaries(popper, reference, padding, boundariesElement) { 612 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; 613 614 // NOTE: 1 DOM access here 615 616 var boundaries = { top: 0, left: 0 }; 617 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 618 619 // Handle viewport case 620 if (boundariesElement === 'viewport') { 621 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 622 } else { 623 // Handle other cases based on DOM element used as boundaries 624 var boundariesNode = void 0; 625 if (boundariesElement === 'scrollParent') { 626 boundariesNode = getScrollParent(getParentNode(reference)); 627 if (boundariesNode.nodeName === 'BODY') { 628 boundariesNode = popper.ownerDocument.documentElement; 629 } 630 } else if (boundariesElement === 'window') { 631 boundariesNode = popper.ownerDocument.documentElement; 632 } else { 633 boundariesNode = boundariesElement; 634 } 635 636 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); 637 638 // In case of HTML, we need a different computation 639 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 640 var _getWindowSizes = getWindowSizes(popper.ownerDocument), 641 height = _getWindowSizes.height, 642 width = _getWindowSizes.width; 643 644 boundaries.top += offsets.top - offsets.marginTop; 645 boundaries.bottom = height + offsets.top; 646 boundaries.left += offsets.left - offsets.marginLeft; 647 boundaries.right = width + offsets.left; 648 } else { 649 // for all the other DOM elements, this one is good 650 boundaries = offsets; 651 } 652 } 653 654 // Add paddings 655 padding = padding || 0; 656 var isPaddingNumber = typeof padding === 'number'; 657 boundaries.left += isPaddingNumber ? padding : padding.left || 0; 658 boundaries.top += isPaddingNumber ? padding : padding.top || 0; 659 boundaries.right -= isPaddingNumber ? padding : padding.right || 0; 660 boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; 661 662 return boundaries; 663} 664 665function getArea(_ref) { 666 var width = _ref.width, 667 height = _ref.height; 668 669 return width * height; 670} 671 672/** 673 * Utility used to transform the `auto` placement to the placement with more 674 * available space. 675 * @method 676 * @memberof Popper.Utils 677 * @argument {Object} data - The data object generated by update method 678 * @argument {Object} options - Modifiers configuration and options 679 * @returns {Object} The data object, properly modified 680 */ 681function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 682 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 683 684 if (placement.indexOf('auto') === -1) { 685 return placement; 686 } 687 688 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 689 690 var rects = { 691 top: { 692 width: boundaries.width, 693 height: refRect.top - boundaries.top 694 }, 695 right: { 696 width: boundaries.right - refRect.right, 697 height: boundaries.height 698 }, 699 bottom: { 700 width: boundaries.width, 701 height: boundaries.bottom - refRect.bottom 702 }, 703 left: { 704 width: refRect.left - boundaries.left, 705 height: boundaries.height 706 } 707 }; 708 709 var sortedAreas = Object.keys(rects).map(function (key) { 710 return _extends({ 711 key: key 712 }, rects[key], { 713 area: getArea(rects[key]) 714 });
715 }).sort(function (a, b) { 716 return b.area - a.area; 717 }); 718 719 var filteredAreas = sortedAreas.filter(function (_ref2) { 720 var width = _ref2.width, 721 height = _ref2.height; 722 return width >= popper.clientWidth && height >= popper.clientHeight; 723 }); 724 725 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 726 727 var variation = placement.split('-')[1]; 728 729 return computedPlacement + (variation ? '-' + variation : ''); 730} 731 732/** 733 * Get offsets to the reference element 734 * @method 735 * @memberof Popper.Utils 736 * @param {Object} state 737 * @param {Element} popper - the popper element 738 * @param {Element} reference - the reference element (the popper will be relative to this) 739 * @param {Element} fixedPosition - is in fixed position mode 740 * @returns {Object} An object containing the offsets which will be applied to the popper 741 */ 742function getReferenceOffsets(state, popper, reference) { 743 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 744 745 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 746 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 747} 748 749/** 750 * Get the outer sizes of the given element (offset size + margins) 751 * @method 752 * @memberof Popper.Utils 753 * @argument {Element} element 754 * @returns {Object}
vendor: 4,852 bytes, lines 754-903
754 object containing width and height properties 755 */ 756function getOuterSizes(element) { 757 var window = element.ownerDocument.defaultView; 758 var styles = window.getComputedStyle(element); 759 var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); 760 var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); 761 var result = { 762 width: element.offsetWidth + y, 763 height: element.offsetHeight + x 764 }; 765 return result; 766} 767 768/** 769 * Get the opposite placement of the given one 770 * @method 771 * @memberof Popper.Utils 772 * @argument {String} placement 773 * @returns {String} flipped placement 774 */ 775function getOppositePlacement(placement) { 776 var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 777 return placement.replace(/left|right|bottom|top/g, function (matched) { 778 return hash[matched]; 779 }); 780} 781 782/** 783 * Get offsets to the popper 784 * @method 785 * @memberof Popper.Utils 786 * @param {Object} position - CSS position the Popper will get applied 787 * @param {HTMLElement} popper - the popper element 788 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 789 * @param {String} placement - one of the valid placement options 790 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 791 */ 792function getPopperOffsets(popper, referenceOffsets, placement) { 793 placement = placement.split('-')[0]; 794 795 // Get popper node sizes 796 var popperRect = getOuterSizes(popper); 797 798 // Add position, width and height to our offsets object 799 var popperOffsets = { 800 width: popperRect.width, 801 height: popperRect.height 802 }; 803 804 // depending by the popper placement we have to compute its offsets slightly differently 805 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 806 var mainSide = isHoriz ? 'top' : 'left'; 807 var secondarySide = isHoriz ? 'left' : 'top'; 808 var measurement = isHoriz ? 'height' : 'width'; 809 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 810 811 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 812 if (placement === secondarySide) { 813 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 814 } else { 815 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 816 } 817 818 return popperOffsets; 819} 820 821/** 822 * Mimics the `find` method of Array 823 * @method 824 * @memberof Popper.Utils 825 * @argument {Array} arr 826 * @argument prop 827 * @argument value 828 * @returns index or -1 829 */ 830function find(arr, check) { 831 // use native find if supported 832 if (Array.prototype.find) { 833 return arr.find(check); 834 } 835 836 // use `filter` to obtain the same behavior of `find` 837 return arr.filter(check)[0]; 838} 839 840/** 841 * Return the index of the matching object 842 * @method 843 * @memberof Popper.Utils 844 * @argument {Array} arr 845 * @argument prop 846 * @argument value 847 * @returns index or -1 848 */ 849function findIndex(arr, prop, value) { 850 // use native findIndex if supported 851 if (Array.prototype.findIndex) { 852 return arr.findIndex(function (cur) { 853 return cur[prop] === value; 854 }); 855 } 856 857 // use `find` + `indexOf` if `findIndex` isn't supported 858 var match = find(arr, function (obj) { 859 return obj[prop] === value; 860 }); 861 return arr.indexOf(match); 862} 863 864/** 865 * Loop trough the list of modifiers and run them in order, 866 * each of them will then edit the data object. 867 * @method 868 * @memberof Popper.Utils 869 * @param {dataObject} data 870 * @param {Array} modifiers 871 * @param {String} ends - Optional modifier name used as stopper 872 * @returns {dataObject} 873 */ 874function runModifiers(modifiers, data, ends) { 875 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 876 877 modifiersToRun.forEach(function (modifier) { 878 if (modifier['function']) { 879 // eslint-disable-line dot-notation 880 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 881 } 882 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 883 if (modifier.enabled && isFunction(fn)) { 884 // Add properties to offsets to make them a complete clientRect object 885 // we do this before each modifier to make sure the previous one doesn't 886 // mess with these values 887 data.offsets.popper = getClientRect(data.offsets.popper); 888 data.offsets.reference = getClientRect(data.offsets.reference); 889 890 data = fn(data, modifier); 891 } 892 }); 893 894 return data; 895} 896 897/** 898 * Updates the position of the popper, computing the new offsets and applying 899 * the new style.<br /> 900 * Prefer `scheduleUpdate` over `update` because of performance reasons. 901 * @method 902 * @memberof Popper 903 */
vendor: 8,685 bytes, lines 904-1174
904function update() { 905 // if popper is destroyed, don't perform any further update 906 if (this.state.isDestroyed) { 907 return; 908 } 909 910 var data = { 911 instance: this, 912 styles: {}, 913 arrowStyles: {}, 914 attributes: {}, 915 flipped: false, 916 offsets: {} 917 }; 918 919 // compute reference element offsets 920 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); 921 922 // compute auto placement, store placement inside the data object, 923 // modifiers will be able to edit `placement` if needed 924 // and refer to originalPlacement to know the original value 925 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); 926 927 // store the computed placement inside `originalPlacement` 928 data.originalPlacement = data.placement; 929 930 data.positionFixed = this.options.positionFixed; 931 932 // compute the popper offsets 933 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 934 935 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; 936 937 // run the modifiers 938 data = runModifiers(this.modifiers, data); 939 940 // the first `update` will call `onCreate` callback 941 // the other ones will call `onUpdate` callback 942 if (!this.state.isCreated) { 943 this.state.isCreated = true; 944 this.options.onCreate(data); 945 } else { 946 this.options.onUpdate(data); 947 } 948} 949 950/** 951 * Helper used to know if the given modifier is enabled. 952 * @method 953 * @memberof Popper.Utils 954 * @returns {Boolean} 955 */ 956function isModifierEnabled(modifiers, modifierName) { 957 return modifiers.some(function (_ref) { 958 var name = _ref.name, 959 enabled = _ref.enabled; 960 return enabled && name === modifierName; 961 }); 962} 963 964/** 965 * Get the prefixed supported property name 966 * @method 967 * @memberof Popper.Utils 968 * @argument {String} property (camelCase) 969 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 970 */ 971function getSupportedPropertyName(property) { 972 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 973 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 974 975 for (var i = 0; i < prefixes.length; i++) { 976 var prefix = prefixes[i]; 977 var toCheck = prefix ? '' + prefix + upperProp : property; 978 if (typeof document.body.style[toCheck] !== 'undefined') { 979 return toCheck; 980 } 981 } 982 return null; 983} 984 985/** 986 * Destroys the popper. 987 * @method 988 * @memberof Popper 989 */ 990function destroy() { 991 this.state.isDestroyed = true; 992 993 // touch DOM only if `applyStyle` modifier is enabled 994 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 995 this.popper.removeAttribute('x-placement'); 996 this.popper.style.position = ''; 997 this.popper.style.top = ''; 998 this.popper.style.left = ''; 999 this.popper.style.right = ''; 1000 this.popper.style.bottom = ''; 1001 this.popper.style.willChange = ''; 1002 this.popper.style[getSupportedPropertyName('transform')] = ''; 1003 } 1004 1005 this.disableEventListeners(); 1006 1007 // remove the popper if user explicity asked for the deletion on destroy 1008 // do not use `remove` because IE11 doesn't support it 1009 if (this.options.removeOnDestroy) { 1010 this.popper.parentNode.removeChild(this.popper); 1011 } 1012 return this; 1013} 1014 1015/** 1016 * Get the window associated with the element 1017 * @argument {Element} element 1018 * @returns {Window} 1019 */ 1020function getWindow(element) { 1021 var ownerDocument = element.ownerDocument; 1022 return ownerDocument ? ownerDocument.defaultView : window; 1023} 1024 1025function attachToScrollParents(scrollParent, event, callback, scrollParents) { 1026 var isBody = scrollParent.nodeName === 'BODY'; 1027 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 1028 target.addEventListener(event, callback, { passive: true }); 1029 1030 if (!isBody) { 1031 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 1032 } 1033 scrollParents.push(target); 1034} 1035 1036/** 1037 * Setup needed event listeners used to update the popper position 1038 * @method 1039 * @memberof Popper.Utils 1040 * @private 1041 */ 1042function setupEventListeners(reference, options, state, updateBound) { 1043 // Resize event listener on window 1044 state.updateBound = updateBound; 1045 getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 1046 1047 // Scroll event listener on scroll parents 1048 var scrollElement = getScrollParent(reference); 1049 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 1050 state.scrollElement = scrollElement; 1051 state.eventsEnabled = true; 1052 1053 return state; 1054} 1055 1056/** 1057 * It will add resize/scroll events and start recalculating 1058 * position of the popper element when they are triggered. 1059 * @method 1060 * @memberof Popper 1061 */ 1062function enableEventListeners() { 1063 if (!this.state.eventsEnabled) { 1064 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 1065 } 1066} 1067 1068/** 1069 * Remove event listeners used to update the popper position 1070 * @method 1071 * @memberof Popper.Utils 1072 * @private 1073 */ 1074function removeEventListeners(reference, state) { 1075 // Remove resize event listener on window 1076 getWindow(reference).removeEventListener('resize', state.updateBound); 1077 1078 // Remove scroll event listener on scroll parents 1079 state.scrollParents.forEach(function (target) { 1080 target.removeEventListener('scroll', state.updateBound); 1081 }); 1082 1083 // Reset state 1084 state.updateBound = null; 1085 state.scrollParents = []; 1086 state.scrollElement = null; 1087 state.eventsEnabled = false; 1088 return state; 1089} 1090 1091/** 1092 * It will remove resize/scroll events and won't recalculate popper position 1093 * when they are triggered. It also won't trigger `onUpdate` callback anymore, 1094 * unless you call `update` method manually. 1095 * @method 1096 * @memberof Popper 1097 */ 1098function disableEventListeners() { 1099 if (this.state.eventsEnabled) { 1100 cancelAnimationFrame(this.scheduleUpdate); 1101 this.state = removeEventListeners(this.reference, this.state); 1102 } 1103} 1104 1105/** 1106 * Tells if a given input is a number 1107 * @method 1108 * @memberof Popper.Utils 1109 * @param {*} input to check 1110 * @return {Boolean} 1111 */ 1112function isNumeric(n) { 1113 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 1114} 1115 1116/** 1117 * Set the style to the given popper 1118 * @method 1119 * @memberof Popper.Utils 1120 * @argument {Element} element - Element to apply the style to 1121 * @argument {Object} styles 1122 * Object with a list of properties and values which will be applied to the element 1123 */ 1124function setStyles(element, styles) { 1125 Object.keys(styles).forEach(function (prop) { 1126 var unit = ''; 1127 // add unit if the value is numeric and is one of the following 1128 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 1129 unit = 'px'; 1130 } 1131 element.style[prop] = styles[prop] + unit; 1132 }); 1133} 1134 1135/** 1136 * Set the attributes to the given popper 1137 * @method 1138 * @memberof Popper.Utils 1139 * @argument {Element} element - Element to apply the attributes to 1140 * @argument {Object} styles 1141 * Object with a list of properties and values which will be applied to the element 1142 */ 1143function setAttributes(element, attributes) { 1144 Object.keys(attributes).forEach(function (prop) { 1145 var value = attributes[prop]; 1146 if (value !== false) { 1147 element.setAttribute(prop, attributes[prop]); 1148 } else { 1149 element.removeAttribute(prop); 1150 } 1151 }); 1152} 1153 1154/** 1155 * @function 1156 * @memberof Modifiers 1157 * @argument {Object} data - The data object generated by `update` method 1158 * @argument {Object} data.styles - List of style properties - values to apply to popper element 1159 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 1160 * @argument {Object} options - Modifiers configuration and options 1161 * @returns {Object} The same data object 1162 */ 1163function applyStyle(data) { 1164 // any property present in `data.styles` will be applied to the popper, 1165 // in this way we can make the 3rd party modifiers add custom styles to it 1166 // Be aware, modifiers could override the properties defined in the previous 1167 // lines of this modifier! 1168 setStyles(data.instance.popper, data.styles); 1169 1170 // any property present in `data.attributes` will be applied to the popper, 1171 // they will be set as HTML attributes of the element 1172 setAttributes(data.instance.popper, data.attributes); 1173 1174 // if arrowElement is defined and arrowStyles has some properties
1175 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 1176 setStyles(data.arrowElement, data.arrowStyles); 1177 } 1178 1179 return data; 1180} 1181 1182/** 1183 * Set the x-placement attribute before everything else because it could be used 1184 * to add margins to the popper margins needs to be calculated to get the 1185 * correct popper offsets. 1186 * @method 1187 * @memberof Popper.modifiers 1188 * @param {HTMLElement} reference - The reference element used to position the popper 1189 * @param {HTMLElement} popper - The HTML element used as popper 1190 * @param {Object} options - Popper.js options 1191 */ 1192function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 1193 // compute reference element offsets 1194 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 1195 1196 // compute auto placement, store placement inside the data object, 1197 // modifiers will be able to edit `placement` if needed 1198 // and refer to originalPlacement to know the original value 1199 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 1200 1201 popper.setAttribute('x-placement', placement); 1202 1203 // Apply `position` to popper before anything else because 1204 // without the position applied we can't guarantee correct computations 1205 setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 1206 1207 return options; 1208} 1209 1210/** 1211 * @function 1212 * @memberof Modifiers 1213 * @argument {Object} data - The data object generated by `update` method 1214 * @argument {Object} options - Modifiers configuration and options 1215 * @returns {Object} The data object, properly modified 1216 */ 1217function computeStyle(data, options) { 1218 var x = options.x, 1219 y = options.y;
vendor: 4,290 bytes, lines 1220-1332
1220 var popper = data.offsets.popper; 1221 1222 // Remove this legacy support in Popper.js v2 1223 1224 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 1225 return modifier.name === 'applyStyle'; 1226 }).gpuAcceleration; 1227 if (legacyGpuAccelerationOption !== undefined) { 1228 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 1229 } 1230 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 1231 1232 var offsetParent = getOffsetParent(data.instance.popper); 1233 var offsetParentRect = getBoundingClientRect(offsetParent); 1234 1235 // Styles 1236 var styles = { 1237 position: popper.position 1238 }; 1239 1240 // Avoid blurry text by using full pixel integers. 1241 // For pixel-perfect positioning, top/bottom prefers rounded 1242 // values, while left/right prefers floored values. 1243 var offsets = { 1244 left: Math.floor(popper.left), 1245 top: Math.round(popper.top), 1246 bottom: Math.round(popper.bottom), 1247 right: Math.floor(popper.right) 1248 }; 1249 1250 var sideA = x === 'bottom' ? 'top' : 'bottom'; 1251 var sideB = y === 'right' ? 'left' : 'right'; 1252 1253 // if gpuAcceleration is set to `true` and transform is supported, 1254 // we use `translate3d` to apply the position to the popper we 1255 // automatically use the supported prefixed version if needed 1256 var prefixedProperty = getSupportedPropertyName('transform'); 1257 1258 // now, let's make a step back and look at this code closely (wtf?) 1259 // If the content of the popper grows once it's been positioned, it 1260 // may happen that the popper gets misplaced because of the new content 1261 // overflowing its reference element 1262 // To avoid this problem, we provide two options (x and y), which allow 1263 // the consumer to define the offset origin. 1264 // If we position a popper on top of a reference element, we can set 1265 // `x` to `top` to make the popper grow towards its top instead of 1266 // its bottom. 1267 var left = void 0, 1268 top = void 0; 1269 if (sideA === 'bottom') { 1270 // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar) 1271 // and not the bottom of the html element 1272 if (offsetParent.nodeName === 'HTML') { 1273 top = -offsetParent.clientHeight + offsets.bottom; 1274 } else { 1275 top = -offsetParentRect.height + offsets.bottom; 1276 } 1277 } else { 1278 top = offsets.top; 1279 } 1280 if (sideB === 'right') { 1281 if (offsetParent.nodeName === 'HTML') { 1282 left = -offsetParent.clientWidth + offsets.right; 1283 } else { 1284 left = -offsetParentRect.width + offsets.right; 1285 } 1286 } else { 1287 left = offsets.left; 1288 } 1289 if (gpuAcceleration && prefixedProperty) { 1290 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 1291 styles[sideA] = 0; 1292 styles[sideB] = 0; 1293 styles.willChange = 'transform'; 1294 } else { 1295 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 1296 var invertTop = sideA === 'bottom' ? -1 : 1; 1297 var invertLeft = sideB === 'right' ? -1 : 1; 1298 styles[sideA] = top * invertTop; 1299 styles[sideB] = left * invertLeft; 1300 styles.willChange = sideA + ', ' + sideB; 1301 } 1302 1303 // Attributes 1304 var attributes = { 1305 'x-placement': data.placement 1306 }; 1307 1308 // Update `data` attributes, styles and arrowStyles 1309 data.attributes = _extends({}, attributes, data.attributes); 1310 data.styles = _extends({}, styles, data.styles); 1311 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 1312 1313 return data; 1314} 1315 1316/** 1317 * Helper used to know if the given modifier depends from another one.<br /> 1318 * It checks if the needed modifier is listed and enabled. 1319 * @method 1320 * @memberof Popper.Utils 1321 * @param {Array} modifiers - list of modifiers 1322 * @param {String} requestingName - name of requesting modifier 1323 * @param {String} requestedName - name of requested modifier 1324 * @returns {Boolean} 1325 */ 1326function isModifierRequired(modifiers, requestingName, requestedName) { 1327 var requesting = find(modifiers, function (_ref) { 1328 var name = _ref.name; 1329 return name === requestingName; 1330 }); 1331 1332 var isRequired = !!requesting && modifiers.some(function (modifier) {
vendor: 6,780 bytes, lines 1333-1520
1333 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 1334 }); 1335 1336 if (!isRequired) { 1337 var _requesting = '`' + requestingName + '`'; 1338 var requested = '`' + requestedName + '`'; 1339 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 1340 } 1341 return isRequired; 1342} 1343 1344/** 1345 * @function 1346 * @memberof Modifiers 1347 * @argument {Object} data - The data object generated by update method 1348 * @argument {Object} options - Modifiers configuration and options 1349 * @returns {Object} The data object, properly modified 1350 */ 1351function arrow(data, options) { 1352 var _data$offsets$arrow; 1353 1354 // arrow depends on keepTogether in order to work 1355 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 1356 return data; 1357 } 1358 1359 var arrowElement = options.element; 1360 1361 // if arrowElement is a string, suppose it's a CSS selector 1362 if (typeof arrowElement === 'string') { 1363 arrowElement = data.instance.popper.querySelector(arrowElement); 1364 1365 // if arrowElement is not found, don't run the modifier 1366 if (!arrowElement) { 1367 return data; 1368 } 1369 } else { 1370 // if the arrowElement isn't a query selector we must check that the 1371 // provided DOM node is child of its popper node 1372 if (!data.instance.popper.contains(arrowElement)) { 1373 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 1374 return data; 1375 } 1376 } 1377 1378 var placement = data.placement.split('-')[0]; 1379 var _data$offsets = data.offsets, 1380 popper = _data$offsets.popper, 1381 reference = _data$offsets.reference; 1382 1383 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 1384 1385 var len = isVertical ? 'height' : 'width'; 1386 var sideCapitalized = isVertical ? 'Top' : 'Left'; 1387 var side = sideCapitalized.toLowerCase(); 1388 var altSide = isVertical ? 'left' : 'top'; 1389 var opSide = isVertical ? 'bottom' : 'right'; 1390 var arrowElementSize = getOuterSizes(arrowElement)[len]; 1391 1392 // 1393 // extends keepTogether behavior making sure the popper and its 1394 // reference have enough pixels in conjunction 1395 // 1396 1397 // top/left side 1398 if (reference[opSide] - arrowElementSize < popper[side]) { 1399 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 1400 } 1401 // bottom/right side 1402 if (reference[side] + arrowElementSize > popper[opSide]) { 1403 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 1404 } 1405 data.offsets.popper = getClientRect(data.offsets.popper); 1406 1407 // compute center of the popper 1408 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 1409 1410 // Compute the sideValue using the updated popper offsets 1411 // take popper margin in account because we don't have this info available 1412 var css = getStyleComputedProperty(data.instance.popper); 1413 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 1414 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 1415 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 1416 1417 // prevent arrowElement from being placed not contiguously to its popper 1418 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 1419 1420 data.arrowElement = arrowElement; 1421 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 1422 1423 return data; 1424} 1425 1426/** 1427 * Get the opposite placement variation of the given one 1428 * @method 1429 * @memberof Popper.Utils 1430 * @argument {String} placement variation 1431 * @returns {String} flipped placement variation 1432 */ 1433function getOppositeVariation(variation) { 1434 if (variation === 'end') { 1435 return 'start'; 1436 } else if (variation === 'start') { 1437 return 'end'; 1438 } 1439 return variation; 1440} 1441 1442/** 1443 * List of accepted placements to use as values of the `placement` option.<br /> 1444 * Valid placements are: 1445 * - `auto` 1446 * - `top` 1447 * - `right` 1448 * - `bottom` 1449 * - `left` 1450 * 1451 * Each placement can have a variation from this list: 1452 * - `-start` 1453 * - `-end` 1454 * 1455 * Variations are interpreted easily if you think of them as the left to right 1456 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 1457 * is right.<br /> 1458 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 1459 * 1460 * Some valid examples are: 1461 * - `top-end` (on top of reference, right aligned) 1462 * - `right-start` (on right of reference, top aligned) 1463 * - `bottom` (on bottom, centered) 1464 * - `auto-end` (on the side with more space available, alignment depends by placement) 1465 * 1466 * @static 1467 * @type {Array} 1468 * @enum {String} 1469 * @readonly 1470 * @method placements 1471 * @memberof Popper 1472 */ 1473var 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']; 1474 1475// Get rid of `auto` `auto-start` and `auto-end` 1476var validPlacements = placements.slice(3); 1477 1478/** 1479 * Given an initial placement, returns all the subsequent placements 1480 * clockwise (or counter-clockwise). 1481 * 1482 * @method 1483 * @memberof Popper.Utils 1484 * @argument {String} placement - A valid placement (it accepts variations) 1485 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 1486 * @returns {Array} placements including their variations 1487 */ 1488function clockwise(placement) { 1489 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 1490 1491 var index = validPlacements.indexOf(placement); 1492 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 1493 return counter ? arr.reverse() : arr; 1494} 1495 1496var BEHAVIORS = { 1497 FLIP: 'flip', 1498 CLOCKWISE: 'clockwise', 1499 COUNTERCLOCKWISE: 'counterclockwise' 1500}; 1501 1502/** 1503 * @function 1504 * @memberof Modifiers 1505 * @argument {Object} data - The data object generated by update method 1506 * @argument {Object} options - Modifiers configuration and options 1507 * @returns {Object} The data object, properly modified 1508 */ 1509function flip(data, options) { 1510 // if `inner` modifier is enabled, we can't use the `flip` modifier 1511 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 1512 return data; 1513 } 1514 1515 if (data.flipped && data.placement === data.originalPlacement) { 1516 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 1517 return data; 1518 } 1519 1520 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
vendor: 2,694 bytes, lines 1521-1581
1521 1522 var placement = data.placement.split('-')[0]; 1523 var placementOpposite = getOppositePlacement(placement); 1524 var variation = data.placement.split('-')[1] || ''; 1525 1526 var flipOrder = []; 1527 1528 switch (options.behavior) { 1529 case BEHAVIORS.FLIP: 1530 flipOrder = [placement, placementOpposite]; 1531 break; 1532 case BEHAVIORS.CLOCKWISE: 1533 flipOrder = clockwise(placement); 1534 break; 1535 case BEHAVIORS.COUNTERCLOCKWISE: 1536 flipOrder = clockwise(placement, true); 1537 break; 1538 default: 1539 flipOrder = options.behavior; 1540 } 1541 1542 flipOrder.forEach(function (step, index) { 1543 if (placement !== step || flipOrder.length === index + 1) { 1544 return data; 1545 } 1546 1547 placement = data.placement.split('-')[0]; 1548 placementOpposite = getOppositePlacement(placement); 1549 1550 var popperOffsets = data.offsets.popper; 1551 var refOffsets = data.offsets.reference; 1552 1553 // using floor because the reference offsets may contain decimals we are not going to consider here 1554 var floor = Math.floor; 1555 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); 1556 1557 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 1558 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 1559 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 1560 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 1561 1562 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 1563 1564 // flip the variation if required 1565 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1566 var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 1567 1568 if (overlapsRef || overflowsBoundaries || flippedVariation) { 1569 // this boolean to detect any flip loop 1570 data.flipped = true; 1571 1572 if (overlapsRef || overflowsBoundaries) { 1573 placement = flipOrder[index + 1]; 1574 } 1575 1576 if (flippedVariation) { 1577 variation = getOppositeVariation(variation); 1578 } 1579 1580 data.placement = placement + (variation ? '-' + variation : ''); 1581
vendor: 15,310 bytes, lines 1582-2017
1582 // this object contains `position`, we want to preserve it along with 1583 // any additional property we may add in the future 1584 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 1585 1586 data = runModifiers(data.instance.modifiers, data, 'flip'); 1587 } 1588 }); 1589 return data; 1590} 1591 1592/** 1593 * @function 1594 * @memberof Modifiers 1595 * @argument {Object} data - The data object generated by update method 1596 * @argument {Object} options - Modifiers configuration and options 1597 * @returns {Object} The data object, properly modified 1598 */ 1599function keepTogether(data) { 1600 var _data$offsets = data.offsets, 1601 popper = _data$offsets.popper, 1602 reference = _data$offsets.reference; 1603 1604 var placement = data.placement.split('-')[0]; 1605 var floor = Math.floor; 1606 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1607 var side = isVertical ? 'right' : 'bottom'; 1608 var opSide = isVertical ? 'left' : 'top'; 1609 var measurement = isVertical ? 'width' : 'height'; 1610 1611 if (popper[side] < floor(reference[opSide])) { 1612 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 1613 } 1614 if (popper[opSide] > floor(reference[side])) { 1615 data.offsets.popper[opSide] = floor(reference[side]); 1616 } 1617 1618 return data; 1619} 1620 1621/** 1622 * Converts a string containing value + unit into a px value number 1623 * @function 1624 * @memberof {modifiers~offset} 1625 * @private 1626 * @argument {String} str - Value + unit string 1627 * @argument {String} measurement - `height` or `width` 1628 * @argument {Object} popperOffsets 1629 * @argument {Object} referenceOffsets 1630 * @returns {Number|String} 1631 * Value in pixels, or original string if no values were extracted 1632 */ 1633function toValue(str, measurement, popperOffsets, referenceOffsets) { 1634 // separate value from unit 1635 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 1636 var value = +split[1]; 1637 var unit = split[2]; 1638 1639 // If it's not a number it's an operator, I guess 1640 if (!value) { 1641 return str; 1642 } 1643 1644 if (unit.indexOf('%') === 0) { 1645 var element = void 0; 1646 switch (unit) { 1647 case '%p': 1648 element = popperOffsets; 1649 break; 1650 case '%': 1651 case '%r': 1652 default: 1653 element = referenceOffsets; 1654 } 1655 1656 var rect = getClientRect(element); 1657 return rect[measurement] / 100 * value; 1658 } else if (unit === 'vh' || unit === 'vw') { 1659 // if is a vh or vw, we calculate the size based on the viewport 1660 var size = void 0; 1661 if (unit === 'vh') { 1662 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 1663 } else { 1664 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 1665 } 1666 return size / 100 * value; 1667 } else { 1668 // if is an explicit pixel unit, we get rid of the unit and keep the value 1669 // if is an implicit unit, it's px, and we return just the value 1670 return value; 1671 } 1672} 1673 1674/** 1675 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 1676 * @function 1677 * @memberof {modifiers~offset} 1678 * @private 1679 * @argument {String} offset 1680 * @argument {Object} popperOffsets 1681 * @argument {Object} referenceOffsets 1682 * @argument {String} basePlacement 1683 * @returns {Array} a two cells array with x and y offsets in numbers 1684 */ 1685function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 1686 var offsets = [0, 0]; 1687 1688 // Use height if placement is left or right and index is 0 otherwise use width 1689 // in this way the first offset will use an axis and the second one 1690 // will use the other one 1691 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 1692 1693 // Split the offset string to obtain a list of values and operands 1694 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 1695 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 1696 return frag.trim(); 1697 }); 1698 1699 // Detect if the offset string contains a pair of values or a single one 1700 // they could be separated by comma or space 1701 var divider = fragments.indexOf(find(fragments, function (frag) { 1702 return frag.search(/,|\s/) !== -1; 1703 })); 1704 1705 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 1706 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 1707 } 1708 1709 // If divider is found, we divide the list of values and operands to divide 1710 // them by ofset X and Y. 1711 var splitRegex = /\s*,\s*|\s+/; 1712 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]; 1713 1714 // Convert the values with units to absolute pixels to allow our computations 1715 ops = ops.map(function (op, index) { 1716 // Most of the units rely on the orientation of the popper 1717 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 1718 var mergeWithPrevious = false; 1719 return op 1720 // This aggregates any `+` or `-` sign that aren't considered operators 1721 // e.g.: 10 + +5 => [10, +, +5] 1722 .reduce(function (a, b) { 1723 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 1724 a[a.length - 1] = b; 1725 mergeWithPrevious = true; 1726 return a; 1727 } else if (mergeWithPrevious) { 1728 a[a.length - 1] += b; 1729 mergeWithPrevious = false; 1730 return a; 1731 } else { 1732 return a.concat(b); 1733 } 1734 }, []) 1735 // Here we convert the string values into number values (in px) 1736 .map(function (str) { 1737 return toValue(str, measurement, popperOffsets, referenceOffsets); 1738 }); 1739 }); 1740 1741 // Loop trough the offsets arrays and execute the operations 1742 ops.forEach(function (op, index) { 1743 op.forEach(function (frag, index2) { 1744 if (isNumeric(frag)) { 1745 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 1746 } 1747 }); 1748 }); 1749 return offsets; 1750} 1751 1752/** 1753 * @function 1754 * @memberof Modifiers 1755 * @argument {Object} data - The data object generated by update method 1756 * @argument {Object} options - Modifiers configuration and options 1757 * @argument {Number|String} options.offset=0 1758 * The offset value as described in the modifier description 1759 * @returns {Object} The data object, properly modified 1760 */ 1761function offset(data, _ref) { 1762 var offset = _ref.offset; 1763 var placement = data.placement, 1764 _data$offsets = data.offsets, 1765 popper = _data$offsets.popper, 1766 reference = _data$offsets.reference; 1767 1768 var basePlacement = placement.split('-')[0]; 1769 1770 var offsets = void 0; 1771 if (isNumeric(+offset)) { 1772 offsets = [+offset, 0]; 1773 } else { 1774 offsets = parseOffset(offset, popper, reference, basePlacement); 1775 } 1776 1777 if (basePlacement === 'left') { 1778 popper.top += offsets[0]; 1779 popper.left -= offsets[1]; 1780 } else if (basePlacement === 'right') { 1781 popper.top += offsets[0]; 1782 popper.left += offsets[1]; 1783 } else if (basePlacement === 'top') { 1784 popper.left += offsets[0]; 1785 popper.top -= offsets[1]; 1786 } else if (basePlacement === 'bottom') { 1787 popper.left += offsets[0]; 1788 popper.top += offsets[1]; 1789 } 1790 1791 data.popper = popper; 1792 return data; 1793} 1794 1795/** 1796 * @function 1797 * @memberof Modifiers 1798 * @argument {Object} data - The data object generated by `update` method 1799 * @argument {Object} options - Modifiers configuration and options 1800 * @returns {Object} The data object, properly modified 1801 */ 1802function preventOverflow(data, options) { 1803 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 1804 1805 // If offsetParent is the reference element, we really want to 1806 // go one step up and use the next offsetParent as reference to 1807 // avoid to make this modifier completely useless and look like broken 1808 if (data.instance.reference === boundariesElement) { 1809 boundariesElement = getOffsetParent(boundariesElement); 1810 } 1811 1812 // NOTE: DOM access here 1813 // resets the popper's position so that the document size can be calculated excluding 1814 // the size of the popper element itself 1815 var transformProp = getSupportedPropertyName('transform'); 1816 var popperStyles = data.instance.popper.style; // assignment to help minification 1817 var top = popperStyles.top, 1818 left = popperStyles.left, 1819 transform = popperStyles[transformProp]; 1820 1821 popperStyles.top = ''; 1822 popperStyles.left = ''; 1823 popperStyles[transformProp] = ''; 1824 1825 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 1826 1827 // NOTE: DOM access here 1828 // restores the original style properties after the offsets have been computed 1829 popperStyles.top = top; 1830 popperStyles.left = left; 1831 popperStyles[transformProp] = transform; 1832 1833 options.boundaries = boundaries; 1834 1835 var order = options.priority; 1836 var popper = data.offsets.popper; 1837 1838 var check = { 1839 primary: function primary(placement) { 1840 var value = popper[placement]; 1841 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 1842 value = Math.max(popper[placement], boundaries[placement]); 1843 } 1844 return defineProperty({}, placement, value); 1845 }, 1846 secondary: function secondary(placement) { 1847 var mainSide = placement === 'right' ? 'left' : 'top'; 1848 var value = popper[mainSide]; 1849 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 1850 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 1851 } 1852 return defineProperty({}, mainSide, value); 1853 } 1854 }; 1855 1856 order.forEach(function (placement) { 1857 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 1858 popper = _extends({}, popper, check[side](placement)); 1859 }); 1860 1861 data.offsets.popper = popper; 1862 1863 return data; 1864} 1865 1866/** 1867 * @function 1868 * @memberof Modifiers 1869 * @argument {Object} data - The data object generated by `update` method 1870 * @argument {Object} options - Modifiers configuration and options 1871 * @returns {Object} The data object, properly modified 1872 */ 1873function shift(data) { 1874 var placement = data.placement; 1875 var basePlacement = placement.split('-')[0]; 1876 var shiftvariation = placement.split('-')[1]; 1877 1878 // if shift shiftvariation is specified, run the modifier 1879 if (shiftvariation) { 1880 var _data$offsets = data.offsets, 1881 reference = _data$offsets.reference, 1882 popper = _data$offsets.popper; 1883 1884 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 1885 var side = isVertical ? 'left' : 'top'; 1886 var measurement = isVertical ? 'width' : 'height'; 1887 1888 var shiftOffsets = { 1889 start: defineProperty({}, side, reference[side]), 1890 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 1891 }; 1892 1893 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 1894 } 1895 1896 return data; 1897} 1898 1899/** 1900 * @function 1901 * @memberof Modifiers 1902 * @argument {Object} data - The data object generated by update method 1903 * @argument {Object} options - Modifiers configuration and options 1904 * @returns {Object} The data object, properly modified 1905 */ 1906function hide(data) { 1907 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 1908 return data; 1909 } 1910 1911 var refRect = data.offsets.reference; 1912 var bound = find(data.instance.modifiers, function (modifier) { 1913 return modifier.name === 'preventOverflow'; 1914 }).boundaries; 1915 1916 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 1917 // Avoid unnecessary DOM access if visibility hasn't changed 1918 if (data.hide === true) { 1919 return data; 1920 } 1921 1922 data.hide = true; 1923 data.attributes['x-out-of-boundaries'] = ''; 1924 } else { 1925 // Avoid unnecessary DOM access if visibility hasn't changed 1926 if (data.hide === false) { 1927 return data; 1928 } 1929 1930 data.hide = false; 1931 data.attributes['x-out-of-boundaries'] = false; 1932 } 1933 1934 return data; 1935} 1936 1937/** 1938 * @function 1939 * @memberof Modifiers 1940 * @argument {Object} data - The data object generated by `update` method 1941 * @argument {Object} options - Modifiers configuration and options 1942 * @returns {Object} The data object, properly modified 1943 */ 1944function inner(data) { 1945 var placement = data.placement; 1946 var basePlacement = placement.split('-')[0]; 1947 var _data$offsets = data.offsets, 1948 popper = _data$offsets.popper, 1949 reference = _data$offsets.reference; 1950 1951 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 1952 1953 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 1954 1955 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 1956 1957 data.placement = getOppositePlacement(placement); 1958 data.offsets.popper = getClientRect(popper); 1959 1960 return data; 1961} 1962 1963/** 1964 * Modifier function, each modifier can have a function of this type assigned 1965 * to its `fn` property.<br /> 1966 * These functions will be called on each update, this means that you must 1967 * make sure they are performant enough to avoid performance bottlenecks. 1968 * 1969 * @function ModifierFn 1970 * @argument {dataObject} data - The data object generated by `update` method 1971 * @argument {Object} options - Modifiers configuration and options 1972 * @returns {dataObject} The data object, properly modified 1973 */ 1974 1975/** 1976 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 1977 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 1978 * needed by the library. 1979 * 1980 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 1981 * All the other properties are configurations that could be tweaked. 1982 * @namespace modifiers 1983 */ 1984var modifiers = { 1985 /** 1986 * Modifier used to shift the popper on the start or end of its reference 1987 * element.<br /> 1988 * It will read the variation of the `placement` property.<br /> 1989 * It can be one either `-end` or `-start`. 1990 * @memberof modifiers 1991 * @inner 1992 */ 1993 shift: { 1994 /** @prop {number} order=100 - Index used to define the order of execution */ 1995 order: 100, 1996 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 1997 enabled: true, 1998 /** @prop {ModifierFn} */ 1999 fn: shift 2000 }, 2001 2002 /** 2003 * The `offset` modifier can shift your popper on both its axis. 2004 * 2005 * It accepts the following units: 2006 * - `px` or unit-less, interpreted as pixels 2007 * - `%` or `%r`, percentage relative to the length of the reference element 2008 * - `%p`, percentage relative to the length of the popper element 2009 * - `vw`, CSS viewport width unit 2010 * - `vh`, CSS viewport height unit 2011 * 2012 * For length is intended the main axis relative to the placement of the popper.<br /> 2013 * This means that if the placement is `top` or `bottom`, the length will be the 2014 * `width`. In case of `left` or `right`, it will be the `height`. 2015 * 2016 * You can provide a single value (as `Number` or `String`), or a pair of values 2017 * as `String` divided by a comma or one (or more) white space
2017s.<br /> 2018 * The latter is a deprecated method because it leads to confusion and will be 2019 * removed in v2.<br /> 2020 * Additionally, it accepts additions and subtractions between different units. 2021 * Note that multiplications and divisions aren't supported. 2022 * 2023 * Valid examples are: 2024 * ``` 2025 * 10 2026 * '10%' 2027 * '10, 10' 2028 * '10%, 10' 2029 * '10 + 10%' 2030 * '10 - 5vh + 3%' 2031 * '-10px + 5vh, 5px - 6%' 2032 * ``` 2033 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 2034 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 2035 * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). 2036 * 2037 * @memberof modifiers 2038 * @inner 2039 */ 2040 offset: { 2041 /** @prop {number} order=200 - Index used to define the order of execution */ 2042 order: 200, 2043 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2044 enabled: true, 2045 /** @prop {ModifierFn} */ 2046 fn: offset, 2047 /** @prop {Number|String} offset=0 2048 * The offset value as described in the modifier description 2049 */ 2050 offset: 0 2051 }, 2052 2053 /** 2054 * Modifier used to prevent the popper from being positioned outside the boundary. 2055 * 2056 * A scenario exists where the reference itself is not within the boundaries.<br /> 2057 * We can say it has "escaped the boundaries" â or just "escaped".<br /> 2058 * In this case we need to decide whether the popper should either: 2059 * 2060 * - detach from the reference and remain "trapped" in the boundaries, or 2061 * - if it should ignore the boundary and "escape with its reference" 2062 * 2063 * When `escapeWithReference` is set to`true` and reference is completely 2064 * outside its boundaries, the popper will overflow (or completely leave) 2065 * the boundaries in order to remain attached to the edge of the reference. 2066 * 2067 * @memberof modifiers 2068 * @inner 2069 */ 2070 preventOverflow: { 2071 /** @prop {number} order=300 - Index used to define the order of execution */ 2072 order: 300, 2073 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2074 enabled: true, 2075 /** @prop {ModifierFn} */ 2076 fn: preventOverflow, 2077 /** 2078 * @prop {Array} [priority=['left','right','top','bottom']] 2079 * Popper will try to prevent overflow following these priorities by default, 2080 * then, it could overflow on the left and on top of the `boundariesElement` 2081 */ 2082 priority: ['left', 'right', 'top', 'bottom'], 2083 /** 2084 * @prop {number} padding=5 2085 * Amount of pixel used to define a minimum distance between the boundaries 2086 * and the popper. This makes sure the popper always has a little padding 2087 * between the edges of its container 2088 */ 2089 padding: 5, 2090 /** 2091 * @prop {String|HTMLElement} boundariesElement='scrollParent' 2092 * Boundaries used by the modifier. Can be `scrollParent`, `window`, 2093 * `viewport` or any DOM element. 2094 */ 2095 boundariesElement: 'scrollParent' 2096 }, 2097 2098 /** 2099 * Modifier used to make sure the reference and its popper stay near each other 2100 * without leaving any gap between the two. Especially useful when the arrow is 2101 * enabled and you want to ensure that it points to its reference element. 2102 * It cares only about the first axis. You can still have poppers with margin 2103 * between the popper and its reference element. 2104 * @memberof modifiers 2105 * @inner 2106 */ 2107 keepTogether: { 2108 /** @prop {number} order=400 - Index used to define the order of execution */ 2109 order: 400, 2110 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2111 enabled: true, 2112 /** @prop {ModifierFn} */ 2113 fn: keepTogether 2114 }, 2115 2116 /** 2117 * This modifier is used to move the `arrowElement` of the popper to make 2118 * sure it is positioned between the reference element and its popper element. 2119 * It will read the outer size of the `arrowElement` node to detect how many 2120 * pixels of conjunction are needed. 2121 * 2122 * It has no effect if no `arrowElement` is provided. 2123 * @memberof modifiers 2124 * @inner 2125 */ 2126 arrow: { 2127 /** @prop {number} order=500 - Index used to define the order of execution */ 2128 order: 500, 2129 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2130 enabled: true, 2131 /** @prop {ModifierFn} */ 2132 fn: arrow, 2133 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 2134 element: '[x-arrow]' 2135 }, 2136 2137 /** 2138 * Modifier used to flip the popper's placement when it starts to overlap its 2139 * reference element. 2140 * 2141 * Requires the `preventOverflow` modifier before it in order to work. 2142 * 2143 * **NOTE:** this modifier will interrupt the current update cycle and will 2144 * restart it if it detects the need to flip the placement. 2145 * @memberof modifiers 2146 * @inner 2147 */ 2148 flip: { 2149 /** @prop {number} order=600 - Index used to define the order of execution */ 2150 order: 600, 2151 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2152 enabled: true, 2153 /** @prop {ModifierFn} */ 2154 fn: flip, 2155 /** 2156 * @prop {String|Array} behavior='flip' 2157 * The behavior used to change the popper's placement. It can be one of 2158 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 2159 * placements (with optional variations) 2160 */ 2161 behavior: 'flip', 2162 /** 2163 * @prop {number} padding=5 2164 * The popper will flip if it hits the edges of the `boundariesElement` 2165 */ 2166 padding: 5, 2167 /** 2168 * @prop {String|HTMLElement} boundariesElement='viewport' 2169 * The element which will define the boundaries of the popper position. 2170 * The popper will never be placed outside of the defined boundaries 2171 * (except if `keepTogether` is enabled) 2172 */ 2173 boundariesElement: 'viewport' 2174 }, 2175 2176 /** 2177 * Modifier used to make the popper flow toward the inner of the reference element. 2178 * By default, when this modifier is disabled, the popper will be placed outside 2179 * the reference element. 2180 * @memberof modifiers 2181 * @inner 2182 */ 2183 inner: { 2184 /** @prop {number} order=700 - Index used to define the order of execution */ 2185 order: 700, 2186 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 2187 enabled: false, 2188 /** @prop {ModifierFn} */ 2189 fn: inner 2190 }, 2191 2192 /** 2193 * Modifier used to hide the popper when its reference element is outside of the 2194 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 2195 * be used to hide with a CSS selector the popper when its reference is 2196 * out of boundaries. 2197 * 2198 * Requires the `preventOverflow` modifier before it in order to work. 2199 * @memberof modifiers 2200 * @inner 2201 */ 2202 hide: { 2203 /** @prop {number} order=800 - Index used to define the order of execution */ 2204 order: 800, 2205 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2206 enabled: true, 2207 /** @prop {ModifierFn} */ 2208 fn: hide 2209 }, 2210 2211 /** 2212 * Computes the style that will be applied to the popper element to gets 2213 * properly positioned. 2214 * 2215 * Note that this modifier will not touch the DOM, it just prepares the styles 2216 * so that `applyStyle` modifier can apply it. This separation is useful 2217 * in case you need to replace `applyStyle` with a custom implementation. 2218 * 2219 * This modifier has `850` as `order` value to maintain backward compatibility 2220 * with previous versions of Popper.js. Expect the modifiers ordering method 2221 * to change in future major versions of the library. 2222 * 2223 * @memberof modifiers 2224 * @inner 2225 */ 2226 computeStyle: { 2227 /** @prop {number} order=850 - Index used to define the order of execution */ 2228 order: 850, 2229 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2230 enabled: true, 2231 /** @prop {ModifierFn} */ 2232 fn: computeStyle, 2233 /** 2234 * @prop {Boolean} gpuAcceleration=true 2235 * If true, it uses the CSS 3D transformation to position the popper. 2236 * Otherwise, it will use the `top` and `left` properties 2237 */ 2238 gpuAcceleration: true, 2239 /** 2240 * @prop {string} [x='bottom'] 2241 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 2242 * Change this if your popper should grow in a direction different from `bottom` 2243 */ 2244 x: 'bottom', 2245 /** 2246 * @prop {string} [x='left'] 2247 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 2248 * Change this if your popper should grow in a direction different from `right` 2249 */ 2250 y: 'right' 2251 }, 2252 2253 /** 2254 * Applies the computed styles to the popper element. 2255 * 2256 * All the DOM manipulations are limited to this modifier. This is useful in case 2257 * you want to integrate Popper.js inside a framework or view library and you 2258 * want to delegate all the DOM manipulations to it. 2259 * 2260 * Note that if you disable this modifier, you must make sure the popper element 2261 * has its position set to `absolute` before Popper.js can do its work! 2262 * 2263 * Just disable this modifier and define your own to achieve the desired effect. 2264 * 2265 * @memberof modifiers 2266 * @inner 2267 */ 2268 applyStyle: { 2269 /** @prop {number} order=900 - Index used to define the order of execution */ 2270 order: 900, 2271 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2272 enabled: true, 2273 /** @prop {ModifierFn} */
vendor: 4,969 bytes, lines 2274-2412
2274 fn: applyStyle, 2275 /** @prop {Function} */ 2276 onLoad: applyStyleOnLoad, 2277 /** 2278 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 2279 * @prop {Boolean} gpuAcceleration=true 2280 * If true, it uses the CSS 3D transformation to position the popper. 2281 * Otherwise, it will use the `top` and `left` properties 2282 */ 2283 gpuAcceleration: undefined 2284 } 2285}; 2286 2287/** 2288 * The `dataObject` is an object containing all the information used by Popper.js. 2289 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 2290 * @name dataObject 2291 * @property {Object} data.instance The Popper.js instance 2292 * @property {String} data.placement Placement applied to popper 2293 * @property {String} data.originalPlacement Placement originally defined on init 2294 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 2295 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper 2296 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 2297 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) 2298 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) 2299 * @property {Object} data.boundaries Offsets of the popper boundaries 2300 * @property {Object} data.offsets The measurements of popper, reference and arrow elements 2301 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 2302 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 2303 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 2304 */ 2305 2306/** 2307 * Default options provided to Popper.js constructor.<br /> 2308 * These can be overridden using the `options` argument of Popper.js.<br /> 2309 * To override an option, simply pass an object with the same 2310 * structure of the `options` object, as the 3rd argument. For example: 2311 * ``` 2312 * new Popper(ref, pop, { 2313 * modifiers: { 2314 * preventOverflow: { enabled: false } 2315 * } 2316 * }) 2317 * ``` 2318 * @type {Object} 2319 * @static 2320 * @memberof Popper 2321 */ 2322var Defaults = { 2323 /** 2324 * Popper's placement. 2325 * @prop {Popper.placements} placement='bottom' 2326 */ 2327 placement: 'bottom', 2328 2329 /** 2330 * Set this to true if you want popper to position it self in 'fixed' mode 2331 * @prop {Boolean} positionFixed=false 2332 */ 2333 positionFixed: false, 2334 2335 /** 2336 * Whether events (resize, scroll) are initially enabled. 2337 * @prop {Boolean} eventsEnabled=true 2338 */ 2339 eventsEnabled: true, 2340 2341 /** 2342 * Set to true if you want to automatically remove the popper when 2343 * you call the `destroy` method. 2344 * @prop {Boolean} removeOnDestroy=false 2345 */ 2346 removeOnDestroy: false, 2347 2348 /** 2349 * Callback called when the popper is created.<br /> 2350 * By default, it is set to no-op.<br /> 2351 * Access Popper.js instance with `data.instance`. 2352 * @prop {onCreate} 2353 */ 2354 onCreate: function onCreate() {}, 2355 2356 /** 2357 * Callback called when the popper is updated. This callback is not called 2358 * on the initialization/creation of the popper, but only on subsequent 2359 * updates.<br /> 2360 * By default, it is set to no-op.<br /> 2361 * Access Popper.js instance with `data.instance`. 2362 * @prop {onUpdate} 2363 */ 2364 onUpdate: function onUpdate() {}, 2365 2366 /** 2367 * List of modifiers used to modify the offsets before they are applied to the popper. 2368 * They provide most of the functionalities of Popper.js. 2369 * @prop {modifiers} 2370 */ 2371 modifiers: modifiers 2372}; 2373 2374/** 2375 * @callback onCreate 2376 * @param {dataObject} data 2377 */ 2378 2379/** 2380 * @callback onUpdate 2381 * @param {dataObject} data 2382 */ 2383 2384// Utils 2385// Methods 2386var Popper = function () { 2387 /** 2388 * Creates a new Popper.js instance. 2389 * @class Popper 2390 * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper 2391 * @param {HTMLElement} popper - The HTML element used as the popper 2392 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 2393 * @return {Object} instance - The generated Popper.js instance 2394 */ 2395 function Popper(reference, popper) { 2396 var _this = this; 2397 2398 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 2399 classCallCheck(this, Popper); 2400 2401 this.scheduleUpdate = function () { 2402 return requestAnimationFrame(_this.update); 2403 }; 2404 2405 // make update() debounced, so that it only runs at most once-per-tick 2406 this.update = debounce(this.update.bind(this)); 2407 2408 // with {} we create a new object with the options inside it 2409 this.options = _extends({}, Popper.Defaults, options); 2410 2411 // init state 2412 this.state = {
vendor: 4,486 bytes, lines 2413-2542
2413 isDestroyed: false, 2414 isCreated: false, 2415 scrollParents: [] 2416 }; 2417 2418 // get reference and popper elements (allow jQuery wrappers) 2419 this.reference = reference && reference.jquery ? reference[0] : reference; 2420 this.popper = popper && popper.jquery ? popper[0] : popper; 2421 2422 // Deep merge modifiers options 2423 this.options.modifiers = {}; 2424 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 2425 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 2426 }); 2427 2428 // Refactoring modifiers' list (Object => Array) 2429 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 2430 return _extends({ 2431 name: name 2432 }, _this.options.modifiers[name]); 2433 }) 2434 // sort the modifiers by order 2435 .sort(function (a, b) { 2436 return a.order - b.order; 2437 }); 2438 2439 // modifiers have the ability to execute arbitrary code when Popper.js get inited 2440 // such code is executed in the same order of its modifier 2441 // they could add new properties to their options configuration 2442 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 2443 this.modifiers.forEach(function (modifierOptions) { 2444 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 2445 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 2446 } 2447 }); 2448 2449 // fire the first update to position the popper in the right place 2450 this.update(); 2451 2452 var eventsEnabled = this.options.eventsEnabled; 2453 if (eventsEnabled) { 2454 // setup event listeners, they will take care of update the position in specific situations 2455 this.enableEventListeners(); 2456 } 2457 2458 this.state.eventsEnabled = eventsEnabled; 2459 } 2460 2461 // We can't use class properties because they don't get listed in the 2462 // class prototype and break stuff like Sinon stubs 2463 2464 2465 createClass(Popper, [{ 2466 key: 'update', 2467 value: function update$$1() { 2468 return update.call(this); 2469 } 2470 }, { 2471 key: 'destroy', 2472 value: function destroy$$1() { 2473 return destroy.call(this); 2474 } 2475 }, { 2476 key: 'enableEventListeners', 2477 value: function enableEventListeners$$1() { 2478 return enableEventListeners.call(this); 2479 } 2480 }, { 2481 key: 'disableEventListeners', 2482 value: function disableEventListeners$$1() { 2483 return disableEventListeners.call(this); 2484 } 2485 2486 /** 2487 * Schedules an update. It will run on the next UI update available. 2488 * @method scheduleUpdate 2489 * @memberof Popper 2490 */ 2491 2492 2493 /** 2494 * Collection of utilities useful when writing custom modifiers. 2495 * Starting from version 1.7, this method is available only if you 2496 * include `popper-utils.js` before `popper.js`. 2497 * 2498 * **DEPRECATION**: This way to access PopperUtils is deprecated 2499 * and will be removed in v2! Use the PopperUtils module directly instead. 2500 * Due to the high instability of the methods contained in Utils, we can't 2501 * guarantee them to follow semver. Use them at your own risk! 2502 * @static 2503 * @private 2504 * @type {Object} 2505 * @deprecated since version 1.8 2506 * @member Utils 2507 * @memberof Popper 2508 */ 2509 2510 }]); 2511 return Popper; 2512}(); 2513 2514/** 2515 * The `referenceObject` is an object that provides an interface compatible with Popper.js 2516 * and lets you use it as replacement of a real DOM node.<br /> 2517 * You can use this method to position a popper relatively to a set of coordinates 2518 * in case you don't have a DOM node to use as reference. 2519 * 2520 * ``` 2521 * new Popper(referenceObject, popperNode); 2522 * ``` 2523 * 2524 * NB: This feature isn't supported in Internet Explorer 10. 2525 * @name referenceObject 2526 * @property {Function} data.getBoundingClientRect 2527 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 2528 * @property {number} data.clientWidth 2529 * An ES6 getter that will return the width of the virtual reference element. 2530 * @property {number} data.clientHeight 2531 * An ES6 getter that will return the height of the virtual reference element. 2532 */ 2533 2534 2535Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 2536Popper.placements = placements; 2537Popper.Defaults = Defaults; 2538 2539return Popper; 2540 2541}))); 2542//# 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.