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