LaravelTest
1151 строка · 35.8 Кб
1/**!
2* @fileOverview Kickass library to create and place poppers near their reference elements.
3* @version 1.16.1
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) {26typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :27typeof define === 'function' && define.amd ? define(['exports'], factory) :28(factory((global.PopperUtils = {})));29}(this, (function (exports) { 'use strict';30
31/**
32* Get CSS computed property of the given element
33* @method
34* @memberof Popper.Utils
35* @argument {Eement} element
36* @argument {String} property
37*/
38function getStyleComputedProperty(element, property) {39if (element.nodeType !== 1) {40return [];41}42// NOTE: 1 DOM access here43var window = element.ownerDocument.defaultView;44var css = window.getComputedStyle(element, null);45return property ? css[property] : css;46}
47
48/**
49* Returns the parentNode or the host of the element
50* @method
51* @memberof Popper.Utils
52* @argument {Element} element
53* @returns {Element} parent
54*/
55function getParentNode(element) {56if (element.nodeName === 'HTML') {57return element;58}59return element.parentNode || element.host;60}
61
62/**
63* Returns the scrolling parent of the given element
64* @method
65* @memberof Popper.Utils
66* @argument {Element} element
67* @returns {Element} scroll parent
68*/
69function getScrollParent(element) {70// Return body, `getScroll` will take care to get the correct `scrollTop` from it71if (!element) {72return document.body;73}74
75switch (element.nodeName) {76case 'HTML':77case 'BODY':78return element.ownerDocument.body;79case '#document':80return element.body;81}82
83// Firefox want us to check `-x` and `-y` variations as well84
85var _getStyleComputedProp = getStyleComputedProperty(element),86overflow = _getStyleComputedProp.overflow,87overflowX = _getStyleComputedProp.overflowX,88overflowY = _getStyleComputedProp.overflowY;89
90if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {91return element;92}93
94return getScrollParent(getParentNode(element));95}
96
97/**
98* Returns the reference node of the reference object, or the reference object itself.
99* @method
100* @memberof Popper.Utils
101* @param {Element|Object} reference - the reference element (the popper will be relative to this)
102* @returns {Element} parent
103*/
104function getReferenceNode(reference) {105return reference && reference.referenceNode ? reference.referenceNode : reference;106}
107
108var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';109
110var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);111var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);112
113/**
114* Determines if the browser is Internet Explorer
115* @method
116* @memberof Popper.Utils
117* @param {Number} version to check
118* @returns {Boolean} isIE
119*/
120function isIE(version) {121if (version === 11) {122return isIE11;123}124if (version === 10) {125return isIE10;126}127return isIE11 || isIE10;128}
129
130/**
131* Returns the offset parent of the given element
132* @method
133* @memberof Popper.Utils
134* @argument {Element} element
135* @returns {Element} offset parent
136*/
137function getOffsetParent(element) {138if (!element) {139return document.documentElement;140}141
142var noOffsetParent = isIE(10) ? document.body : null;143
144// NOTE: 1 DOM access here145var offsetParent = element.offsetParent || null;146// Skip hidden elements which don't have an offsetParent147while (offsetParent === noOffsetParent && element.nextElementSibling) {148offsetParent = (element = element.nextElementSibling).offsetParent;149}150
151var nodeName = offsetParent && offsetParent.nodeName;152
153if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {154return element ? element.ownerDocument.documentElement : document.documentElement;155}156
157// .offsetParent will return the closest TH, TD or TABLE in case158// no offsetParent is present, I hate this job...159if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {160return getOffsetParent(offsetParent);161}162
163return offsetParent;164}
165
166function isOffsetContainer(element) {167var nodeName = element.nodeName;168
169if (nodeName === 'BODY') {170return false;171}172return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;173}
174
175/**
176* Finds the root node (document, shadowDOM root) of the given element
177* @method
178* @memberof Popper.Utils
179* @argument {Element} node
180* @returns {Element} root node
181*/
182function getRoot(node) {183if (node.parentNode !== null) {184return getRoot(node.parentNode);185}186
187return node;188}
189
190/**
191* Finds the offset parent common to the two provided nodes
192* @method
193* @memberof Popper.Utils
194* @argument {Element} element1
195* @argument {Element} element2
196* @returns {Element} common offset parent
197*/
198function findCommonOffsetParent(element1, element2) {199// This check is needed to avoid errors in case one of the elements isn't defined for any reason200if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {201return document.documentElement;202}203
204// Here we make sure to give as "start" the element that comes first in the DOM205var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;206var start = order ? element1 : element2;207var end = order ? element2 : element1;208
209// Get common ancestor container210var range = document.createRange();211range.setStart(start, 0);212range.setEnd(end, 0);213var commonAncestorContainer = range.commonAncestorContainer;214
215// Both nodes are inside #document216
217if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {218if (isOffsetContainer(commonAncestorContainer)) {219return commonAncestorContainer;220}221
222return getOffsetParent(commonAncestorContainer);223}224
225// one of the nodes is inside shadowDOM, find which one226var element1root = getRoot(element1);227if (element1root.host) {228return findCommonOffsetParent(element1root.host, element2);229} else {230return findCommonOffsetParent(element1, getRoot(element2).host);231}232}
233
234/**
235* Gets the scroll value of the given element in the given side (top and left)
236* @method
237* @memberof Popper.Utils
238* @argument {Element} element
239* @argument {String} side `top` or `left`
240* @returns {number} amount of scrolled pixels
241*/
242function getScroll(element) {243var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';244
245var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';246var nodeName = element.nodeName;247
248if (nodeName === 'BODY' || nodeName === 'HTML') {249var html = element.ownerDocument.documentElement;250var scrollingElement = element.ownerDocument.scrollingElement || html;251return scrollingElement[upperSide];252}253
254return element[upperSide];255}
256
257/*
258* Sum or subtract the element scroll values (left and top) from a given rect object
259* @method
260* @memberof Popper.Utils
261* @param {Object} rect - Rect object you want to change
262* @param {HTMLElement} element - The element from the function reads the scroll values
263* @param {Boolean} subtract - set to true if you want to subtract the scroll values
264* @return {Object} rect - The modifier rect object
265*/
266function includeScroll(rect, element) {267var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;268
269var scrollTop = getScroll(element, 'top');270var scrollLeft = getScroll(element, 'left');271var modifier = subtract ? -1 : 1;272rect.top += scrollTop * modifier;273rect.bottom += scrollTop * modifier;274rect.left += scrollLeft * modifier;275rect.right += scrollLeft * modifier;276return rect;277}
278
279/*
280* Helper to detect borders of a given element
281* @method
282* @memberof Popper.Utils
283* @param {CSSStyleDeclaration} styles
284* Result of `getStyleComputedProperty` on the given element
285* @param {String} axis - `x` or `y`
286* @return {number} borders - The borders size of the given axis
287*/
288
289function getBordersSize(styles, axis) {290var sideA = axis === 'x' ? 'Left' : 'Top';291var sideB = sideA === 'Left' ? 'Right' : 'Bottom';292
293return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);294}
295
296function getSize(axis, body, html, computedStyle) {297return 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);298}
299
300function getWindowSizes(document) {301var body = document.body;302var html = document.documentElement;303var computedStyle = isIE(10) && getComputedStyle(html);304
305return {306height: getSize('Height', body, html, computedStyle),307width: getSize('Width', body, html, computedStyle)308};309}
310
311var _extends = Object.assign || function (target) {312for (var i = 1; i < arguments.length; i++) {313var source = arguments[i];314
315for (var key in source) {316if (Object.prototype.hasOwnProperty.call(source, key)) {317target[key] = source[key];318}319}320}321
322return target;323};324
325/**
326* Given element offsets, generate an output similar to getBoundingClientRect
327* @method
328* @memberof Popper.Utils
329* @argument {Object} offsets
330* @returns {Object} ClientRect like output
331*/
332function getClientRect(offsets) {333return _extends({}, offsets, {334right: offsets.left + offsets.width,335bottom: offsets.top + offsets.height336});337}
338
339/**
340* Get bounding client rect of given element
341* @method
342* @memberof Popper.Utils
343* @param {HTMLElement} element
344* @return {Object} client rect
345*/
346function getBoundingClientRect(element) {347var rect = {};348
349// IE10 10 FIX: Please, don't ask, the element isn't350// considered in DOM in some circumstances...351// This isn't reproducible in IE10 compatibility mode of IE11352try {353if (isIE(10)) {354rect = element.getBoundingClientRect();355var scrollTop = getScroll(element, 'top');356var scrollLeft = getScroll(element, 'left');357rect.top += scrollTop;358rect.left += scrollLeft;359rect.bottom += scrollTop;360rect.right += scrollLeft;361} else {362rect = element.getBoundingClientRect();363}364} catch (e) {}365
366var result = {367left: rect.left,368top: rect.top,369width: rect.right - rect.left,370height: rect.bottom - rect.top371};372
373// subtract scrollbar size from sizes374var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};375var width = sizes.width || element.clientWidth || result.width;376var height = sizes.height || element.clientHeight || result.height;377
378var horizScrollbar = element.offsetWidth - width;379var vertScrollbar = element.offsetHeight - height;380
381// if an hypothetical scrollbar is detected, we must be sure it's not a `border`382// we make this check conditional for performance reasons383if (horizScrollbar || vertScrollbar) {384var styles = getStyleComputedProperty(element);385horizScrollbar -= getBordersSize(styles, 'x');386vertScrollbar -= getBordersSize(styles, 'y');387
388result.width -= horizScrollbar;389result.height -= vertScrollbar;390}391
392return getClientRect(result);393}
394
395function getOffsetRectRelativeToArbitraryNode(children, parent) {396var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;397
398var isIE10 = isIE(10);399var isHTML = parent.nodeName === 'HTML';400var childrenRect = getBoundingClientRect(children);401var parentRect = getBoundingClientRect(parent);402var scrollParent = getScrollParent(children);403
404var styles = getStyleComputedProperty(parent);405var borderTopWidth = parseFloat(styles.borderTopWidth);406var borderLeftWidth = parseFloat(styles.borderLeftWidth);407
408// In cases where the parent is fixed, we must ignore negative scroll in offset calc409if (fixedPosition && isHTML) {410parentRect.top = Math.max(parentRect.top, 0);411parentRect.left = Math.max(parentRect.left, 0);412}413var offsets = getClientRect({414top: childrenRect.top - parentRect.top - borderTopWidth,415left: childrenRect.left - parentRect.left - borderLeftWidth,416width: childrenRect.width,417height: childrenRect.height418});419offsets.marginTop = 0;420offsets.marginLeft = 0;421
422// Subtract margins of documentElement in case it's being used as parent423// we do this only on HTML because it's the only element that behaves424// differently when margins are applied to it. The margins are included in425// the box of the documentElement, in the other cases not.426if (!isIE10 && isHTML) {427var marginTop = parseFloat(styles.marginTop);428var marginLeft = parseFloat(styles.marginLeft);429
430offsets.top -= borderTopWidth - marginTop;431offsets.bottom -= borderTopWidth - marginTop;432offsets.left -= borderLeftWidth - marginLeft;433offsets.right -= borderLeftWidth - marginLeft;434
435// Attach marginTop and marginLeft because in some circumstances we may need them436offsets.marginTop = marginTop;437offsets.marginLeft = marginLeft;438}439
440if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {441offsets = includeScroll(offsets, parent);442}443
444return offsets;445}
446
447function getViewportOffsetRectRelativeToArtbitraryNode(element) {448var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;449
450var html = element.ownerDocument.documentElement;451var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);452var width = Math.max(html.clientWidth, window.innerWidth || 0);453var height = Math.max(html.clientHeight, window.innerHeight || 0);454
455var scrollTop = !excludeScroll ? getScroll(html) : 0;456var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;457
458var offset = {459top: scrollTop - relativeOffset.top + relativeOffset.marginTop,460left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,461width: width,462height: height463};464
465return getClientRect(offset);466}
467
468/**
469* Check if the given element is fixed or is inside a fixed parent
470* @method
471* @memberof Popper.Utils
472* @argument {Element} element
473* @argument {Element} customContainer
474* @returns {Boolean} answer to "isFixed?"
475*/
476function isFixed(element) {477var nodeName = element.nodeName;478if (nodeName === 'BODY' || nodeName === 'HTML') {479return false;480}481if (getStyleComputedProperty(element, 'position') === 'fixed') {482return true;483}484var parentNode = getParentNode(element);485if (!parentNode) {486return false;487}488return isFixed(parentNode);489}
490
491/**
492* Finds the first parent of an element that has a transformed property defined
493* @method
494* @memberof Popper.Utils
495* @argument {Element} element
496* @returns {Element} first transformed parent or documentElement
497*/
498
499function getFixedPositionOffsetParent(element) {500// This check is needed to avoid errors in case one of the elements isn't defined for any reason501if (!element || !element.parentElement || isIE()) {502return document.documentElement;503}504var el = element.parentElement;505while (el && getStyleComputedProperty(el, 'transform') === 'none') {506el = el.parentElement;507}508return el || document.documentElement;509}
510
511/**
512* Computed the boundaries limits and return them
513* @method
514* @memberof Popper.Utils
515* @param {HTMLElement} popper
516* @param {HTMLElement} reference
517* @param {number} padding
518* @param {HTMLElement} boundariesElement - Element used to define the boundaries
519* @param {Boolean} fixedPosition - Is in fixed position mode
520* @returns {Object} Coordinates of the boundaries
521*/
522function getBoundaries(popper, reference, padding, boundariesElement) {523var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;524
525// NOTE: 1 DOM access here526
527var boundaries = { top: 0, left: 0 };528var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));529
530// Handle viewport case531if (boundariesElement === 'viewport') {532boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);533} else {534// Handle other cases based on DOM element used as boundaries535var boundariesNode = void 0;536if (boundariesElement === 'scrollParent') {537boundariesNode = getScrollParent(getParentNode(reference));538if (boundariesNode.nodeName === 'BODY') {539boundariesNode = popper.ownerDocument.documentElement;540}541} else if (boundariesElement === 'window') {542boundariesNode = popper.ownerDocument.documentElement;543} else {544boundariesNode = boundariesElement;545}546
547var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);548
549// In case of HTML, we need a different computation550if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {551var _getWindowSizes = getWindowSizes(popper.ownerDocument),552height = _getWindowSizes.height,553width = _getWindowSizes.width;554
555boundaries.top += offsets.top - offsets.marginTop;556boundaries.bottom = height + offsets.top;557boundaries.left += offsets.left - offsets.marginLeft;558boundaries.right = width + offsets.left;559} else {560// for all the other DOM elements, this one is good561boundaries = offsets;562}563}564
565// Add paddings566padding = padding || 0;567var isPaddingNumber = typeof padding === 'number';568boundaries.left += isPaddingNumber ? padding : padding.left || 0;569boundaries.top += isPaddingNumber ? padding : padding.top || 0;570boundaries.right -= isPaddingNumber ? padding : padding.right || 0;571boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;572
573return boundaries;574}
575
576function getArea(_ref) {577var width = _ref.width,578height = _ref.height;579
580return width * height;581}
582
583/**
584* Utility used to transform the `auto` placement to the placement with more
585* available space.
586* @method
587* @memberof Popper.Utils
588* @argument {Object} data - The data object generated by update method
589* @argument {Object} options - Modifiers configuration and options
590* @returns {Object} The data object, properly modified
591*/
592function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {593var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;594
595if (placement.indexOf('auto') === -1) {596return placement;597}598
599var boundaries = getBoundaries(popper, reference, padding, boundariesElement);600
601var rects = {602top: {603width: boundaries.width,604height: refRect.top - boundaries.top605},606right: {607width: boundaries.right - refRect.right,608height: boundaries.height609},610bottom: {611width: boundaries.width,612height: boundaries.bottom - refRect.bottom613},614left: {615width: refRect.left - boundaries.left,616height: boundaries.height617}618};619
620var sortedAreas = Object.keys(rects).map(function (key) {621return _extends({622key: key623}, rects[key], {624area: getArea(rects[key])625});626}).sort(function (a, b) {627return b.area - a.area;628});629
630var filteredAreas = sortedAreas.filter(function (_ref2) {631var width = _ref2.width,632height = _ref2.height;633return width >= popper.clientWidth && height >= popper.clientHeight;634});635
636var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;637
638var variation = placement.split('-')[1];639
640return computedPlacement + (variation ? '-' + variation : '');641}
642
643var timeoutDuration = function () {644var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];645for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {646if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {647return 1;648}649}650return 0;651}();652
653function microtaskDebounce(fn) {654var called = false;655return function () {656if (called) {657return;658}659called = true;660window.Promise.resolve().then(function () {661called = false;662fn();663});664};665}
666
667function taskDebounce(fn) {668var scheduled = false;669return function () {670if (!scheduled) {671scheduled = true;672setTimeout(function () {673scheduled = false;674fn();675}, timeoutDuration);676}677};678}
679
680var supportsMicroTasks = isBrowser && window.Promise;681
682/**
683* Create a debounced version of a method, that's asynchronously deferred
684* but called in the minimum time possible.
685*
686* @method
687* @memberof Popper.Utils
688* @argument {Function} fn
689* @returns {Function}
690*/
691var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;692
693/**
694* Mimics the `find` method of Array
695* @method
696* @memberof Popper.Utils
697* @argument {Array} arr
698* @argument prop
699* @argument value
700* @returns index or -1
701*/
702function find(arr, check) {703// use native find if supported704if (Array.prototype.find) {705return arr.find(check);706}707
708// use `filter` to obtain the same behavior of `find`709return arr.filter(check)[0];710}
711
712/**
713* Return the index of the matching object
714* @method
715* @memberof Popper.Utils
716* @argument {Array} arr
717* @argument prop
718* @argument value
719* @returns index or -1
720*/
721function findIndex(arr, prop, value) {722// use native findIndex if supported723if (Array.prototype.findIndex) {724return arr.findIndex(function (cur) {725return cur[prop] === value;726});727}728
729// use `find` + `indexOf` if `findIndex` isn't supported730var match = find(arr, function (obj) {731return obj[prop] === value;732});733return arr.indexOf(match);734}
735
736/**
737* Get the position of the given element, relative to its offset parent
738* @method
739* @memberof Popper.Utils
740* @param {Element} element
741* @return {Object} position - Coordinates of the element and its `scrollTop`
742*/
743function getOffsetRect(element) {744var elementRect = void 0;745if (element.nodeName === 'HTML') {746var _getWindowSizes = getWindowSizes(element.ownerDocument),747width = _getWindowSizes.width,748height = _getWindowSizes.height;749
750elementRect = {751width: width,752height: height,753left: 0,754top: 0755};756} else {757elementRect = {758width: element.offsetWidth,759height: element.offsetHeight,760left: element.offsetLeft,761top: element.offsetTop762};763}764
765// position766return getClientRect(elementRect);767}
768
769/**
770* Get the outer sizes of the given element (offset size + margins)
771* @method
772* @memberof Popper.Utils
773* @argument {Element} element
774* @returns {Object} object containing width and height properties
775*/
776function getOuterSizes(element) {777var window = element.ownerDocument.defaultView;778var styles = window.getComputedStyle(element);779var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);780var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);781var result = {782width: element.offsetWidth + y,783height: element.offsetHeight + x784};785return result;786}
787
788/**
789* Get the opposite placement of the given one
790* @method
791* @memberof Popper.Utils
792* @argument {String} placement
793* @returns {String} flipped placement
794*/
795function getOppositePlacement(placement) {796var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };797return placement.replace(/left|right|bottom|top/g, function (matched) {798return hash[matched];799});800}
801
802/**
803* Get offsets to the popper
804* @method
805* @memberof Popper.Utils
806* @param {Object} position - CSS position the Popper will get applied
807* @param {HTMLElement} popper - the popper element
808* @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
809* @param {String} placement - one of the valid placement options
810* @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
811*/
812function getPopperOffsets(popper, referenceOffsets, placement) {813placement = placement.split('-')[0];814
815// Get popper node sizes816var popperRect = getOuterSizes(popper);817
818// Add position, width and height to our offsets object819var popperOffsets = {820width: popperRect.width,821height: popperRect.height822};823
824// depending by the popper placement we have to compute its offsets slightly differently825var isHoriz = ['right', 'left'].indexOf(placement) !== -1;826var mainSide = isHoriz ? 'top' : 'left';827var secondarySide = isHoriz ? 'left' : 'top';828var measurement = isHoriz ? 'height' : 'width';829var secondaryMeasurement = !isHoriz ? 'height' : 'width';830
831popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;832if (placement === secondarySide) {833popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];834} else {835popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];836}837
838return popperOffsets;839}
840
841/**
842* Get offsets to the reference element
843* @method
844* @memberof Popper.Utils
845* @param {Object} state
846* @param {Element} popper - the popper element
847* @param {Element} reference - the reference element (the popper will be relative to this)
848* @param {Element} fixedPosition - is in fixed position mode
849* @returns {Object} An object containing the offsets which will be applied to the popper
850*/
851function getReferenceOffsets(state, popper, reference) {852var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;853
854var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));855return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);856}
857
858/**
859* Get the prefixed supported property name
860* @method
861* @memberof Popper.Utils
862* @argument {String} property (camelCase)
863* @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
864*/
865function getSupportedPropertyName(property) {866var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];867var upperProp = property.charAt(0).toUpperCase() + property.slice(1);868
869for (var i = 0; i < prefixes.length; i++) {870var prefix = prefixes[i];871var toCheck = prefix ? '' + prefix + upperProp : property;872if (typeof document.body.style[toCheck] !== 'undefined') {873return toCheck;874}875}876return null;877}
878
879/**
880* Check if the given variable is a function
881* @method
882* @memberof Popper.Utils
883* @argument {Any} functionToCheck - variable to check
884* @returns {Boolean} answer to: is a function?
885*/
886function isFunction(functionToCheck) {887var getType = {};888return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';889}
890
891/**
892* Helper used to know if the given modifier is enabled.
893* @method
894* @memberof Popper.Utils
895* @returns {Boolean}
896*/
897function isModifierEnabled(modifiers, modifierName) {898return modifiers.some(function (_ref) {899var name = _ref.name,900enabled = _ref.enabled;901return enabled && name === modifierName;902});903}
904
905/**
906* Helper used to know if the given modifier depends from another one.<br />
907* It checks if the needed modifier is listed and enabled.
908* @method
909* @memberof Popper.Utils
910* @param {Array} modifiers - list of modifiers
911* @param {String} requestingName - name of requesting modifier
912* @param {String} requestedName - name of requested modifier
913* @returns {Boolean}
914*/
915function isModifierRequired(modifiers, requestingName, requestedName) {916var requesting = find(modifiers, function (_ref) {917var name = _ref.name;918return name === requestingName;919});920
921var isRequired = !!requesting && modifiers.some(function (modifier) {922return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;923});924
925if (!isRequired) {926var _requesting = '`' + requestingName + '`';927var requested = '`' + requestedName + '`';928console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');929}930return isRequired;931}
932
933/**
934* Tells if a given input is a number
935* @method
936* @memberof Popper.Utils
937* @param {*} input to check
938* @return {Boolean}
939*/
940function isNumeric(n) {941return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);942}
943
944/**
945* Get the window associated with the element
946* @argument {Element} element
947* @returns {Window}
948*/
949function getWindow(element) {950var ownerDocument = element.ownerDocument;951return ownerDocument ? ownerDocument.defaultView : window;952}
953
954/**
955* Remove event listeners used to update the popper position
956* @method
957* @memberof Popper.Utils
958* @private
959*/
960function removeEventListeners(reference, state) {961// Remove resize event listener on window962getWindow(reference).removeEventListener('resize', state.updateBound);963
964// Remove scroll event listener on scroll parents965state.scrollParents.forEach(function (target) {966target.removeEventListener('scroll', state.updateBound);967});968
969// Reset state970state.updateBound = null;971state.scrollParents = [];972state.scrollElement = null;973state.eventsEnabled = false;974return state;975}
976
977/**
978* Loop trough the list of modifiers and run them in order,
979* each of them will then edit the data object.
980* @method
981* @memberof Popper.Utils
982* @param {dataObject} data
983* @param {Array} modifiers
984* @param {String} ends - Optional modifier name used as stopper
985* @returns {dataObject}
986*/
987function runModifiers(modifiers, data, ends) {988var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));989
990modifiersToRun.forEach(function (modifier) {991if (modifier['function']) {992// eslint-disable-line dot-notation993console.warn('`modifier.function` is deprecated, use `modifier.fn`!');994}995var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation996if (modifier.enabled && isFunction(fn)) {997// Add properties to offsets to make them a complete clientRect object998// we do this before each modifier to make sure the previous one doesn't999// mess with these values1000data.offsets.popper = getClientRect(data.offsets.popper);1001data.offsets.reference = getClientRect(data.offsets.reference);1002
1003data = fn(data, modifier);1004}1005});1006
1007return data;1008}
1009
1010/**
1011* Set the attributes to the given popper
1012* @method
1013* @memberof Popper.Utils
1014* @argument {Element} element - Element to apply the attributes to
1015* @argument {Object} styles
1016* Object with a list of properties and values which will be applied to the element
1017*/
1018function setAttributes(element, attributes) {1019Object.keys(attributes).forEach(function (prop) {1020var value = attributes[prop];1021if (value !== false) {1022element.setAttribute(prop, attributes[prop]);1023} else {1024element.removeAttribute(prop);1025}1026});1027}
1028
1029/**
1030* Set the style to the given popper
1031* @method
1032* @memberof Popper.Utils
1033* @argument {Element} element - Element to apply the style to
1034* @argument {Object} styles
1035* Object with a list of properties and values which will be applied to the element
1036*/
1037function setStyles(element, styles) {1038Object.keys(styles).forEach(function (prop) {1039var unit = '';1040// add unit if the value is numeric and is one of the following1041if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {1042unit = 'px';1043}1044element.style[prop] = styles[prop] + unit;1045});1046}
1047
1048function attachToScrollParents(scrollParent, event, callback, scrollParents) {1049var isBody = scrollParent.nodeName === 'BODY';1050var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;1051target.addEventListener(event, callback, { passive: true });1052
1053if (!isBody) {1054attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);1055}1056scrollParents.push(target);1057}
1058
1059/**
1060* Setup needed event listeners used to update the popper position
1061* @method
1062* @memberof Popper.Utils
1063* @private
1064*/
1065function setupEventListeners(reference, options, state, updateBound) {1066// Resize event listener on window1067state.updateBound = updateBound;1068getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });1069
1070// Scroll event listener on scroll parents1071var scrollElement = getScrollParent(reference);1072attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);1073state.scrollElement = scrollElement;1074state.eventsEnabled = true;1075
1076return state;1077}
1078
1079// This is here just for backward compatibility with versions lower than v1.10.3
1080// you should import the utilities using named exports, if you want them all use:
1081// ```
1082// import * as PopperUtils from 'popper-utils';
1083// ```
1084// The default export will be removed in the next major version.
1085var index = {1086computeAutoPlacement: computeAutoPlacement,1087debounce: debounce,1088findIndex: findIndex,1089getBordersSize: getBordersSize,1090getBoundaries: getBoundaries,1091getBoundingClientRect: getBoundingClientRect,1092getClientRect: getClientRect,1093getOffsetParent: getOffsetParent,1094getOffsetRect: getOffsetRect,1095getOffsetRectRelativeToArbitraryNode: getOffsetRectRelativeToArbitraryNode,1096getOuterSizes: getOuterSizes,1097getParentNode: getParentNode,1098getPopperOffsets: getPopperOffsets,1099getReferenceOffsets: getReferenceOffsets,1100getScroll: getScroll,1101getScrollParent: getScrollParent,1102getStyleComputedProperty: getStyleComputedProperty,1103getSupportedPropertyName: getSupportedPropertyName,1104getWindowSizes: getWindowSizes,1105isFixed: isFixed,1106isFunction: isFunction,1107isModifierEnabled: isModifierEnabled,1108isModifierRequired: isModifierRequired,1109isNumeric: isNumeric,1110removeEventListeners: removeEventListeners,1111runModifiers: runModifiers,1112setAttributes: setAttributes,1113setStyles: setStyles,1114setupEventListeners: setupEventListeners1115};1116
1117exports.computeAutoPlacement = computeAutoPlacement;1118exports.debounce = debounce;1119exports.findIndex = findIndex;1120exports.getBordersSize = getBordersSize;1121exports.getBoundaries = getBoundaries;1122exports.getBoundingClientRect = getBoundingClientRect;1123exports.getClientRect = getClientRect;1124exports.getOffsetParent = getOffsetParent;1125exports.getOffsetRect = getOffsetRect;1126exports.getOffsetRectRelativeToArbitraryNode = getOffsetRectRelativeToArbitraryNode;1127exports.getOuterSizes = getOuterSizes;1128exports.getParentNode = getParentNode;1129exports.getPopperOffsets = getPopperOffsets;1130exports.getReferenceOffsets = getReferenceOffsets;1131exports.getScroll = getScroll;1132exports.getScrollParent = getScrollParent;1133exports.getStyleComputedProperty = getStyleComputedProperty;1134exports.getSupportedPropertyName = getSupportedPropertyName;1135exports.getWindowSizes = getWindowSizes;1136exports.isFixed = isFixed;1137exports.isFunction = isFunction;1138exports.isModifierEnabled = isModifierEnabled;1139exports.isModifierRequired = isModifierRequired;1140exports.isNumeric = isNumeric;1141exports.removeEventListeners = removeEventListeners;1142exports.runModifiers = runModifiers;1143exports.setAttributes = setAttributes;1144exports.setStyles = setStyles;1145exports.setupEventListeners = setupEventListeners;1146exports['default'] = index;1147
1148Object.defineProperty(exports, '__esModule', { value: true });1149
1150})));1151//# sourceMappingURL=popper-utils.js.map
1152