vendor: 6,603 bytes, lines 1-200
1/**! 2 * @fileOverview Kickass library to create and place poppers near their reference elements. 3 * @version 1.14.6 4 * @license 5 * Copyright (c) 2016 Federico Zivolo and contributors 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 */ 25(function (global, factory) { 26 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 27 typeof define === 'function' && define.amd ? define(factory) : 28 (global.Popper = factory()); 29}(this, (function () { 'use strict'; 30 31 var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; 32 33 var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 34 var timeoutDuration = 0; 35 for (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 42 function 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 56 function 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 69 var 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 */ 80 var 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 */ 89 function 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 */ 101 function 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 */ 118 function 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 */ 132 function 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 160 var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 161 var 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 */ 170 function 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 */ 187 function 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: 4,363 bytes, lines 201-317
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 216 function 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 */ 232 function 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 */ 248 function findCommonOffsetParent(element1, element2) { 249 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 250 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 251 return document.documentElement; 252 } 253 254 // Here we make sure to give as "start" the element that comes first in the DOM 255 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 256 var start = order ? element1 : element2; 257 var end = order ? element2 : element1; 258 259 // Get common ancestor container 260 var range = document.createRange(); 261 range.setStart(start, 0); 262 range.setEnd(end, 0); 263 var commonAncestorContainer = range.commonAncestorContainer; 264 265 // Both nodes are inside #document 266 267 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 268 if (isOffsetContainer(commonAncestorContainer)) { 269 return commonAncestorContainer; 270 } 271 272 return getOffsetParent(commonAncestorContainer); 273 } 274 275 // one of the nodes is inside shadowDOM, find which one 276 var element1root = getRoot(element1); 277 if (element1root.host) { 278 return findCommonOffsetParent(element1root.host, element2); 279 } else { 280 return findCommonOffsetParent(element1, getRoot(element2).host); 281 } 282 } 283 284 /** 285 * Gets the scroll value of the given element in the given side (top and left) 286 * @method 287 * @memberof Popper.Utils 288 * @argument {Element} element 289 * @argument {String} side `top` or `left` 290 * @returns {number} amount of scrolled pixels 291 */ 292 function 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 */ 316 function includeScroll(rect, element) { 317 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
vendor: 8,402 bytes, lines 318-541
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 339 function 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 346 function 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 350 function 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 361 var classCallCheck = function (instance, Constructor) { 362 if (!(instance instanceof Constructor)) { 363 throw new TypeError("Cannot call a class as a function"); 364 } 365 }; 366 367 var 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 389 var 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 404 var _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 */ 425 function 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 */ 439 function 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 488 function 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 540 function getViewportOffsetRectRelativeToArtbitraryNode(element) { 541 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
vendor: 7,514 bytes, lines 542-740
542 543 var html = element.ownerDocument.documentElement; 544 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 545 var width = Math.max(html.clientWidth, window.innerWidth || 0); 546 var height = Math.max(html.clientHeight, window.innerHeight || 0); 547 548 var scrollTop = !excludeScroll ? getScroll(html) : 0; 549 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 550 551 var offset = { 552 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 553 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 554 width: width, 555 height: height 556 }; 557 558 return getClientRect(offset); 559 } 560 561 /** 562 * Check if the given element is fixed or is inside a fixed parent 563 * @method 564 * @memberof Popper.Utils 565 * @argument {Element} element 566 * @argument {Element} customContainer 567 * @returns {Boolean} answer to "isFixed?" 568 */ 569 function 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 588 function 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 */ 611 function 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 665 function 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 */ 681 function 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}
740 An object containing the offsets which will be applied to the popper 741 */ 742 function 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} object containing width and height properties 755 */ 756 function getOuterSizes(element) { 757 var window = element.ownerDocument.defaultView; 758 var styles = window.getComputedStyle(element); 759 var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); 760 var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0
vendor: 5,077 bytes, lines 760-903
760); 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 */ 775 function 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 */ 792 function 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 */ 830 function 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 */ 849 function 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 */ 874 function 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: 9,724 bytes, lines 904-1174
904 function 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 */ 956 function 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 */ 971 function 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 */ 990 function 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 */ 1020 function getWindow(element) { 1021 var ownerDocument = element.ownerDocument; 1022 return ownerDocument ? ownerDocument.defaultView : window; 1023 } 1024 1025 function 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 */ 1042 function 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 */ 1062 function 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 */ 1074 function 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 */ 1098 function 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 */ 1112 function 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 */ 1124 function 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 */ 1143 function 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 */ 1163 function 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 */ 1192 function 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 Popper.Utils 1213 * @argument {Object} data - The data object generated by `update` method 1214 * @argument {Boolean} shouldRound - If the offsets should be rounded at all 1215 * @returns {Object} The popper's position offsets rounded 1216 * 1217 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as 1218 * good as it can be within reason. 1219 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 1220 * 1221 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari 1222 * as well on High DPI screens). 1223 * 1224 * Firefox prefers no rounding for positioning and does not have blurriness on 1225 * high DPI screens. 1226 * 1227 * Only horizontal placement and left/right values need to be considered. 1228 */ 1229 function getRoundedOffsets(data, shouldRound) { 1230 var _data$offsets = data.offsets, 1231 popper = _data$offsets.popper, 1232 reference = _data$offsets.reference; 1233 1234 1235 var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; 1236 var isVariation = data.placement.indexOf('-') !== -1; 1237 var sameWidthOddness = reference.width % 2 === popper.width % 2; 1238 var bothOddWidth = reference.width % 2 === 1 && popper.width % 2 === 1; 1239 var noRound = function noRound(v) { 1240 return v; 1241 }; 1242 1243 var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthOddness ? Math.round : Math.floor; 1244 var verticalToInteger = !shouldRound ? noRound : Math.round; 1245 1246 return { 1247 left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), 1248 top: verticalToInteger(popper.top), 1249 bottom: verticalToInteger(popper.bottom), 1250 right: horizontalToInteger(popper.right) 1251 }; 1252 } 1253 1254 var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); 1255 1256 /** 1257 * @function 1258 * @memberof Modifiers 1259 * @argument {Object} data - The data object generated by `update` method 1260 * @argument {Object} options - Modifiers configuration and options 1261 * @returns {Object} The data object, properly modified 1262 */ 1263 function computeStyle(data, options) { 1264 var x = options.x, 1265 y = options.y; 1266 var popper = data.offsets.popper; 1267 1268 // Remove this legacy support in Popper.js v2 1269 1270 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
vendor: 4,329 bytes, lines 1271-1370
1271 return modifier.name === 'applyStyle'; 1272 }).gpuAcceleration; 1273 if (legacyGpuAccelerationOption !== undefined) { 1274 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 1275 } 1276 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 1277 1278 var offsetParent = getOffsetParent(data.instance.popper); 1279 var offsetParentRect = getBoundingClientRect(offsetParent); 1280 1281 // Styles 1282 var styles = { 1283 position: popper.position 1284 }; 1285 1286 var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); 1287 1288 var sideA = x === 'bottom' ? 'top' : 'bottom'; 1289 var sideB = y === 'right' ? 'left' : 'right'; 1290 1291 // if gpuAcceleration is set to `true` and transform is supported, 1292 // we use `translate3d` to apply the position to the popper we 1293 // automatically use the supported prefixed version if needed 1294 var prefixedProperty = getSupportedPropertyName('transform'); 1295 1296 // now, let's make a step back and look at this code closely (wtf?) 1297 // If the content of the popper grows once it's been positioned, it 1298 // may happen that the popper gets misplaced because of the new content 1299 // overflowing its reference element 1300 // To avoid this problem, we provide two options (x and y), which allow 1301 // the consumer to define the offset origin. 1302 // If we position a popper on top of a reference element, we can set 1303 // `x` to `top` to make the popper grow towards its top instead of 1304 // its bottom. 1305 var left = void 0, 1306 top = void 0; 1307 if (sideA === 'bottom') { 1308 // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar) 1309 // and not the bottom of the html element 1310 if (offsetParent.nodeName === 'HTML') { 1311 top = -offsetParent.clientHeight + offsets.bottom; 1312 } else { 1313 top = -offsetParentRect.height + offsets.bottom; 1314 } 1315 } else { 1316 top = offsets.top; 1317 } 1318 if (sideB === 'right') { 1319 if (offsetParent.nodeName === 'HTML') { 1320 left = -offsetParent.clientWidth + offsets.right; 1321 } else { 1322 left = -offsetParentRect.width + offsets.right; 1323 } 1324 } else { 1325 left = offsets.left; 1326 } 1327 if (gpuAcceleration && prefixedProperty) { 1328 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 1329 styles[sideA] = 0; 1330 styles[sideB] = 0; 1331 styles.willChange = 'transform'; 1332 } else { 1333 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 1334 var invertTop = sideA === 'bottom' ? -1 : 1; 1335 var invertLeft = sideB === 'right' ? -1 : 1; 1336 styles[sideA] = top * invertTop; 1337 styles[sideB] = left * invertLeft; 1338 styles.willChange = sideA + ', ' + sideB; 1339 } 1340 1341 // Attributes 1342 var attributes = { 1343 'x-placement': data.placement 1344 }; 1345 1346 // Update `data` attributes, styles and arrowStyles 1347 data.attributes = _extends({}, attributes, data.attributes); 1348 data.styles = _extends({}, styles, data.styles); 1349 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 1350 1351 return data; 1352 } 1353 1354 /** 1355 * Helper used to know if the given modifier depends from another one.<br /> 1356 * It checks if the needed modifier is listed and enabled. 1357 * @method 1358 * @memberof Popper.Utils 1359 * @param {Array} modifiers - list of modifiers 1360 * @param {String} requestingName - name of requesting modifier 1361 * @param {String} requestedName - name of requested modifier 1362 * @returns {Boolean} 1363 */ 1364 function isModifierRequired(modifiers, requestingName, requestedName) { 1365 var requesting = find(modifiers, function (_ref) { 1366 var name = _ref.name; 1367 return name === requestingName; 1368 }); 1369 1370 var isRequired = !!requesting && modifiers.some(function (modifier) {
vendor: 4,719 bytes, lines 1371-1490
1371 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 1372 }); 1373 1374 if (!isRequired) { 1375 var _requesting = '`' + requestingName + '`'; 1376 var requested = '`' + requestedName + '`'; 1377 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 1378 } 1379 return isRequired; 1380 } 1381 1382 /** 1383 * @function 1384 * @memberof Modifiers 1385 * @argument {Object} data - The data object generated by update method 1386 * @argument {Object} options - Modifiers configuration and options 1387 * @returns {Object} The data object, properly modified 1388 */ 1389 function arrow(data, options) { 1390 var _data$offsets$arrow; 1391 1392 // arrow depends on keepTogether in order to work 1393 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 1394 return data; 1395 } 1396 1397 var arrowElement = options.element; 1398 1399 // if arrowElement is a string, suppose it's a CSS selector 1400 if (typeof arrowElement === 'string') { 1401 arrowElement = data.instance.popper.querySelector(arrowElement); 1402 1403 // if arrowElement is not found, don't run the modifier 1404 if (!arrowElement) { 1405 return data; 1406 } 1407 } else { 1408 // if the arrowElement isn't a query selector we must check that the 1409 // provided DOM node is child of its popper node 1410 if (!data.instance.popper.contains(arrowElement)) { 1411 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 1412 return data; 1413 } 1414 } 1415 1416 var placement = data.placement.split('-')[0]; 1417 var _data$offsets = data.offsets, 1418 popper = _data$offsets.popper, 1419 reference = _data$offsets.reference; 1420 1421 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 1422 1423 var len = isVertical ? 'height' : 'width'; 1424 var sideCapitalized = isVertical ? 'Top' : 'Left'; 1425 var side = sideCapitalized.toLowerCase(); 1426 var altSide = isVertical ? 'left' : 'top'; 1427 var opSide = isVertical ? 'bottom' : 'right'; 1428 var arrowElementSize = getOuterSizes(arrowElement)[len]; 1429 1430 // 1431 // extends keepTogether behavior making sure the popper and its 1432 // reference have enough pixels in conjunction 1433 // 1434 1435 // top/left side 1436 if (reference[opSide] - arrowElementSize < popper[side]) { 1437 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 1438 } 1439 // bottom/right side 1440 if (reference[side] + arrowElementSize > popper[opSide]) { 1441 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 1442 } 1443 data.offsets.popper = getClientRect(data.offsets.popper); 1444 1445 // compute center of the popper 1446 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 1447 1448 // Compute the sideValue using the updated popper offsets 1449 // take popper margin in account because we don't have this info available 1450 var css = getStyleComputedProperty(data.instance.popper); 1451 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 1452 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 1453 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 1454 1455 // prevent arrowElement from being placed not contiguously to its popper 1456 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 1457 1458 data.arrowElement = arrowElement; 1459 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 1460 1461 return data; 1462 } 1463 1464 /** 1465 * Get the opposite placement variation of the given one 1466 * @method 1467 * @memberof Popper.Utils 1468 * @argument {String} placement variation 1469 * @returns {String} flipped placement variation 1470 */ 1471 function getOppositeVariation(variation) { 1472 if (variation === 'end') { 1473 return 'start'; 1474 } else if (variation === 'start') { 1475 return 'end'; 1476 } 1477 return variation; 1478 } 1479 1480 /** 1481 * List of accepted placements to use as values of the `placement` option.<br /> 1482 * Valid placements are: 1483 * - `auto` 1484 * - `top` 1485 * - `right` 1486 * - `bottom` 1487 * - `left` 1488 * 1489 * Each placement can have a variation from this list: 1490 * - `-start`
1491 * - `-end` 1492 * 1493 * Variations are interpreted easily if you think of them as the left to right 1494 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 1495 * is right.<br /> 1496 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 1497 * 1498 * Some valid examples are: 1499 * - `top-end` (on top of reference, right aligned) 1500 * - `right-start` (on right of reference, top aligned) 1501 * - `bottom` (on bottom, centered) 1502 * - `auto-end` (on the side with more space available, alignment depends by placement) 1503 * 1504 * @static 1505 * @type {Array} 1506 * @enum {String} 1507 * @readonly 1508 * @method placements 1509 * @memberof Popper 1510 */ 1511 var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; 1512 1513// Get rid of `auto` `auto-start` and `auto-end` 1514 var validPlacements = placements.slice(3); 1515 1516 /** 1517 * Given an initial placement, returns all the subsequent placements 1518 * clockwise (or counter-clockwise). 1519 * 1520 * @method 1521 * @memberof Popper.Utils 1522 * @argument {String} placement - A valid placement (it accepts variations) 1523 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 1524 * @returns {Array} placements including their variations 1525 */ 1526 function clockwise(placement) { 1527 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 1528 1529 var index = validPlacements.indexOf(placement); 1530 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 1531 return counter ? arr.reverse() : arr; 1532 } 1533 1534 var BEHAVIORS = { 1535 FLIP: 'flip', 1536 CLOCKWISE: 'clockwise', 1537 COUNTERCLOCKWISE: 'counterclockwise' 1538 }; 1539 1540 /** 1541 * @function 1542 * @memberof Modifiers 1543 * @argument {Object} data - The data object generated by update method 1544 * @argument {Object} options - Modifiers configuration and options 1545 * @returns {Object} The data object, properly modified 1546 */ 1547 function flip(data, options) { 1548 // if `inner` modifier is enabled, we can't use the `flip` modifier 1549 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 1550 return data; 1551 } 1552 1553 if (data.flipped && data.placement === data.originalPlacement) { 1554 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 1555 return data; 1556 } 1557 1558 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 1559 1560 var placement = data.placement.split('-')[0]; 1561 var placementOpposite = getOppositePlacement(placement); 1562 var variation = data.placement.split('-')[1] || ''; 1563 1564 var flipOrder = []; 1565 1566 switch (options.behavior) { 1567 case BEHAVIORS.FLIP: 1568 flipOrder = [placement, placementOpposite]; 1569 break; 1570 case BEHAVIORS.CLOCKWISE: 1571 flipOrder = clockwise(placement); 1572 break; 1573 case BEHAVIORS.COUNTERCLOCKWISE: 1574 flipOrder = clockwise(placement, true); 1575 break; 1576 default: 1577 flipOrder = options.behavior; 1578 } 1579 1580 flipOrder.forEach(function (step, index) { 1581 if (placement !== step || flipOrder.length === index + 1) { 1582 return data; 1583 } 1584 1585 placement = data.placement.split('-')[0]; 1586 placementOpposite = getOppositePlacement(placement); 1587 1588 var popperOffsets = data.offsets.popper; 1589 var refOffsets = data.offsets.reference; 1590 1591 // using floor because the reference offsets may contain decimals we are not going to consider here 1592 var floor = Math.floor; 1593 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); 1594 1595 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 1596 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 1597 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 1598 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 1599 1600 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 1601 1602 // flip the variation if required 1603 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1604 var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 1605 1606 if (overlapsRef || overflowsBoundaries || flippedVariation) { 1607 // this boolean to detect any flip loop 1608 data.flipped = true; 1609 1610 if (overlapsRef || overflowsBoundaries) { 1611 placement = flipOrder[index + 1]; 1612 } 1613 1614 if (flippedVariation) { 1615 variation = getOppositeVariation(variation); 1616 } 1617 1618 data.placement = placement + (variation ? '-' + variation : ''); 1619
vendor: 17,373 bytes, lines 1620-2055
1620 // this object contains `position`, we want to preserve it along with 1621 // any additional property we may add in the future 1622 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 1623 1624 data = runModifiers(data.instance.modifiers, data, 'flip'); 1625 } 1626 }); 1627 return data; 1628 } 1629 1630 /** 1631 * @function 1632 * @memberof Modifiers 1633 * @argument {Object} data - The data object generated by update method 1634 * @argument {Object} options - Modifiers configuration and options 1635 * @returns {Object} The data object, properly modified 1636 */ 1637 function keepTogether(data) { 1638 var _data$offsets = data.offsets, 1639 popper = _data$offsets.popper, 1640 reference = _data$offsets.reference; 1641 1642 var placement = data.placement.split('-')[0]; 1643 var floor = Math.floor; 1644 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 1645 var side = isVertical ? 'right' : 'bottom'; 1646 var opSide = isVertical ? 'left' : 'top'; 1647 var measurement = isVertical ? 'width' : 'height'; 1648 1649 if (popper[side] < floor(reference[opSide])) { 1650 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 1651 } 1652 if (popper[opSide] > floor(reference[side])) { 1653 data.offsets.popper[opSide] = floor(reference[side]); 1654 } 1655 1656 return data; 1657 } 1658 1659 /** 1660 * Converts a string containing value + unit into a px value number 1661 * @function 1662 * @memberof {modifiers~offset} 1663 * @private 1664 * @argument {String} str - Value + unit string 1665 * @argument {String} measurement - `height` or `width` 1666 * @argument {Object} popperOffsets 1667 * @argument {Object} referenceOffsets 1668 * @returns {Number|String} 1669 * Value in pixels, or original string if no values were extracted 1670 */ 1671 function toValue(str, measurement, popperOffsets, referenceOffsets) { 1672 // separate value from unit 1673 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 1674 var value = +split[1]; 1675 var unit = split[2]; 1676 1677 // If it's not a number it's an operator, I guess 1678 if (!value) { 1679 return str; 1680 } 1681 1682 if (unit.indexOf('%') === 0) { 1683 var element = void 0; 1684 switch (unit) { 1685 case '%p': 1686 element = popperOffsets; 1687 break; 1688 case '%': 1689 case '%r': 1690 default: 1691 element = referenceOffsets; 1692 } 1693 1694 var rect = getClientRect(element); 1695 return rect[measurement] / 100 * value; 1696 } else if (unit === 'vh' || unit === 'vw') { 1697 // if is a vh or vw, we calculate the size based on the viewport 1698 var size = void 0; 1699 if (unit === 'vh') { 1700 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 1701 } else { 1702 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 1703 } 1704 return size / 100 * value; 1705 } else { 1706 // if is an explicit pixel unit, we get rid of the unit and keep the value 1707 // if is an implicit unit, it's px, and we return just the value 1708 return value; 1709 } 1710 } 1711 1712 /** 1713 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 1714 * @function 1715 * @memberof {modifiers~offset} 1716 * @private 1717 * @argument {String} offset 1718 * @argument {Object} popperOffsets 1719 * @argument {Object} referenceOffsets 1720 * @argument {String} basePlacement 1721 * @returns {Array} a two cells array with x and y offsets in numbers 1722 */ 1723 function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 1724 var offsets = [0, 0]; 1725 1726 // Use height if placement is left or right and index is 0 otherwise use width 1727 // in this way the first offset will use an axis and the second one 1728 // will use the other one 1729 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 1730 1731 // Split the offset string to obtain a list of values and operands 1732 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 1733 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 1734 return frag.trim(); 1735 }); 1736 1737 // Detect if the offset string contains a pair of values or a single one 1738 // they could be separated by comma or space 1739 var divider = fragments.indexOf(find(fragments, function (frag) { 1740 return frag.search(/,|\s/) !== -1; 1741 })); 1742 1743 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 1744 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 1745 } 1746 1747 // If divider is found, we divide the list of values and operands to divide 1748 // them by ofset X and Y. 1749 var splitRegex = /\s*,\s*|\s+/; 1750 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]; 1751 1752 // Convert the values with units to absolute pixels to allow our computations 1753 ops = ops.map(function (op, index) { 1754 // Most of the units rely on the orientation of the popper 1755 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 1756 var mergeWithPrevious = false; 1757 return op 1758 // This aggregates any `+` or `-` sign that aren't considered operators 1759 // e.g.: 10 + +5 => [10, +, +5] 1760 .reduce(function (a, b) { 1761 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 1762 a[a.length - 1] = b; 1763 mergeWithPrevious = true; 1764 return a; 1765 } else if (mergeWithPrevious) { 1766 a[a.length - 1] += b; 1767 mergeWithPrevious = false; 1768 return a; 1769 } else { 1770 return a.concat(b); 1771 } 1772 }, []) 1773 // Here we convert the string values into number values (in px) 1774 .map(function (str) { 1775 return toValue(str, measurement, popperOffsets, referenceOffsets); 1776 }); 1777 }); 1778 1779 // Loop trough the offsets arrays and execute the operations 1780 ops.forEach(function (op, index) { 1781 op.forEach(function (frag, index2) { 1782 if (isNumeric(frag)) { 1783 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 1784 } 1785 }); 1786 }); 1787 return offsets; 1788 } 1789 1790 /** 1791 * @function 1792 * @memberof Modifiers 1793 * @argument {Object} data - The data object generated by update method 1794 * @argument {Object} options - Modifiers configuration and options 1795 * @argument {Number|String} options.offset=0 1796 * The offset value as described in the modifier description 1797 * @returns {Object} The data object, properly modified 1798 */ 1799 function offset(data, _ref) { 1800 var offset = _ref.offset; 1801 var placement = data.placement, 1802 _data$offsets = data.offsets, 1803 popper = _data$offsets.popper, 1804 reference = _data$offsets.reference; 1805 1806 var basePlacement = placement.split('-')[0]; 1807 1808 var offsets = void 0; 1809 if (isNumeric(+offset)) { 1810 offsets = [+offset, 0]; 1811 } else { 1812 offsets = parseOffset(offset, popper, reference, basePlacement); 1813 } 1814 1815 if (basePlacement === 'left') { 1816 popper.top += offsets[0]; 1817 popper.left -= offsets[1]; 1818 } else if (basePlacement === 'right') { 1819 popper.top += offsets[0]; 1820 popper.left += offsets[1]; 1821 } else if (basePlacement === 'top') { 1822 popper.left += offsets[0]; 1823 popper.top -= offsets[1]; 1824 } else if (basePlacement === 'bottom') { 1825 popper.left += offsets[0]; 1826 popper.top += offsets[1]; 1827 } 1828 1829 data.popper = popper; 1830 return data; 1831 } 1832 1833 /** 1834 * @function 1835 * @memberof Modifiers 1836 * @argument {Object} data - The data object generated by `update` method 1837 * @argument {Object} options - Modifiers configuration and options 1838 * @returns {Object} The data object, properly modified 1839 */ 1840 function preventOverflow(data, options) { 1841 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 1842 1843 // If offsetParent is the reference element, we really want to 1844 // go one step up and use the next offsetParent as reference to 1845 // avoid to make this modifier completely useless and look like broken 1846 if (data.instance.reference === boundariesElement) { 1847 boundariesElement = getOffsetParent(boundariesElement); 1848 } 1849 1850 // NOTE: DOM access here 1851 // resets the popper's position so that the document size can be calculated excluding 1852 // the size of the popper element itself 1853 var transformProp = getSupportedPropertyName('transform'); 1854 var popperStyles = data.instance.popper.style; // assignment to help minification 1855 var top = popperStyles.top, 1856 left = popperStyles.left, 1857 transform = popperStyles[transformProp]; 1858 1859 popperStyles.top = ''; 1860 popperStyles.left = ''; 1861 popperStyles[transformProp] = ''; 1862 1863 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 1864 1865 // NOTE: DOM access here 1866 // restores the original style properties after the offsets have been computed 1867 popperStyles.top = top; 1868 popperStyles.left = left; 1869 popperStyles[transformProp] = transform; 1870 1871 options.boundaries = boundaries; 1872 1873 var order = options.priority; 1874 var popper = data.offsets.popper; 1875 1876 var check = { 1877 primary: function primary(placement) { 1878 var value = popper[placement]; 1879 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 1880 value = Math.max(popper[placement], boundaries[placement]); 1881 } 1882 return defineProperty({}, placement, value); 1883 }, 1884 secondary: function secondary(placement) { 1885 var mainSide = placement === 'right' ? 'left' : 'top'; 1886 var value = popper[mainSide]; 1887 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 1888 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 1889 } 1890 return defineProperty({}, mainSide, value); 1891 } 1892 }; 1893 1894 order.forEach(function (placement) { 1895 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 1896 popper = _extends({}, popper, check[side](placement)); 1897 }); 1898 1899 data.offsets.popper = popper; 1900 1901 return data; 1902 } 1903 1904 /** 1905 * @function 1906 * @memberof Modifiers 1907 * @argument {Object} data - The data object generated by `update` method 1908 * @argument {Object} options - Modifiers configuration and options 1909 * @returns {Object} The data object, properly modified 1910 */ 1911 function shift(data) { 1912 var placement = data.placement; 1913 var basePlacement = placement.split('-')[0]; 1914 var shiftvariation = placement.split('-')[1]; 1915 1916 // if shift shiftvariation is specified, run the modifier 1917 if (shiftvariation) { 1918 var _data$offsets = data.offsets, 1919 reference = _data$offsets.reference, 1920 popper = _data$offsets.popper; 1921 1922 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 1923 var side = isVertical ? 'left' : 'top'; 1924 var measurement = isVertical ? 'width' : 'height'; 1925 1926 var shiftOffsets = { 1927 start: defineProperty({}, side, reference[side]), 1928 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 1929 }; 1930 1931 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 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 */ 1944 function hide(data) { 1945 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 1946 return data; 1947 } 1948 1949 var refRect = data.offsets.reference; 1950 var bound = find(data.instance.modifiers, function (modifier) { 1951 return modifier.name === 'preventOverflow'; 1952 }).boundaries; 1953 1954 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 1955 // Avoid unnecessary DOM access if visibility hasn't changed 1956 if (data.hide === true) { 1957 return data; 1958 } 1959 1960 data.hide = true; 1961 data.attributes['x-out-of-boundaries'] = ''; 1962 } else { 1963 // Avoid unnecessary DOM access if visibility hasn't changed 1964 if (data.hide === false) { 1965 return data; 1966 } 1967 1968 data.hide = false; 1969 data.attributes['x-out-of-boundaries'] = false; 1970 } 1971 1972 return data; 1973 } 1974 1975 /** 1976 * @function 1977 * @memberof Modifiers 1978 * @argument {Object} data - The data object generated by `update` method 1979 * @argument {Object} options - Modifiers configuration and options 1980 * @returns {Object} The data object, properly modified 1981 */ 1982 function inner(data) { 1983 var placement = data.placement; 1984 var basePlacement = placement.split('-')[0]; 1985 var _data$offsets = data.offsets, 1986 popper = _data$offsets.popper, 1987 reference = _data$offsets.reference; 1988 1989 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 1990 1991 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 1992 1993 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 1994 1995 data.placement = getOppositePlacement(placement); 1996 data.offsets.popper = getClientRect(popper); 1997 1998 return data; 1999 } 2000 2001 /** 2002 * Modifier function, each modifier can have a function of this type assigned 2003 * to its `fn` property.<br /> 2004 * These functions will be called on each update, this means that you must 2005 * make sure they are performant enough to avoid performance bottlenecks. 2006 * 2007 * @function ModifierFn 2008 * @argument {dataObject} data - The data object generated by `update` method 2009 * @argument {Object} options - Modifiers configuration and options 2010 * @returns {dataObject} The data object, properly modified 2011 */ 2012 2013 /** 2014 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 2015 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 2016 * needed by the library. 2017 * 2018 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 2019 * All the other properties are configurations that could be tweaked. 2020 * @namespace modifiers 2021 */ 2022 var modifiers = { 2023 /** 2024 * Modifier used to shift the popper on the start or end of its reference 2025 * element.<br /> 2026 * It will read the variation of the `placement` property.<br /> 2027 * It can be one either `-end` or `-start`. 2028 * @memberof modifiers 2029 * @inner 2030 */ 2031 shift: { 2032 /** @prop {number} order=100 - Index used to define the order of execution */ 2033 order: 100, 2034 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2035 enabled: true, 2036 /** @prop {ModifierFn} */ 2037 fn: shift 2038 }, 2039 2040 /** 2041 * The `offset` modifier can shift your popper on both its axis. 2042 * 2043 * It accepts the following units: 2044 * - `px` or unit-less, interpreted as pixels 2045 * - `%` or `%r`, percentage relative to the length of the reference element 2046 * - `%p`, percentage relative to the length of the popper element 2047 * - `vw`, CSS viewport width unit 2048 * - `vh`, CSS viewport height unit 2049 * 2050 * For length is intended the main axis relative to the placement of the popper.<br /> 2051 * This means that if the placement is `top` or `bottom`, the length will be the 2052 * `width`. In case of `left` or `right`, it will be the `height`. 2053 * 2054 * You can provide a single value (as `Number` or `String`), or a pair of values 2055 * as `String` divided by a comma or one (or more) white space
2055s.<br /> 2056 * The latter is a deprecated method because it leads to confusion and will be 2057 * removed in v2.<br /> 2058 * Additionally, it accepts additions and subtractions between different units. 2059 * Note that multiplications and divisions aren't supported. 2060 * 2061 * Valid examples are: 2062 * ``` 2063 * 10 2064 * '10%' 2065 * '10, 10' 2066 * '10%, 10' 2067 * '10 + 10%' 2068 * '10 - 5vh + 3%' 2069 * '-10px + 5vh, 5px - 6%' 2070 * ``` 2071 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 2072 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 2073 * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). 2074 * 2075 * @memberof modifiers 2076 * @inner 2077 */ 2078 offset: { 2079 /** @prop {number} order=200 - Index used to define the order of execution */ 2080 order: 200, 2081 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2082 enabled: true, 2083 /** @prop {ModifierFn} */ 2084 fn: offset, 2085 /** @prop {Number|String} offset=0 2086 * The offset value as described in the modifier description 2087 */ 2088 offset: 0 2089 }, 2090 2091 /** 2092 * Modifier used to prevent the popper from being positioned outside the boundary. 2093 * 2094 * A scenario exists where the reference itself is not within the boundaries.<br /> 2095 * We can say it has "escaped the boundaries" â or just "escaped".<br /> 2096 * In this case we need to decide whether the popper should either: 2097 * 2098 * - detach from the reference and remain "trapped" in the boundaries, or 2099 * - if it should ignore the boundary and "escape with its reference" 2100 * 2101 * When `escapeWithReference` is set to`true` and reference is completely 2102 * outside its boundaries, the popper will overflow (or completely leave) 2103 * the boundaries in order to remain attached to the edge of the reference. 2104 * 2105 * @memberof modifiers 2106 * @inner 2107 */ 2108 preventOverflow: { 2109 /** @prop {number} order=300 - Index used to define the order of execution */ 2110 order: 300, 2111 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2112 enabled: true, 2113 /** @prop {ModifierFn} */ 2114 fn: preventOverflow, 2115 /** 2116 * @prop {Array} [priority=['left','right','top','bottom']] 2117 * Popper will try to prevent overflow following these priorities by default, 2118 * then, it could overflow on the left and on top of the `boundariesElement` 2119 */ 2120 priority: ['left', 'right', 'top', 'bottom'], 2121 /** 2122 * @prop {number} padding=5 2123 * Amount of pixel used to define a minimum distance between the boundaries 2124 * and the popper. This makes sure the popper always has a little padding 2125 * between the edges of its container 2126 */ 2127 padding: 5, 2128 /** 2129 * @prop {String|HTMLElement} boundariesElement='scrollParent' 2130 * Boundaries used by the modifier. Can be `scrollParent`, `window`, 2131 * `viewport` or any DOM element. 2132 */ 2133 boundariesElement: 'scrollParent' 2134 }, 2135 2136 /** 2137 * Modifier used to make sure the reference and its popper stay near each other 2138 * without leaving any gap between the two. Especially useful when the arrow is 2139 * enabled and you want to ensure that it points to its reference element. 2140 * It cares only about the first axis. You can still have poppers with margin 2141 * between the popper and its reference element. 2142 * @memberof modifiers 2143 * @inner 2144 */ 2145 keepTogether: { 2146 /** @prop {number} order=400 - Index used to define the order of execution */ 2147 order: 400, 2148 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2149 enabled: true, 2150 /** @prop {ModifierFn} */ 2151 fn: keepTogether 2152 }, 2153 2154 /** 2155 * This modifier is used to move the `arrowElement` of the popper to make 2156 * sure it is positioned between the reference element and its popper element. 2157 * It will read the outer size of the `arrowElement` node to detect how many 2158 * pixels of conjunction are needed. 2159 * 2160 * It has no effect if no `arrowElement` is provided. 2161 * @memberof modifiers 2162 * @inner 2163 */ 2164 arrow: { 2165 /** @prop {number} order=500 - Index used to define the order of execution */ 2166 order: 500, 2167 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2168 enabled: true, 2169 /** @prop {ModifierFn} */ 2170 fn: arrow, 2171 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 2172 element: '[x-arrow]' 2173 }, 2174 2175 /** 2176 * Modifier used to flip the popper's placement when it starts to overlap its 2177 * reference element. 2178 * 2179 * Requires the `preventOverflow` modifier before it in order to work. 2180 * 2181 * **NOTE:** this modifier will interrupt the current update cycle and will 2182 * restart it if it detects the need to flip the placement. 2183 * @memberof modifiers 2184 * @inner 2185 */ 2186 flip: { 2187 /** @prop {number} order=600 - Index used to define the order of execution */ 2188 order: 600, 2189 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2190 enabled: true, 2191 /** @prop {ModifierFn} */ 2192 fn: flip, 2193 /** 2194 * @prop {String|Array} behavior='flip' 2195 * The behavior used to change the popper's placement. It can be one of 2196 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 2197 * placements (with optional variations) 2198 */ 2199 behavior: 'flip', 2200 /** 2201 * @prop {number} padding=5 2202 * The popper will flip if it hits the edges of the `boundariesElement` 2203 */ 2204 padding: 5, 2205 /** 2206 * @prop {String|HTMLElement} boundariesElement='viewport' 2207 * The element which will define the boundaries of the popper position. 2208 * The popper will never be placed outside of the defined boundaries 2209 * (except if `keepTogether` is enabled) 2210 */ 2211 boundariesElement: 'viewport' 2212 }, 2213 2214 /** 2215 * Modifier used to make the popper flow toward the inner of the reference element. 2216 * By default, when this modifier is disabled, the popper will be placed outside 2217 * the reference element. 2218 * @memberof modifiers 2219 * @inner 2220 */ 2221 inner: { 2222 /** @prop {number} order=700 - Index used to define the order of execution */ 2223 order: 700, 2224 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 2225 enabled: false, 2226 /** @prop {ModifierFn} */ 2227 fn: inner 2228 }, 2229 2230 /** 2231 * Modifier used to hide the popper when its reference element is outside of the 2232 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 2233 * be used to hide with a CSS selector the popper when its reference is 2234 * out of boundaries. 2235 * 2236 * Requires the `preventOverflow` modifier before it in order to work. 2237 * @memberof modifiers 2238 * @inner 2239 */ 2240 hide: { 2241 /** @prop {number} order=800 - Index used to define the order of execution */ 2242 order: 800, 2243 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2244 enabled: true, 2245 /** @prop {ModifierFn} */ 2246 fn: hide 2247 }, 2248 2249 /** 2250 * Computes the style that will be applied to the popper element to gets 2251 * properly positioned. 2252 * 2253 * Note that this modifier will not touch the DOM, it just prepares the styles 2254 * so that `applyStyle` modifier can apply it. This separation is useful 2255 * in case you need to replace `applyStyle` with a custom implementation. 2256 * 2257 * This modifier has `850` as `order` value to maintain backward compatibility 2258 * with previous versions of Popper.js. Expect the modifiers ordering method 2259 * to change in future major versions of the library. 2260 * 2261 * @memberof modifiers 2262 * @inner 2263 */ 2264 computeStyle: { 2265 /** @prop {number} order=850 - Index used to define the order of execution */ 2266 order: 850, 2267 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2268 enabled: true, 2269 /** @prop {ModifierFn} */ 2270 fn: computeStyle, 2271 /** 2272 * @prop {Boolean} gpuAcceleration=true 2273 * If true, it uses the CSS 3D transformation to position the popper. 2274 * Otherwise, it will use the `top` and `left` properties 2275 */ 2276 gpuAcceleration: true, 2277 /** 2278 * @prop {string} [x='bottom'] 2279 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 2280 * Change this if your popper should grow in a direction different from `bottom` 2281 */ 2282 x: 'bottom', 2283 /** 2284 * @prop {string} [x='left'] 2285 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 2286 * Change this if your popper should grow in a direction different from `right` 2287 */ 2288 y: 'right' 2289 }, 2290 2291 /** 2292 * Applies the computed styles to the popper element. 2293 * 2294 * All the DOM manipulations are limited to this modifier. This is useful in case 2295 * you want to integrate Popper.js inside a framework or view library and you 2296 * want to delegate all the DOM manipulations to it. 2297 * 2298 * Note that if you disable this modifier, you must make sure the popper element 2299 * has its position set to `absolute` before Popper.js can do its work! 2300 * 2301 * Just disable this modifier and define your own to achieve the desired effect. 2302 * 2303 * @memberof modifiers 2304 * @inner 2305 */ 2306 applyStyle: { 2307 /** @prop {number} order=900 - Index used to define the order of execution */ 2308 order: 900, 2309 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 2310 enabled: true, 2311 /** @prop {ModifierFn} */
vendor: 5,510 bytes, lines 2312-2450
2312 fn: applyStyle, 2313 /** @prop {Function} */ 2314 onLoad: applyStyleOnLoad, 2315 /** 2316 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 2317 * @prop {Boolean} gpuAcceleration=true 2318 * If true, it uses the CSS 3D transformation to position the popper. 2319 * Otherwise, it will use the `top` and `left` properties 2320 */ 2321 gpuAcceleration: undefined 2322 } 2323 }; 2324 2325 /** 2326 * The `dataObject` is an object containing all the information used by Popper.js. 2327 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 2328 * @name dataObject 2329 * @property {Object} data.instance The Popper.js instance 2330 * @property {String} data.placement Placement applied to popper 2331 * @property {String} data.originalPlacement Placement originally defined on init 2332 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 2333 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper 2334 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 2335 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) 2336 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) 2337 * @property {Object} data.boundaries Offsets of the popper boundaries 2338 * @property {Object} data.offsets The measurements of popper, reference and arrow elements 2339 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 2340 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 2341 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 2342 */ 2343 2344 /** 2345 * Default options provided to Popper.js constructor.<br /> 2346 * These can be overridden using the `options` argument of Popper.js.<br /> 2347 * To override an option, simply pass an object with the same 2348 * structure of the `options` object, as the 3rd argument. For example: 2349 * ``` 2350 * new Popper(ref, pop, { 2351 * modifiers: { 2352 * preventOverflow: { enabled: false } 2353 * } 2354 * }) 2355 * ``` 2356 * @type {Object} 2357 * @static 2358 * @memberof Popper 2359 */ 2360 var Defaults = { 2361 /** 2362 * Popper's placement. 2363 * @prop {Popper.placements} placement='bottom' 2364 */ 2365 placement: 'bottom', 2366 2367 /** 2368 * Set this to true if you want popper to position it self in 'fixed' mode 2369 * @prop {Boolean} positionFixed=false 2370 */ 2371 positionFixed: false, 2372 2373 /** 2374 * Whether events (resize, scroll) are initially enabled. 2375 * @prop {Boolean} eventsEnabled=true 2376 */ 2377 eventsEnabled: true, 2378 2379 /** 2380 * Set to true if you want to automatically remove the popper when 2381 * you call the `destroy` method. 2382 * @prop {Boolean} removeOnDestroy=false 2383 */ 2384 removeOnDestroy: false, 2385 2386 /** 2387 * Callback called when the popper is created.<br /> 2388 * By default, it is set to no-op.<br /> 2389 * Access Popper.js instance with `data.instance`. 2390 * @prop {onCreate} 2391 */ 2392 onCreate: function onCreate() {}, 2393 2394 /** 2395 * Callback called when the popper is updated. This callback is not called 2396 * on the initialization/creation of the popper, but only on subsequent 2397 * updates.<br /> 2398 * By default, it is set to no-op.<br /> 2399 * Access Popper.js instance with `data.instance`. 2400 * @prop {onUpdate} 2401 */ 2402 onUpdate: function onUpdate() {}, 2403 2404 /** 2405 * List of modifiers used to modify the offsets before they are applied to the popper. 2406 * They provide most of the functionalities of Popper.js. 2407 * @prop {modifiers} 2408 */ 2409 modifiers: modifiers 2410 }; 2411 2412 /** 2413 * @callback onCreate 2414 * @param {dataObject} data 2415 */ 2416 2417 /** 2418 * @callback onUpdate 2419 * @param {dataObject} data 2420 */ 2421 2422// Utils 2423// Methods 2424 var Popper = function () { 2425 /** 2426 * Creates a new Popper.js instance. 2427 * @class Popper 2428 * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper 2429 * @param {HTMLElement} popper - The HTML element used as the popper 2430 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 2431 * @return {Object} instance - The generated Popper.js instance 2432 */ 2433 function Popper(reference, popper) { 2434 var _this = this; 2435 2436 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 2437 classCallCheck(this, Popper); 2438 2439 this.scheduleUpdate = function () { 2440 return requestAnimationFrame(_this.update); 2441 }; 2442 2443 // make update() debounced, so that it only runs at most once-per-tick 2444 this.update = debounce(this.update.bind(this)); 2445 2446 // with {} we create a new object with the options inside it 2447 this.options = _extends({}, Popper.Defaults, options); 2448 2449 // init state 2450 this.state = {
vendor: 5,163 bytes, lines 2451-2580
2451 isDestroyed: false, 2452 isCreated: false, 2453 scrollParents: [] 2454 }; 2455 2456 // get reference and popper elements (allow jQuery wrappers) 2457 this.reference = reference && reference.jquery ? reference[0] : reference; 2458 this.popper = popper && popper.jquery ? popper[0] : popper; 2459 2460 // Deep merge modifiers options 2461 this.options.modifiers = {}; 2462 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 2463 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 2464 }); 2465 2466 // Refactoring modifiers' list (Object => Array) 2467 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 2468 return _extends({ 2469 name: name 2470 }, _this.options.modifiers[name]); 2471 }) 2472 // sort the modifiers by order 2473 .sort(function (a, b) { 2474 return a.order - b.order; 2475 }); 2476 2477 // modifiers have the ability to execute arbitrary code when Popper.js get inited 2478 // such code is executed in the same order of its modifier 2479 // they could add new properties to their options configuration 2480 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 2481 this.modifiers.forEach(function (modifierOptions) { 2482 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 2483 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 2484 } 2485 }); 2486 2487 // fire the first update to position the popper in the right place 2488 this.update(); 2489 2490 var eventsEnabled = this.options.eventsEnabled; 2491 if (eventsEnabled) { 2492 // setup event listeners, they will take care of update the position in specific situations 2493 this.enableEventListeners(); 2494 } 2495 2496 this.state.eventsEnabled = eventsEnabled; 2497 } 2498 2499 // We can't use class properties because they don't get listed in the 2500 // class prototype and break stuff like Sinon stubs 2501 2502 2503 createClass(Popper, [{ 2504 key: 'update', 2505 value: function update$$1() { 2506 return update.call(this); 2507 } 2508 }, { 2509 key: 'destroy', 2510 value: function destroy$$1() { 2511 return destroy.call(this); 2512 } 2513 }, { 2514 key: 'enableEventListeners', 2515 value: function enableEventListeners$$1() { 2516 return enableEventListeners.call(this); 2517 } 2518 }, { 2519 key: 'disableEventListeners', 2520 value: function disableEventListeners$$1() { 2521 return disableEventListeners.call(this); 2522 } 2523 2524 /** 2525 * Schedules an update. It will run on the next UI update available. 2526 * @method scheduleUpdate 2527 * @memberof Popper 2528 */ 2529 2530 2531 /** 2532 * Collection of utilities useful when writing custom modifiers. 2533 * Starting from version 1.7, this method is available only if you 2534 * include `popper-utils.js` before `popper.js`. 2535 * 2536 * **DEPRECATION**: This way to access PopperUtils is deprecated 2537 * and will be removed in v2! Use the PopperUtils module directly instead. 2538 * Due to the high instability of the methods contained in Utils, we can't 2539 * guarantee them to follow semver. Use them at your own risk! 2540 * @static 2541 * @private 2542 * @type {Object} 2543 * @deprecated since version 1.8 2544 * @member Utils 2545 * @memberof Popper 2546 */ 2547 2548 }]); 2549 return Popper; 2550 }(); 2551 2552 /** 2553 * The `referenceObject` is an object that provides an interface compatible with Popper.js 2554 * and lets you use it as replacement of a real DOM node.<br /> 2555 * You can use this method to position a popper relatively to a set of coordinates 2556 * in case you don't have a DOM node to use as reference. 2557 * 2558 * ``` 2559 * new Popper(referenceObject, popperNode); 2560 * ``` 2561 * 2562 * NB: This feature isn't supported in Internet Explorer 10. 2563 * @name referenceObject 2564 * @property {Function} data.getBoundingClientRect 2565 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 2566 * @property {number} data.clientWidth 2567 * An ES6 getter that will return the width of the virtual reference element. 2568 * @property {number} data.clientHeight 2569 * An ES6 getter that will return the height of the virtual reference element. 2570 */ 2571 2572 2573 Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 2574 Popper.placements = placements; 2575 Popper.Defaults = Defaults; 2576 2577 return Popper; 2578 2579}))); 2580//# 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.