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