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