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