tippy_rails 1.2.1.2 → 1.2.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62a2fb2f9434ce211346f60974758f1079c4c58b
4
- data.tar.gz: 7c258c46080d9abc0235e3e3e952f17a49906b8d
3
+ metadata.gz: 628ae86f13911f10bf41b80795dd6284c6c96d09
4
+ data.tar.gz: 4743dd7cd548bf141550d8d6457caaefc280ebe2
5
5
  SHA512:
6
- metadata.gz: cf15eb18f9a1d4b8519546d564533686679d00c5e0bd3b709a6c72c31d732919e62ddfb5c28d51e85d45d446b883223dcfb1e2c596f8ceed4331d0c8ed67fd07
7
- data.tar.gz: 368a3ddc13923247a048acaaf9267590f60ad04214c2a7b31ff917a1cd3434a60215a6ed17f0b253e390fece3169ec68a14e41bd7037830947b840a4649e190c
6
+ metadata.gz: 06bc82af349599c6925cc973cb33f4ec1df0cbe566992157fa34753218d29dc0453e7d65ba117d8a5384f1c0d5bb264f73fe73bb9e8e36873d8cb0f4c2af36e4
7
+ data.tar.gz: c6cb47185f8eff5dc5772e64c5ef99774709f6a6793d194cd15477547f5a00101b655c1b6c2f0e8fa4a2e67bec0f3c722c41c478be7035dbc3098ee5f2572beb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tippy_rails (1.2.1.2)
4
+ tippy_rails (1.2.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -0,0 +1,16 @@
1
+ require "tippy_rails/version"
2
+
3
+ module TippyRails
4
+ if defined? ::Rails
5
+ if ::Rails.version.to_s < '3.1'
6
+ require 'tippy_rails/railtie'
7
+ else
8
+ require 'tippy_rails/engine'
9
+ end
10
+ elsif defined? ::Sprockets
11
+ require 'tippy_rails/sprockets'
12
+ else
13
+ require 'tippy_rails/errors/unsupported_platform_error'
14
+ raise UnsupportedPlatformError
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ module TippyRails
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class UnsupportedPlatformError < StandardError
2
+ def initialize(msg="Your Technology is Not Supported. Supported Technologies: Rails, Sprockets.")
3
+ super
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module TippyRails
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module TippyRails
2
+ root_dir = File.expand_path(File.dirname(File.dirname(File.dirname(__FILE__))))
3
+
4
+ Sprockets.paths << File.join(root_dir, 'vendor', 'assets')
5
+ end
@@ -0,0 +1,3 @@
1
+ module TippyRails
2
+ VERSION = "1.2.1.3"
3
+ end
data/tippy_rails.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/ElliottAYoung/tippy_rails.git"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = Dir["*"]
17
+ spec.files = Dir["{lib,vendor}/**/*" ,"*"]
18
18
 
19
19
  spec.add_development_dependency "bundler", "~> 1.15"
20
20
  spec.add_development_dependency "rake", "~> 10.0"
@@ -0,0 +1,3927 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global.tippy = factory());
5
+ }(this, (function () { 'use strict';
6
+
7
+ var Browser = {};
8
+
9
+ if (typeof window !== 'undefined') {
10
+ Browser.SUPPORTED = 'requestAnimationFrame' in window;
11
+ Browser.SUPPORTS_TOUCH = 'ontouchstart' in window;
12
+ Browser.touch = false;
13
+ Browser.dynamicInputDetection = true;
14
+ // Chrome device/touch emulation can make this dynamic
15
+ Browser.iOS = function () {
16
+ return (/iPhone|iPad|iPod/.test(navigator.userAgent) && !window.MSStream
17
+ );
18
+ };
19
+ }
20
+
21
+ /**
22
+ * The global storage array which holds all data reference objects
23
+ * from every instance
24
+ * This allows us to hide tooltips from all instances, finding the ref when
25
+ * clicking on the body, and for followCursor
26
+ */
27
+ var Store = [];
28
+
29
+ /**
30
+ * Selector constants used for grabbing elements
31
+ */
32
+ var Selectors = {
33
+ POPPER: '.tippy-popper',
34
+ TOOLTIP: '.tippy-tooltip',
35
+ CONTENT: '.tippy-tooltip-content',
36
+ CIRCLE: '[x-circle]',
37
+ ARROW: '[x-arrow]',
38
+ TOOLTIPPED_EL: '[data-tooltipped]',
39
+ CONTROLLER: '[data-tippy-controller]'
40
+ };
41
+
42
+ /**
43
+ * The default settings applied to each instance
44
+ */
45
+ var Defaults = {
46
+ html: false,
47
+ position: 'top',
48
+ animation: 'shift',
49
+ animateFill: true,
50
+ arrow: false,
51
+ arrowSize: 'regular',
52
+ delay: 0,
53
+ trigger: 'mouseenter focus',
54
+ duration: 350,
55
+ interactive: false,
56
+ interactiveBorder: 2,
57
+ theme: 'dark',
58
+ size: 'regular',
59
+ distance: 10,
60
+ offset: 0,
61
+ hideOnClick: true,
62
+ multiple: false,
63
+ followCursor: false,
64
+ inertia: false,
65
+ flipDuration: 350,
66
+ sticky: false,
67
+ stickyDuration: 200,
68
+ appendTo: null,
69
+ zIndex: 9999,
70
+ touchHold: false,
71
+ performance: false,
72
+ dynamicTitle: false,
73
+ popperOptions: {}
74
+ };
75
+
76
+ /**
77
+ * The keys of the defaults object for reducing down into a new object
78
+ * Used in `getIndividualSettings()`
79
+ */
80
+ var DefaultsKeys = Browser.SUPPORTED && Object.keys(Defaults);
81
+
82
+ /**
83
+ * Hides all poppers
84
+ * @param {Object} exclude - refData to exclude if needed
85
+ */
86
+ function hideAllPoppers(exclude) {
87
+ Store.forEach(function (refData) {
88
+ var popper = refData.popper,
89
+ tippyInstance = refData.tippyInstance,
90
+ _refData$settings = refData.settings,
91
+ appendTo = _refData$settings.appendTo,
92
+ hideOnClick = _refData$settings.hideOnClick,
93
+ trigger = _refData$settings.trigger;
94
+
95
+ // Don't hide already hidden ones
96
+
97
+ if (!appendTo.contains(popper)) return;
98
+
99
+ // hideOnClick can have the truthy value of 'persistent', so strict check is needed
100
+ var isHideOnClick = hideOnClick === true || trigger.indexOf('focus') !== -1;
101
+ var isNotCurrentRef = !exclude || popper !== exclude.popper;
102
+
103
+ if (isHideOnClick && isNotCurrentRef) {
104
+ tippyInstance.hide(popper);
105
+ }
106
+ });
107
+ }
108
+
109
+ var e = Element.prototype;
110
+ var matches = e.matches || e.matchesSelector || e.webkitMatchesSelector || e.mozMatchesSelector || e.msMatchesSelector || function (s) {
111
+ var matches = (this.document || this.ownerDocument).querySelectorAll(s),
112
+ i = matches.length;
113
+ while (--i >= 0 && matches.item(i) !== this) {}
114
+ return i > -1;
115
+ };
116
+
117
+ /**
118
+ * Ponyfill to get the closest parent element
119
+ * @param {Element} element - child of parent to be returned
120
+ * @param {String} parentSelector - selector to match the parent if found
121
+ * @return {Element}
122
+ */
123
+ function closest(element, parentSelector) {
124
+ var _closest = Element.prototype.closest || function (selector) {
125
+ var el = this;
126
+ while (el) {
127
+ if (matches.call(el, selector)) {
128
+ return el;
129
+ }
130
+ el = el.parentElement;
131
+ }
132
+ };
133
+
134
+ return _closest.call(element, parentSelector);
135
+ }
136
+
137
+ /**
138
+ * Ponyfill for Array.prototype.find
139
+ * @param {Array} arr
140
+ * @param {Function} checkFn
141
+ * @return item in the array
142
+ */
143
+ function find(arr, checkFn) {
144
+ if (Array.prototype.find) {
145
+ return arr.find(checkFn);
146
+ }
147
+
148
+ // use `filter` as fallback
149
+ return arr.filter(checkFn)[0];
150
+ }
151
+
152
+ /**
153
+ * Adds the needed event listeners
154
+ */
155
+ function bindEventListeners() {
156
+ var touchHandler = function touchHandler() {
157
+ Browser.touch = true;
158
+
159
+ if (Browser.iOS()) {
160
+ document.body.classList.add('tippy-touch');
161
+ }
162
+
163
+ if (Browser.dynamicInputDetection && window.performance) {
164
+ document.addEventListener('mousemove', mousemoveHandler);
165
+ }
166
+ };
167
+
168
+ var mousemoveHandler = function () {
169
+ var time = void 0;
170
+
171
+ return function () {
172
+ var now = performance.now();
173
+
174
+ // Chrome 60+ is 1 mousemove per rAF, use 20ms time difference
175
+ if (now - time < 20) {
176
+ Browser.touch = false;
177
+ document.removeEventListener('mousemove', mousemoveHandler);
178
+ if (!Browser.iOS()) {
179
+ document.body.classList.remove('tippy-touch');
180
+ }
181
+ }
182
+
183
+ time = now;
184
+ };
185
+ }();
186
+
187
+ var clickHandler = function clickHandler(event) {
188
+ // Simulated events dispatched on the document
189
+ if (!(event.target instanceof Element)) {
190
+ return hideAllPoppers();
191
+ }
192
+
193
+ var el = closest(event.target, Selectors.TOOLTIPPED_EL);
194
+ var popper = closest(event.target, Selectors.POPPER);
195
+
196
+ if (popper) {
197
+ var ref = find(Store, function (ref) {
198
+ return ref.popper === popper;
199
+ });
200
+ var interactive = ref.settings.interactive;
201
+
202
+ if (interactive) return;
203
+ }
204
+
205
+ if (el) {
206
+ var _ref = find(Store, function (ref) {
207
+ return ref.el === el;
208
+ });
209
+ var _ref$settings = _ref.settings,
210
+ hideOnClick = _ref$settings.hideOnClick,
211
+ multiple = _ref$settings.multiple,
212
+ trigger = _ref$settings.trigger;
213
+
214
+ // Hide all poppers except the one belonging to the element that was clicked IF
215
+ // `multiple` is false AND they are a touch user, OR
216
+ // `multiple` is false AND it's triggered by a click
217
+
218
+ if (!multiple && Browser.touch || !multiple && trigger.indexOf('click') !== -1) {
219
+ return hideAllPoppers(_ref);
220
+ }
221
+
222
+ // If hideOnClick is not strictly true or triggered by a click don't hide poppers
223
+ if (hideOnClick !== true || trigger.indexOf('click') !== -1) return;
224
+ }
225
+
226
+ // Don't trigger a hide for tippy controllers, and don't needlessly run loop
227
+ if (closest(event.target, Selectors.CONTROLLER) || !document.querySelector(Selectors.POPPER)) return;
228
+
229
+ hideAllPoppers();
230
+ };
231
+
232
+ var blurHandler = function blurHandler(event) {
233
+ var _document = document,
234
+ el = _document.activeElement;
235
+
236
+ if (el && el.blur && matches.call(el, Selectors.TOOLTIPPED_EL)) {
237
+ el.blur();
238
+ }
239
+ };
240
+
241
+ // Hook events
242
+ document.addEventListener('click', clickHandler);
243
+ document.addEventListener('touchstart', touchHandler);
244
+ window.addEventListener('blur', blurHandler);
245
+
246
+ if (!Browser.SUPPORTS_TOUCH && (navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0)) {
247
+ document.addEventListener('pointerdown', touchHandler);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * To run a single time, once DOM is presumed to be ready
253
+ * @return {Boolean} whether the function has run or not
254
+ */
255
+ function init() {
256
+ if (init.done) return false;
257
+ init.done = true;
258
+
259
+ // If the script is in <head>, document.body is null, so it's set in the
260
+ // init function
261
+ Defaults.appendTo = document.body;
262
+
263
+ bindEventListeners();
264
+
265
+ return true;
266
+ }
267
+
268
+ /**
269
+ * Waits until next repaint to execute a fn
270
+ * @return {Function}
271
+ */
272
+ function queueExecution(fn) {
273
+ window.requestAnimationFrame(function () {
274
+ setTimeout(fn, 0);
275
+ });
276
+ }
277
+
278
+ /**
279
+ * Returns the supported prefixed property - only `webkit` is needed, `moz`, `ms` and `o` are obsolete
280
+ * @param {String} property
281
+ * @return {String} - browser supported prefixed property
282
+ */
283
+ function prefix(property) {
284
+ var prefixes = [false, 'webkit'];
285
+ var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
286
+
287
+ for (var i = 0; i < prefixes.length; i++) {
288
+ var _prefix = prefixes[i];
289
+ var prefixedProp = _prefix ? '' + _prefix + upperProp : property;
290
+ if (typeof window.document.body.style[prefixedProp] !== 'undefined') {
291
+ return prefixedProp;
292
+ }
293
+ }
294
+
295
+ return null;
296
+ }
297
+
298
+ /**
299
+ * Ponyfill for Array.prototype.findIndex
300
+ * @param {Array} arr
301
+ * @param {Function} checkFn
302
+ * @return index of the item in the array
303
+ */
304
+ function findIndex(arr, checkFn) {
305
+ if (Array.prototype.findIndex) {
306
+ return arr.findIndex(checkFn);
307
+ }
308
+
309
+ // fallback
310
+ return arr.indexOf(find(arr, checkFn));
311
+ }
312
+
313
+ /**
314
+ * Removes the title from the tooltipped element
315
+ * @param {Element} el
316
+ */
317
+ function removeTitle(el) {
318
+ var title = el.getAttribute('title');
319
+ el.setAttribute('data-original-title', title || 'html');
320
+ el.removeAttribute('title');
321
+ }
322
+
323
+ /**
324
+ * Determines if an element is visible in the viewport
325
+ * @param {Element} el
326
+ * @return {Boolean}
327
+ */
328
+ function elementIsInViewport(el) {
329
+ var rect = el.getBoundingClientRect();
330
+
331
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
332
+ }
333
+
334
+ /**
335
+ * Triggers a document repaint or reflow for CSS transition
336
+ * @param {Element} tooltip
337
+ * @param {Element} circle
338
+ */
339
+ function triggerReflow(tooltip, circle) {
340
+ // Safari needs the specific 'transform' property to be accessed
341
+ circle ? window.getComputedStyle(circle)[prefix('transform')] : window.getComputedStyle(tooltip).opacity;
342
+ }
343
+
344
+ /**
345
+ * Modifies elements' class lists
346
+ * @param {Element[]} els - Array of elements
347
+ * @param {Function} callback
348
+ */
349
+ function modifyClassList(els, callback) {
350
+ els.forEach(function (el) {
351
+ if (!el) return;
352
+ callback(el.classList);
353
+ });
354
+ }
355
+
356
+ /**
357
+ * Applies the transition duration to each element
358
+ * @param {Element[]} els - Array of elements
359
+ * @param {Number} duration
360
+ */
361
+ function applyTransitionDuration(els, duration) {
362
+ els.forEach(function (el) {
363
+ if (!el) return;
364
+
365
+ var isContent = matches.call(el, Selectors.CONTENT);
366
+
367
+ var _duration = isContent ? Math.round(duration / 1.3) : duration;
368
+
369
+ el.style[prefix('transitionDuration')] = _duration + 'ms';
370
+ });
371
+ }
372
+
373
+ /**
374
+ * Determines if a popper is currently visible
375
+ * @param {Element} popper
376
+ * @return {Boolean}
377
+ */
378
+ function isVisible(popper) {
379
+ return popper.style.visibility === 'visible';
380
+ }
381
+
382
+ function noop() {}
383
+
384
+ /**
385
+ * Returns the non-shifted placement (e.g., 'bottom-start' => 'bottom')
386
+ * @param {String} placement
387
+ * @return {String}
388
+ */
389
+ function getCorePlacement(placement) {
390
+ return placement.replace(/-.+/, '');
391
+ }
392
+
393
+ /**
394
+ * Mousemove event listener callback method for follow cursor setting
395
+ * @param {MouseEvent} e
396
+ */
397
+ function followCursorHandler(e) {
398
+ var _this = this;
399
+
400
+ var refData = find(Store, function (refData) {
401
+ return refData.el === _this;
402
+ });
403
+
404
+ var popper = refData.popper,
405
+ offset = refData.settings.offset;
406
+
407
+
408
+ var position = getCorePlacement(popper.getAttribute('x-placement'));
409
+ var halfPopperWidth = Math.round(popper.offsetWidth / 2);
410
+ var halfPopperHeight = Math.round(popper.offsetHeight / 2);
411
+ var viewportPadding = 5;
412
+ var pageWidth = document.documentElement.offsetWidth || document.body.offsetWidth;
413
+
414
+ var pageX = e.pageX,
415
+ pageY = e.pageY;
416
+
417
+
418
+ var x = void 0,
419
+ y = void 0;
420
+
421
+ switch (position) {
422
+ case 'top':
423
+ x = pageX - halfPopperWidth + offset;
424
+ y = pageY - 2.25 * halfPopperHeight;
425
+ break;
426
+ case 'left':
427
+ x = pageX - 2 * halfPopperWidth - 10;
428
+ y = pageY - halfPopperHeight + offset;
429
+ break;
430
+ case 'right':
431
+ x = pageX + halfPopperHeight;
432
+ y = pageY - halfPopperHeight + offset;
433
+ break;
434
+ case 'bottom':
435
+ x = pageX - halfPopperWidth + offset;
436
+ y = pageY + halfPopperHeight / 1.5;
437
+ break;
438
+ }
439
+
440
+ var isRightOverflowing = pageX + viewportPadding + halfPopperWidth + offset > pageWidth;
441
+ var isLeftOverflowing = pageX - viewportPadding - halfPopperWidth + offset < 0;
442
+
443
+ // Prevent left/right overflow
444
+ if (position === 'top' || position === 'bottom') {
445
+ if (isRightOverflowing) {
446
+ x = pageWidth - viewportPadding - 2 * halfPopperWidth;
447
+ }
448
+
449
+ if (isLeftOverflowing) {
450
+ x = viewportPadding;
451
+ }
452
+ }
453
+
454
+ popper.style[prefix('transform')] = 'translate3d(' + x + 'px, ' + y + 'px, 0)';
455
+ }
456
+
457
+ /**
458
+ * Returns an array of elements based on the selector input
459
+ * @param {String|Element|Element[]} selector
460
+ * @return {Element[]}
461
+ */
462
+ function getArrayOfElements(selector) {
463
+ if (selector instanceof Element) {
464
+ return [selector];
465
+ }
466
+
467
+ if (Array.isArray(selector)) {
468
+ return selector;
469
+ }
470
+
471
+ return [].slice.call(document.querySelectorAll(selector));
472
+ }
473
+
474
+ /**
475
+ * Prepares the callback functions for `show` and `hide` methods
476
+ * @param {Object} refData - the element/popper reference data
477
+ * @param {Number} duration
478
+ * @param {Function} callback - callback function to fire once transitions complete
479
+ */
480
+ function onTransitionEnd(refData, duration, callback) {
481
+ // Make callback synchronous if duration is 0
482
+ if (!duration) {
483
+ return callback();
484
+ }
485
+
486
+ var tooltip = refData.popper.querySelector(Selectors.TOOLTIP);
487
+ var transitionendFired = false;
488
+
489
+ var listenerCallback = function listenerCallback(e) {
490
+ if (e.target !== tooltip) return;
491
+
492
+ transitionendFired = true;
493
+
494
+ tooltip.removeEventListener('webkitTransitionEnd', listenerCallback);
495
+ tooltip.removeEventListener('transitionend', listenerCallback);
496
+
497
+ callback();
498
+ };
499
+
500
+ // Wait for transitions to complete
501
+ tooltip.addEventListener('webkitTransitionEnd', listenerCallback);
502
+ tooltip.addEventListener('transitionend', listenerCallback);
503
+
504
+ // transitionend listener sometimes may not fire
505
+ clearTimeout(refData._transitionendTimeout);
506
+ refData._transitionendTimeout = setTimeout(function () {
507
+ !transitionendFired && callback();
508
+ }, duration);
509
+ }
510
+
511
+ /**!
512
+ * @fileOverview Kickass library to create and place poppers near their reference elements.
513
+ * @version 1.11.1
514
+ * @license
515
+ * Copyright (c) 2016 Federico Zivolo and contributors
516
+ *
517
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
518
+ * of this software and associated documentation files (the "Software"), to deal
519
+ * in the Software without restriction, including without limitation the rights
520
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
521
+ * copies of the Software, and to permit persons to whom the Software is
522
+ * furnished to do so, subject to the following conditions:
523
+ *
524
+ * The above copyright notice and this permission notice shall be included in all
525
+ * copies or substantial portions of the Software.
526
+ *
527
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
528
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
529
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
530
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
531
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
532
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
533
+ * SOFTWARE.
534
+ */
535
+ var nativeHints = ['native code', '[object MutationObserverConstructor]'];
536
+
537
+ /**
538
+ * Determine if a function is implemented natively (as opposed to a polyfill).
539
+ * @method
540
+ * @memberof Popper.Utils
541
+ * @argument {Function | undefined} fn the function to check
542
+ * @returns {Boolean}
543
+ */
544
+ var isNative = function isNative(fn) {
545
+ return nativeHints.some(function (hint) {
546
+ return (fn || '').toString().indexOf(hint) > -1;
547
+ });
548
+ };
549
+
550
+ var isBrowser = typeof window !== 'undefined';
551
+ var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
552
+ var timeoutDuration = 0;
553
+ for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
554
+ if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
555
+ timeoutDuration = 1;
556
+ break;
557
+ }
558
+ }
559
+
560
+ function microtaskDebounce(fn) {
561
+ var scheduled = false;
562
+ var i = 0;
563
+ var elem = document.createElement('span');
564
+
565
+ // MutationObserver provides a mechanism for scheduling microtasks, which
566
+ // are scheduled *before* the next task. This gives us a way to debounce
567
+ // a function but ensure it's called *before* the next paint.
568
+ var observer = new MutationObserver(function () {
569
+ fn();
570
+ scheduled = false;
571
+ });
572
+
573
+ observer.observe(elem, { attributes: true });
574
+
575
+ return function () {
576
+ if (!scheduled) {
577
+ scheduled = true;
578
+ elem.setAttribute('x-index', i);
579
+ i = i + 1; // don't use compund (+=) because it doesn't get optimized in V8
580
+ }
581
+ };
582
+ }
583
+
584
+ function taskDebounce(fn) {
585
+ var scheduled = false;
586
+ return function () {
587
+ if (!scheduled) {
588
+ scheduled = true;
589
+ setTimeout(function () {
590
+ scheduled = false;
591
+ fn();
592
+ }, timeoutDuration);
593
+ }
594
+ };
595
+ }
596
+
597
+ // It's common for MutationObserver polyfills to be seen in the wild, however
598
+ // these rely on Mutation Events which only occur when an element is connected
599
+ // to the DOM. The algorithm used in this module does not use a connected element,
600
+ // and so we must ensure that a *native* MutationObserver is available.
601
+ var supportsNativeMutationObserver = isBrowser && isNative(window.MutationObserver);
602
+
603
+ /**
604
+ * Create a debounced version of a method, that's asynchronously deferred
605
+ * but called in the minimum time possible.
606
+ *
607
+ * @method
608
+ * @memberof Popper.Utils
609
+ * @argument {Function} fn
610
+ * @returns {Function}
611
+ */
612
+ var debounce = supportsNativeMutationObserver ? microtaskDebounce : taskDebounce;
613
+
614
+ /**
615
+ * Check if the given variable is a function
616
+ * @method
617
+ * @memberof Popper.Utils
618
+ * @argument {Any} functionToCheck - variable to check
619
+ * @returns {Boolean} answer to: is a function?
620
+ */
621
+ function isFunction(functionToCheck) {
622
+ var getType = {};
623
+ return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
624
+ }
625
+
626
+ /**
627
+ * Get CSS computed property of the given element
628
+ * @method
629
+ * @memberof Popper.Utils
630
+ * @argument {Eement} element
631
+ * @argument {String} property
632
+ */
633
+ function getStyleComputedProperty(element, property) {
634
+ if (element.nodeType !== 1) {
635
+ return [];
636
+ }
637
+ // NOTE: 1 DOM access here
638
+ var css = window.getComputedStyle(element, null);
639
+ return property ? css[property] : css;
640
+ }
641
+
642
+ /**
643
+ * Returns the parentNode or the host of the element
644
+ * @method
645
+ * @memberof Popper.Utils
646
+ * @argument {Element} element
647
+ * @returns {Element} parent
648
+ */
649
+ function getParentNode(element) {
650
+ if (element.nodeName === 'HTML') {
651
+ return element;
652
+ }
653
+ return element.parentNode || element.host;
654
+ }
655
+
656
+ /**
657
+ * Returns the scrolling parent of the given element
658
+ * @method
659
+ * @memberof Popper.Utils
660
+ * @argument {Element} element
661
+ * @returns {Element} scroll parent
662
+ */
663
+ function getScrollParent(element) {
664
+ // Return body, `getScroll` will take care to get the correct `scrollTop` from it
665
+ if (!element || ['HTML', 'BODY', '#document'].indexOf(element.nodeName) !== -1) {
666
+ return window.document.body;
667
+ }
668
+
669
+ // Firefox want us to check `-x` and `-y` variations as well
670
+
671
+ var _getStyleComputedProp = getStyleComputedProperty(element),
672
+ overflow = _getStyleComputedProp.overflow,
673
+ overflowX = _getStyleComputedProp.overflowX,
674
+ overflowY = _getStyleComputedProp.overflowY;
675
+
676
+ if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {
677
+ return element;
678
+ }
679
+
680
+ return getScrollParent(getParentNode(element));
681
+ }
682
+
683
+ /**
684
+ * Returns the offset parent of the given element
685
+ * @method
686
+ * @memberof Popper.Utils
687
+ * @argument {Element} element
688
+ * @returns {Element} offset parent
689
+ */
690
+ function getOffsetParent(element) {
691
+ // NOTE: 1 DOM access here
692
+ var offsetParent = element && element.offsetParent;
693
+ var nodeName = offsetParent && offsetParent.nodeName;
694
+
695
+ if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
696
+ return window.document.documentElement;
697
+ }
698
+
699
+ // .offsetParent will return the closest TD or TABLE in case
700
+ // no offsetParent is present, I hate this job...
701
+ if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
702
+ return getOffsetParent(offsetParent);
703
+ }
704
+
705
+ return offsetParent;
706
+ }
707
+
708
+ function isOffsetContainer(element) {
709
+ var nodeName = element.nodeName;
710
+
711
+ if (nodeName === 'BODY') {
712
+ return false;
713
+ }
714
+ return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
715
+ }
716
+
717
+ /**
718
+ * Finds the root node (document, shadowDOM root) of the given element
719
+ * @method
720
+ * @memberof Popper.Utils
721
+ * @argument {Element} node
722
+ * @returns {Element} root node
723
+ */
724
+ function getRoot(node) {
725
+ if (node.parentNode !== null) {
726
+ return getRoot(node.parentNode);
727
+ }
728
+
729
+ return node;
730
+ }
731
+
732
+ /**
733
+ * Finds the offset parent common to the two provided nodes
734
+ * @method
735
+ * @memberof Popper.Utils
736
+ * @argument {Element} element1
737
+ * @argument {Element} element2
738
+ * @returns {Element} common offset parent
739
+ */
740
+ function findCommonOffsetParent(element1, element2) {
741
+ // This check is needed to avoid errors in case one of the elements isn't defined for any reason
742
+ if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
743
+ return window.document.documentElement;
744
+ }
745
+
746
+ // Here we make sure to give as "start" the element that comes first in the DOM
747
+ var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
748
+ var start = order ? element1 : element2;
749
+ var end = order ? element2 : element1;
750
+
751
+ // Get common ancestor container
752
+ var range = document.createRange();
753
+ range.setStart(start, 0);
754
+ range.setEnd(end, 0);
755
+ var commonAncestorContainer = range.commonAncestorContainer;
756
+
757
+ // Both nodes are inside #document
758
+
759
+ if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
760
+ if (isOffsetContainer(commonAncestorContainer)) {
761
+ return commonAncestorContainer;
762
+ }
763
+
764
+ return getOffsetParent(commonAncestorContainer);
765
+ }
766
+
767
+ // one of the nodes is inside shadowDOM, find which one
768
+ var element1root = getRoot(element1);
769
+ if (element1root.host) {
770
+ return findCommonOffsetParent(element1root.host, element2);
771
+ } else {
772
+ return findCommonOffsetParent(element1, getRoot(element2).host);
773
+ }
774
+ }
775
+
776
+ /**
777
+ * Gets the scroll value of the given element in the given side (top and left)
778
+ * @method
779
+ * @memberof Popper.Utils
780
+ * @argument {Element} element
781
+ * @argument {String} side `top` or `left`
782
+ * @returns {number} amount of scrolled pixels
783
+ */
784
+ function getScroll(element) {
785
+ var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
786
+
787
+ var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
788
+ var nodeName = element.nodeName;
789
+
790
+ if (nodeName === 'BODY' || nodeName === 'HTML') {
791
+ var html = window.document.documentElement;
792
+ var scrollingElement = window.document.scrollingElement || html;
793
+ return scrollingElement[upperSide];
794
+ }
795
+
796
+ return element[upperSide];
797
+ }
798
+
799
+ /*
800
+ * Sum or subtract the element scroll values (left and top) from a given rect object
801
+ * @method
802
+ * @memberof Popper.Utils
803
+ * @param {Object} rect - Rect object you want to change
804
+ * @param {HTMLElement} element - The element from the function reads the scroll values
805
+ * @param {Boolean} subtract - set to true if you want to subtract the scroll values
806
+ * @return {Object} rect - The modifier rect object
807
+ */
808
+ function includeScroll(rect, element) {
809
+ var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
810
+
811
+ var scrollTop = getScroll(element, 'top');
812
+ var scrollLeft = getScroll(element, 'left');
813
+ var modifier = subtract ? -1 : 1;
814
+ rect.top += scrollTop * modifier;
815
+ rect.bottom += scrollTop * modifier;
816
+ rect.left += scrollLeft * modifier;
817
+ rect.right += scrollLeft * modifier;
818
+ return rect;
819
+ }
820
+
821
+ /*
822
+ * Helper to detect borders of a given element
823
+ * @method
824
+ * @memberof Popper.Utils
825
+ * @param {CSSStyleDeclaration} styles
826
+ * Result of `getStyleComputedProperty` on the given element
827
+ * @param {String} axis - `x` or `y`
828
+ * @return {number} borders - The borders size of the given axis
829
+ */
830
+
831
+ function getBordersSize(styles, axis) {
832
+ var sideA = axis === 'x' ? 'Left' : 'Top';
833
+ var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
834
+
835
+ return +styles['border' + sideA + 'Width'].split('px')[0] + +styles['border' + sideB + 'Width'].split('px')[0];
836
+ }
837
+
838
+ /**
839
+ * Tells if you are running Internet Explorer 10
840
+ * @method
841
+ * @memberof Popper.Utils
842
+ * @returns {Boolean} isIE10
843
+ */
844
+ var isIE10 = undefined;
845
+
846
+ var isIE10$1 = function isIE10$1() {
847
+ if (isIE10 === undefined) {
848
+ isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;
849
+ }
850
+ return isIE10;
851
+ };
852
+
853
+ function getSize(axis, body, html, computedStyle) {
854
+ return Math.max(body['offset' + axis], html['client' + axis], html['offset' + axis], isIE10$1() ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0);
855
+ }
856
+
857
+ function getWindowSizes() {
858
+ var body = window.document.body;
859
+ var html = window.document.documentElement;
860
+ var computedStyle = isIE10$1() && window.getComputedStyle(html);
861
+
862
+ return {
863
+ height: getSize('Height', body, html, computedStyle),
864
+ width: getSize('Width', body, html, computedStyle)
865
+ };
866
+ }
867
+
868
+ var classCallCheck = function classCallCheck(instance, Constructor) {
869
+ if (!(instance instanceof Constructor)) {
870
+ throw new TypeError("Cannot call a class as a function");
871
+ }
872
+ };
873
+
874
+ var createClass = function () {
875
+ function defineProperties(target, props) {
876
+ for (var i = 0; i < props.length; i++) {
877
+ var descriptor = props[i];
878
+ descriptor.enumerable = descriptor.enumerable || false;
879
+ descriptor.configurable = true;
880
+ if ("value" in descriptor) descriptor.writable = true;
881
+ Object.defineProperty(target, descriptor.key, descriptor);
882
+ }
883
+ }
884
+
885
+ return function (Constructor, protoProps, staticProps) {
886
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
887
+ if (staticProps) defineProperties(Constructor, staticProps);
888
+ return Constructor;
889
+ };
890
+ }();
891
+
892
+ var defineProperty = function defineProperty(obj, key, value) {
893
+ if (key in obj) {
894
+ Object.defineProperty(obj, key, {
895
+ value: value,
896
+ enumerable: true,
897
+ configurable: true,
898
+ writable: true
899
+ });
900
+ } else {
901
+ obj[key] = value;
902
+ }
903
+
904
+ return obj;
905
+ };
906
+
907
+ var _extends = Object.assign || function (target) {
908
+ for (var i = 1; i < arguments.length; i++) {
909
+ var source = arguments[i];
910
+
911
+ for (var key in source) {
912
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
913
+ target[key] = source[key];
914
+ }
915
+ }
916
+ }
917
+
918
+ return target;
919
+ };
920
+
921
+ /**
922
+ * Given element offsets, generate an output similar to getBoundingClientRect
923
+ * @method
924
+ * @memberof Popper.Utils
925
+ * @argument {Object} offsets
926
+ * @returns {Object} ClientRect like output
927
+ */
928
+ function getClientRect(offsets) {
929
+ return _extends({}, offsets, {
930
+ right: offsets.left + offsets.width,
931
+ bottom: offsets.top + offsets.height
932
+ });
933
+ }
934
+
935
+ /**
936
+ * Get bounding client rect of given element
937
+ * @method
938
+ * @memberof Popper.Utils
939
+ * @param {HTMLElement} element
940
+ * @return {Object} client rect
941
+ */
942
+ function getBoundingClientRect(element) {
943
+ var rect = {};
944
+
945
+ // IE10 10 FIX: Please, don't ask, the element isn't
946
+ // considered in DOM in some circumstances...
947
+ // This isn't reproducible in IE10 compatibility mode of IE11
948
+ if (isIE10$1()) {
949
+ try {
950
+ rect = element.getBoundingClientRect();
951
+ var scrollTop = getScroll(element, 'top');
952
+ var scrollLeft = getScroll(element, 'left');
953
+ rect.top += scrollTop;
954
+ rect.left += scrollLeft;
955
+ rect.bottom += scrollTop;
956
+ rect.right += scrollLeft;
957
+ } catch (err) {}
958
+ } else {
959
+ rect = element.getBoundingClientRect();
960
+ }
961
+
962
+ var result = {
963
+ left: rect.left,
964
+ top: rect.top,
965
+ width: rect.right - rect.left,
966
+ height: rect.bottom - rect.top
967
+ };
968
+
969
+ // subtract scrollbar size from sizes
970
+ var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {};
971
+ var width = sizes.width || element.clientWidth || result.right - result.left;
972
+ var height = sizes.height || element.clientHeight || result.bottom - result.top;
973
+
974
+ var horizScrollbar = element.offsetWidth - width;
975
+ var vertScrollbar = element.offsetHeight - height;
976
+
977
+ // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
978
+ // we make this check conditional for performance reasons
979
+ if (horizScrollbar || vertScrollbar) {
980
+ var styles = getStyleComputedProperty(element);
981
+ horizScrollbar -= getBordersSize(styles, 'x');
982
+ vertScrollbar -= getBordersSize(styles, 'y');
983
+
984
+ result.width -= horizScrollbar;
985
+ result.height -= vertScrollbar;
986
+ }
987
+
988
+ return getClientRect(result);
989
+ }
990
+
991
+ function getOffsetRectRelativeToArbitraryNode(children, parent) {
992
+ var isIE10 = isIE10$1();
993
+ var isHTML = parent.nodeName === 'HTML';
994
+ var childrenRect = getBoundingClientRect(children);
995
+ var parentRect = getBoundingClientRect(parent);
996
+ var scrollParent = getScrollParent(children);
997
+
998
+ var styles = getStyleComputedProperty(parent);
999
+ var borderTopWidth = +styles.borderTopWidth.split('px')[0];
1000
+ var borderLeftWidth = +styles.borderLeftWidth.split('px')[0];
1001
+
1002
+ var offsets = getClientRect({
1003
+ top: childrenRect.top - parentRect.top - borderTopWidth,
1004
+ left: childrenRect.left - parentRect.left - borderLeftWidth,
1005
+ width: childrenRect.width,
1006
+ height: childrenRect.height
1007
+ });
1008
+ offsets.marginTop = 0;
1009
+ offsets.marginLeft = 0;
1010
+
1011
+ // Subtract margins of documentElement in case it's being used as parent
1012
+ // we do this only on HTML because it's the only element that behaves
1013
+ // differently when margins are applied to it. The margins are included in
1014
+ // the box of the documentElement, in the other cases not.
1015
+ if (!isIE10 && isHTML) {
1016
+ var marginTop = +styles.marginTop.split('px')[0];
1017
+ var marginLeft = +styles.marginLeft.split('px')[0];
1018
+
1019
+ offsets.top -= borderTopWidth - marginTop;
1020
+ offsets.bottom -= borderTopWidth - marginTop;
1021
+ offsets.left -= borderLeftWidth - marginLeft;
1022
+ offsets.right -= borderLeftWidth - marginLeft;
1023
+
1024
+ // Attach marginTop and marginLeft because in some circumstances we may need them
1025
+ offsets.marginTop = marginTop;
1026
+ offsets.marginLeft = marginLeft;
1027
+ }
1028
+
1029
+ if (isIE10 ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
1030
+ offsets = includeScroll(offsets, parent);
1031
+ }
1032
+
1033
+ return offsets;
1034
+ }
1035
+
1036
+ function getViewportOffsetRectRelativeToArtbitraryNode(element) {
1037
+ var html = window.document.documentElement;
1038
+ var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
1039
+ var width = Math.max(html.clientWidth, window.innerWidth || 0);
1040
+ var height = Math.max(html.clientHeight, window.innerHeight || 0);
1041
+
1042
+ var scrollTop = getScroll(html);
1043
+ var scrollLeft = getScroll(html, 'left');
1044
+
1045
+ var offset = {
1046
+ top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
1047
+ left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
1048
+ width: width,
1049
+ height: height
1050
+ };
1051
+
1052
+ return getClientRect(offset);
1053
+ }
1054
+
1055
+ /**
1056
+ * Check if the given element is fixed or is inside a fixed parent
1057
+ * @method
1058
+ * @memberof Popper.Utils
1059
+ * @argument {Element} element
1060
+ * @argument {Element} customContainer
1061
+ * @returns {Boolean} answer to "isFixed?"
1062
+ */
1063
+ function isFixed(element) {
1064
+ var nodeName = element.nodeName;
1065
+ if (nodeName === 'BODY' || nodeName === 'HTML') {
1066
+ return false;
1067
+ }
1068
+ if (getStyleComputedProperty(element, 'position') === 'fixed') {
1069
+ return true;
1070
+ }
1071
+ return isFixed(getParentNode(element));
1072
+ }
1073
+
1074
+ /**
1075
+ * Computed the boundaries limits and return them
1076
+ * @method
1077
+ * @memberof Popper.Utils
1078
+ * @param {HTMLElement} popper
1079
+ * @param {HTMLElement} reference
1080
+ * @param {number} padding
1081
+ * @param {HTMLElement} boundariesElement - Element used to define the boundaries
1082
+ * @returns {Object} Coordinates of the boundaries
1083
+ */
1084
+ function getBoundaries(popper, reference, padding, boundariesElement) {
1085
+ // NOTE: 1 DOM access here
1086
+ var boundaries = { top: 0, left: 0 };
1087
+ var offsetParent = findCommonOffsetParent(popper, reference);
1088
+
1089
+ // Handle viewport case
1090
+ if (boundariesElement === 'viewport') {
1091
+ boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent);
1092
+ } else {
1093
+ // Handle other cases based on DOM element used as boundaries
1094
+ var boundariesNode = void 0;
1095
+ if (boundariesElement === 'scrollParent') {
1096
+ boundariesNode = getScrollParent(getParentNode(popper));
1097
+ if (boundariesNode.nodeName === 'BODY') {
1098
+ boundariesNode = window.document.documentElement;
1099
+ }
1100
+ } else if (boundariesElement === 'window') {
1101
+ boundariesNode = window.document.documentElement;
1102
+ } else {
1103
+ boundariesNode = boundariesElement;
1104
+ }
1105
+
1106
+ var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent);
1107
+
1108
+ // In case of HTML, we need a different computation
1109
+ if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
1110
+ var _getWindowSizes = getWindowSizes(),
1111
+ height = _getWindowSizes.height,
1112
+ width = _getWindowSizes.width;
1113
+
1114
+ boundaries.top += offsets.top - offsets.marginTop;
1115
+ boundaries.bottom = height + offsets.top;
1116
+ boundaries.left += offsets.left - offsets.marginLeft;
1117
+ boundaries.right = width + offsets.left;
1118
+ } else {
1119
+ // for all the other DOM elements, this one is good
1120
+ boundaries = offsets;
1121
+ }
1122
+ }
1123
+
1124
+ // Add paddings
1125
+ boundaries.left += padding;
1126
+ boundaries.top += padding;
1127
+ boundaries.right -= padding;
1128
+ boundaries.bottom -= padding;
1129
+
1130
+ return boundaries;
1131
+ }
1132
+
1133
+ function getArea(_ref) {
1134
+ var width = _ref.width,
1135
+ height = _ref.height;
1136
+
1137
+ return width * height;
1138
+ }
1139
+
1140
+ /**
1141
+ * Utility used to transform the `auto` placement to the placement with more
1142
+ * available space.
1143
+ * @method
1144
+ * @memberof Popper.Utils
1145
+ * @argument {Object} data - The data object generated by update method
1146
+ * @argument {Object} options - Modifiers configuration and options
1147
+ * @returns {Object} The data object, properly modified
1148
+ */
1149
+ function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
1150
+ var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
1151
+
1152
+ if (placement.indexOf('auto') === -1) {
1153
+ return placement;
1154
+ }
1155
+
1156
+ var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
1157
+
1158
+ var rects = {
1159
+ top: {
1160
+ width: boundaries.width,
1161
+ height: refRect.top - boundaries.top
1162
+ },
1163
+ right: {
1164
+ width: boundaries.right - refRect.right,
1165
+ height: boundaries.height
1166
+ },
1167
+ bottom: {
1168
+ width: boundaries.width,
1169
+ height: boundaries.bottom - refRect.bottom
1170
+ },
1171
+ left: {
1172
+ width: refRect.left - boundaries.left,
1173
+ height: boundaries.height
1174
+ }
1175
+ };
1176
+
1177
+ var sortedAreas = Object.keys(rects).map(function (key) {
1178
+ return _extends({
1179
+ key: key
1180
+ }, rects[key], {
1181
+ area: getArea(rects[key])
1182
+ });
1183
+ }).sort(function (a, b) {
1184
+ return b.area - a.area;
1185
+ });
1186
+
1187
+ var filteredAreas = sortedAreas.filter(function (_ref2) {
1188
+ var width = _ref2.width,
1189
+ height = _ref2.height;
1190
+ return width >= popper.clientWidth && height >= popper.clientHeight;
1191
+ });
1192
+
1193
+ var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
1194
+
1195
+ var variation = placement.split('-')[1];
1196
+
1197
+ return computedPlacement + (variation ? '-' + variation : '');
1198
+ }
1199
+
1200
+ /**
1201
+ * Get offsets to the reference element
1202
+ * @method
1203
+ * @memberof Popper.Utils
1204
+ * @param {Object} state
1205
+ * @param {Element} popper - the popper element
1206
+ * @param {Element} reference - the reference element (the popper will be relative to this)
1207
+ * @returns {Object} An object containing the offsets which will be applied to the popper
1208
+ */
1209
+ function getReferenceOffsets(state, popper, reference) {
1210
+ var commonOffsetParent = findCommonOffsetParent(popper, reference);
1211
+ return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent);
1212
+ }
1213
+
1214
+ /**
1215
+ * Get the outer sizes of the given element (offset size + margins)
1216
+ * @method
1217
+ * @memberof Popper.Utils
1218
+ * @argument {Element} element
1219
+ * @returns {Object} object containing width and height properties
1220
+ */
1221
+ function getOuterSizes(element) {
1222
+ var styles = window.getComputedStyle(element);
1223
+ var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
1224
+ var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
1225
+ var result = {
1226
+ width: element.offsetWidth + y,
1227
+ height: element.offsetHeight + x
1228
+ };
1229
+ return result;
1230
+ }
1231
+
1232
+ /**
1233
+ * Get the opposite placement of the given one
1234
+ * @method
1235
+ * @memberof Popper.Utils
1236
+ * @argument {String} placement
1237
+ * @returns {String} flipped placement
1238
+ */
1239
+ function getOppositePlacement(placement) {
1240
+ var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
1241
+ return placement.replace(/left|right|bottom|top/g, function (matched) {
1242
+ return hash[matched];
1243
+ });
1244
+ }
1245
+
1246
+ /**
1247
+ * Get offsets to the popper
1248
+ * @method
1249
+ * @memberof Popper.Utils
1250
+ * @param {Object} position - CSS position the Popper will get applied
1251
+ * @param {HTMLElement} popper - the popper element
1252
+ * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
1253
+ * @param {String} placement - one of the valid placement options
1254
+ * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
1255
+ */
1256
+ function getPopperOffsets(popper, referenceOffsets, placement) {
1257
+ placement = placement.split('-')[0];
1258
+
1259
+ // Get popper node sizes
1260
+ var popperRect = getOuterSizes(popper);
1261
+
1262
+ // Add position, width and height to our offsets object
1263
+ var popperOffsets = {
1264
+ width: popperRect.width,
1265
+ height: popperRect.height
1266
+ };
1267
+
1268
+ // depending by the popper placement we have to compute its offsets slightly differently
1269
+ var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
1270
+ var mainSide = isHoriz ? 'top' : 'left';
1271
+ var secondarySide = isHoriz ? 'left' : 'top';
1272
+ var measurement = isHoriz ? 'height' : 'width';
1273
+ var secondaryMeasurement = !isHoriz ? 'height' : 'width';
1274
+
1275
+ popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
1276
+ if (placement === secondarySide) {
1277
+ popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
1278
+ } else {
1279
+ popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
1280
+ }
1281
+
1282
+ return popperOffsets;
1283
+ }
1284
+
1285
+ /**
1286
+ * Mimics the `find` method of Array
1287
+ * @method
1288
+ * @memberof Popper.Utils
1289
+ * @argument {Array} arr
1290
+ * @argument prop
1291
+ * @argument value
1292
+ * @returns index or -1
1293
+ */
1294
+ function find$1(arr, check) {
1295
+ // use native find if supported
1296
+ if (Array.prototype.find) {
1297
+ return arr.find(check);
1298
+ }
1299
+
1300
+ // use `filter` to obtain the same behavior of `find`
1301
+ return arr.filter(check)[0];
1302
+ }
1303
+
1304
+ /**
1305
+ * Return the index of the matching object
1306
+ * @method
1307
+ * @memberof Popper.Utils
1308
+ * @argument {Array} arr
1309
+ * @argument prop
1310
+ * @argument value
1311
+ * @returns index or -1
1312
+ */
1313
+ function findIndex$1(arr, prop, value) {
1314
+ // use native findIndex if supported
1315
+ if (Array.prototype.findIndex) {
1316
+ return arr.findIndex(function (cur) {
1317
+ return cur[prop] === value;
1318
+ });
1319
+ }
1320
+
1321
+ // use `find` + `indexOf` if `findIndex` isn't supported
1322
+ var match = find$1(arr, function (obj) {
1323
+ return obj[prop] === value;
1324
+ });
1325
+ return arr.indexOf(match);
1326
+ }
1327
+
1328
+ /**
1329
+ * Loop trough the list of modifiers and run them in order,
1330
+ * each of them will then edit the data object.
1331
+ * @method
1332
+ * @memberof Popper.Utils
1333
+ * @param {dataObject} data
1334
+ * @param {Array} modifiers
1335
+ * @param {String} ends - Optional modifier name used as stopper
1336
+ * @returns {dataObject}
1337
+ */
1338
+ function runModifiers(modifiers, data, ends) {
1339
+ var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex$1(modifiers, 'name', ends));
1340
+
1341
+ modifiersToRun.forEach(function (modifier) {
1342
+ if (modifier.function) {
1343
+ console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
1344
+ }
1345
+ var fn = modifier.function || modifier.fn;
1346
+ if (modifier.enabled && isFunction(fn)) {
1347
+ // Add properties to offsets to make them a complete clientRect object
1348
+ // we do this before each modifier to make sure the previous one doesn't
1349
+ // mess with these values
1350
+ data.offsets.popper = getClientRect(data.offsets.popper);
1351
+ data.offsets.reference = getClientRect(data.offsets.reference);
1352
+
1353
+ data = fn(data, modifier);
1354
+ }
1355
+ });
1356
+
1357
+ return data;
1358
+ }
1359
+
1360
+ /**
1361
+ * Updates the position of the popper, computing the new offsets and applying
1362
+ * the new style.<br />
1363
+ * Prefer `scheduleUpdate` over `update` because of performance reasons.
1364
+ * @method
1365
+ * @memberof Popper
1366
+ */
1367
+ function update() {
1368
+ // if popper is destroyed, don't perform any further update
1369
+ if (this.state.isDestroyed) {
1370
+ return;
1371
+ }
1372
+
1373
+ var data = {
1374
+ instance: this,
1375
+ styles: {},
1376
+ attributes: {},
1377
+ flipped: false,
1378
+ offsets: {}
1379
+ };
1380
+
1381
+ // compute reference element offsets
1382
+ data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference);
1383
+
1384
+ // compute auto placement, store placement inside the data object,
1385
+ // modifiers will be able to edit `placement` if needed
1386
+ // and refer to originalPlacement to know the original value
1387
+ data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
1388
+
1389
+ // store the computed placement inside `originalPlacement`
1390
+ data.originalPlacement = data.placement;
1391
+
1392
+ // compute the popper offsets
1393
+ data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
1394
+ data.offsets.popper.position = 'absolute';
1395
+
1396
+ // run the modifiers
1397
+ data = runModifiers(this.modifiers, data);
1398
+
1399
+ // the first `update` will call `onCreate` callback
1400
+ // the other ones will call `onUpdate` callback
1401
+ if (!this.state.isCreated) {
1402
+ this.state.isCreated = true;
1403
+ this.options.onCreate(data);
1404
+ } else {
1405
+ this.options.onUpdate(data);
1406
+ }
1407
+ }
1408
+
1409
+ /**
1410
+ * Helper used to know if the given modifier is enabled.
1411
+ * @method
1412
+ * @memberof Popper.Utils
1413
+ * @returns {Boolean}
1414
+ */
1415
+ function isModifierEnabled(modifiers, modifierName) {
1416
+ return modifiers.some(function (_ref) {
1417
+ var name = _ref.name,
1418
+ enabled = _ref.enabled;
1419
+ return enabled && name === modifierName;
1420
+ });
1421
+ }
1422
+
1423
+ /**
1424
+ * Get the prefixed supported property name
1425
+ * @method
1426
+ * @memberof Popper.Utils
1427
+ * @argument {String} property (camelCase)
1428
+ * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
1429
+ */
1430
+ function getSupportedPropertyName(property) {
1431
+ var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
1432
+ var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
1433
+
1434
+ for (var i = 0; i < prefixes.length - 1; i++) {
1435
+ var prefix = prefixes[i];
1436
+ var toCheck = prefix ? '' + prefix + upperProp : property;
1437
+ if (typeof window.document.body.style[toCheck] !== 'undefined') {
1438
+ return toCheck;
1439
+ }
1440
+ }
1441
+ return null;
1442
+ }
1443
+
1444
+ /**
1445
+ * Destroy the popper
1446
+ * @method
1447
+ * @memberof Popper
1448
+ */
1449
+ function destroy() {
1450
+ this.state.isDestroyed = true;
1451
+
1452
+ // touch DOM only if `applyStyle` modifier is enabled
1453
+ if (isModifierEnabled(this.modifiers, 'applyStyle')) {
1454
+ this.popper.removeAttribute('x-placement');
1455
+ this.popper.style.left = '';
1456
+ this.popper.style.position = '';
1457
+ this.popper.style.top = '';
1458
+ this.popper.style[getSupportedPropertyName('transform')] = '';
1459
+ }
1460
+
1461
+ this.disableEventListeners();
1462
+
1463
+ // remove the popper if user explicity asked for the deletion on destroy
1464
+ // do not use `remove` because IE11 doesn't support it
1465
+ if (this.options.removeOnDestroy) {
1466
+ this.popper.parentNode.removeChild(this.popper);
1467
+ }
1468
+ return this;
1469
+ }
1470
+
1471
+ function attachToScrollParents(scrollParent, event, callback, scrollParents) {
1472
+ var isBody = scrollParent.nodeName === 'BODY';
1473
+ var target = isBody ? window : scrollParent;
1474
+ target.addEventListener(event, callback, { passive: true });
1475
+
1476
+ if (!isBody) {
1477
+ attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
1478
+ }
1479
+ scrollParents.push(target);
1480
+ }
1481
+
1482
+ /**
1483
+ * Setup needed event listeners used to update the popper position
1484
+ * @method
1485
+ * @memberof Popper.Utils
1486
+ * @private
1487
+ */
1488
+ function setupEventListeners(reference, options, state, updateBound) {
1489
+ // Resize event listener on window
1490
+ state.updateBound = updateBound;
1491
+ window.addEventListener('resize', state.updateBound, { passive: true });
1492
+
1493
+ // Scroll event listener on scroll parents
1494
+ var scrollElement = getScrollParent(reference);
1495
+ attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
1496
+ state.scrollElement = scrollElement;
1497
+ state.eventsEnabled = true;
1498
+
1499
+ return state;
1500
+ }
1501
+
1502
+ /**
1503
+ * It will add resize/scroll events and start recalculating
1504
+ * position of the popper element when they are triggered.
1505
+ * @method
1506
+ * @memberof Popper
1507
+ */
1508
+ function enableEventListeners() {
1509
+ if (!this.state.eventsEnabled) {
1510
+ this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
1511
+ }
1512
+ }
1513
+
1514
+ /**
1515
+ * Remove event listeners used to update the popper position
1516
+ * @method
1517
+ * @memberof Popper.Utils
1518
+ * @private
1519
+ */
1520
+ function removeEventListeners(reference, state) {
1521
+ // Remove resize event listener on window
1522
+ window.removeEventListener('resize', state.updateBound);
1523
+
1524
+ // Remove scroll event listener on scroll parents
1525
+ state.scrollParents.forEach(function (target) {
1526
+ target.removeEventListener('scroll', state.updateBound);
1527
+ });
1528
+
1529
+ // Reset state
1530
+ state.updateBound = null;
1531
+ state.scrollParents = [];
1532
+ state.scrollElement = null;
1533
+ state.eventsEnabled = false;
1534
+ return state;
1535
+ }
1536
+
1537
+ /**
1538
+ * It will remove resize/scroll events and won't recalculate popper position
1539
+ * when they are triggered. It also won't trigger onUpdate callback anymore,
1540
+ * unless you call `update` method manually.
1541
+ * @method
1542
+ * @memberof Popper
1543
+ */
1544
+ function disableEventListeners() {
1545
+ if (this.state.eventsEnabled) {
1546
+ window.cancelAnimationFrame(this.scheduleUpdate);
1547
+ this.state = removeEventListeners(this.reference, this.state);
1548
+ }
1549
+ }
1550
+
1551
+ /**
1552
+ * Tells if a given input is a number
1553
+ * @method
1554
+ * @memberof Popper.Utils
1555
+ * @param {*} input to check
1556
+ * @return {Boolean}
1557
+ */
1558
+ function isNumeric(n) {
1559
+ return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
1560
+ }
1561
+
1562
+ /**
1563
+ * Set the style to the given popper
1564
+ * @method
1565
+ * @memberof Popper.Utils
1566
+ * @argument {Element} element - Element to apply the style to
1567
+ * @argument {Object} styles
1568
+ * Object with a list of properties and values which will be applied to the element
1569
+ */
1570
+ function setStyles(element, styles) {
1571
+ Object.keys(styles).forEach(function (prop) {
1572
+ var unit = '';
1573
+ // add unit if the value is numeric and is one of the following
1574
+ if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
1575
+ unit = 'px';
1576
+ }
1577
+ element.style[prop] = styles[prop] + unit;
1578
+ });
1579
+ }
1580
+
1581
+ /**
1582
+ * Set the attributes to the given popper
1583
+ * @method
1584
+ * @memberof Popper.Utils
1585
+ * @argument {Element} element - Element to apply the attributes to
1586
+ * @argument {Object} styles
1587
+ * Object with a list of properties and values which will be applied to the element
1588
+ */
1589
+ function setAttributes(element, attributes) {
1590
+ Object.keys(attributes).forEach(function (prop) {
1591
+ var value = attributes[prop];
1592
+ if (value !== false) {
1593
+ element.setAttribute(prop, attributes[prop]);
1594
+ } else {
1595
+ element.removeAttribute(prop);
1596
+ }
1597
+ });
1598
+ }
1599
+
1600
+ /**
1601
+ * @function
1602
+ * @memberof Modifiers
1603
+ * @argument {Object} data - The data object generated by `update` method
1604
+ * @argument {Object} data.styles - List of style properties - values to apply to popper element
1605
+ * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
1606
+ * @argument {Object} options - Modifiers configuration and options
1607
+ * @returns {Object} The same data object
1608
+ */
1609
+ function applyStyle(data) {
1610
+ // any property present in `data.styles` will be applied to the popper,
1611
+ // in this way we can make the 3rd party modifiers add custom styles to it
1612
+ // Be aware, modifiers could override the properties defined in the previous
1613
+ // lines of this modifier!
1614
+ setStyles(data.instance.popper, data.styles);
1615
+
1616
+ // any property present in `data.attributes` will be applied to the popper,
1617
+ // they will be set as HTML attributes of the element
1618
+ setAttributes(data.instance.popper, data.attributes);
1619
+
1620
+ // if the arrow style has been computed, apply the arrow style
1621
+ if (data.offsets.arrow) {
1622
+ setStyles(data.arrowElement, data.offsets.arrow);
1623
+ }
1624
+
1625
+ return data;
1626
+ }
1627
+
1628
+ /**
1629
+ * Set the x-placement attribute before everything else because it could be used
1630
+ * to add margins to the popper margins needs to be calculated to get the
1631
+ * correct popper offsets.
1632
+ * @method
1633
+ * @memberof Popper.modifiers
1634
+ * @param {HTMLElement} reference - The reference element used to position the popper
1635
+ * @param {HTMLElement} popper - The HTML element used as popper.
1636
+ * @param {Object} options - Popper.js options
1637
+ */
1638
+ function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
1639
+ // compute reference element offsets
1640
+ var referenceOffsets = getReferenceOffsets(state, popper, reference);
1641
+
1642
+ // compute auto placement, store placement inside the data object,
1643
+ // modifiers will be able to edit `placement` if needed
1644
+ // and refer to originalPlacement to know the original value
1645
+ var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
1646
+
1647
+ popper.setAttribute('x-placement', placement);
1648
+
1649
+ // Apply `position` to popper before anything else because
1650
+ // without the position applied we can't guarantee correct computations
1651
+ setStyles(popper, { position: 'absolute' });
1652
+
1653
+ return options;
1654
+ }
1655
+
1656
+ /**
1657
+ * @function
1658
+ * @memberof Modifiers
1659
+ * @argument {Object} data - The data object generated by `update` method
1660
+ * @argument {Object} options - Modifiers configuration and options
1661
+ * @returns {Object} The data object, properly modified
1662
+ */
1663
+ function computeStyle(data, options) {
1664
+ var x = options.x,
1665
+ y = options.y;
1666
+ var popper = data.offsets.popper;
1667
+
1668
+ // Remove this legacy support in Popper.js v2
1669
+
1670
+ var legacyGpuAccelerationOption = find$1(data.instance.modifiers, function (modifier) {
1671
+ return modifier.name === 'applyStyle';
1672
+ }).gpuAcceleration;
1673
+ if (legacyGpuAccelerationOption !== undefined) {
1674
+ console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
1675
+ }
1676
+ var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
1677
+
1678
+ var offsetParent = getOffsetParent(data.instance.popper);
1679
+ var offsetParentRect = getBoundingClientRect(offsetParent);
1680
+
1681
+ // Styles
1682
+ var styles = {
1683
+ position: popper.position
1684
+ };
1685
+
1686
+ // floor sides to avoid blurry text
1687
+ var offsets = {
1688
+ left: Math.floor(popper.left),
1689
+ top: Math.floor(popper.top),
1690
+ bottom: Math.floor(popper.bottom),
1691
+ right: Math.floor(popper.right)
1692
+ };
1693
+
1694
+ var sideA = x === 'bottom' ? 'top' : 'bottom';
1695
+ var sideB = y === 'right' ? 'left' : 'right';
1696
+
1697
+ // if gpuAcceleration is set to `true` and transform is supported,
1698
+ // we use `translate3d` to apply the position to the popper we
1699
+ // automatically use the supported prefixed version if needed
1700
+ var prefixedProperty = getSupportedPropertyName('transform');
1701
+
1702
+ // now, let's make a step back and look at this code closely (wtf?)
1703
+ // If the content of the popper grows once it's been positioned, it
1704
+ // may happen that the popper gets misplaced because of the new content
1705
+ // overflowing its reference element
1706
+ // To avoid this problem, we provide two options (x and y), which allow
1707
+ // the consumer to define the offset origin.
1708
+ // If we position a popper on top of a reference element, we can set
1709
+ // `x` to `top` to make the popper grow towards its top instead of
1710
+ // its bottom.
1711
+ var left = void 0,
1712
+ top = void 0;
1713
+ if (sideA === 'bottom') {
1714
+ top = -offsetParentRect.height + offsets.bottom;
1715
+ } else {
1716
+ top = offsets.top;
1717
+ }
1718
+ if (sideB === 'right') {
1719
+ left = -offsetParentRect.width + offsets.right;
1720
+ } else {
1721
+ left = offsets.left;
1722
+ }
1723
+ if (gpuAcceleration && prefixedProperty) {
1724
+ styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
1725
+ styles[sideA] = 0;
1726
+ styles[sideB] = 0;
1727
+ styles.willChange = 'transform';
1728
+ } else {
1729
+ // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
1730
+ var invertTop = sideA === 'bottom' ? -1 : 1;
1731
+ var invertLeft = sideB === 'right' ? -1 : 1;
1732
+ styles[sideA] = top * invertTop;
1733
+ styles[sideB] = left * invertLeft;
1734
+ styles.willChange = sideA + ', ' + sideB;
1735
+ }
1736
+
1737
+ // Attributes
1738
+ var attributes = {
1739
+ 'x-placement': data.placement
1740
+ };
1741
+
1742
+ // Update attributes and styles of `data`
1743
+ data.attributes = _extends({}, attributes, data.attributes);
1744
+ data.styles = _extends({}, styles, data.styles);
1745
+
1746
+ return data;
1747
+ }
1748
+
1749
+ /**
1750
+ * Helper used to know if the given modifier depends from another one.<br />
1751
+ * It checks if the needed modifier is listed and enabled.
1752
+ * @method
1753
+ * @memberof Popper.Utils
1754
+ * @param {Array} modifiers - list of modifiers
1755
+ * @param {String} requestingName - name of requesting modifier
1756
+ * @param {String} requestedName - name of requested modifier
1757
+ * @returns {Boolean}
1758
+ */
1759
+ function isModifierRequired(modifiers, requestingName, requestedName) {
1760
+ var requesting = find$1(modifiers, function (_ref) {
1761
+ var name = _ref.name;
1762
+ return name === requestingName;
1763
+ });
1764
+
1765
+ var isRequired = !!requesting && modifiers.some(function (modifier) {
1766
+ return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
1767
+ });
1768
+
1769
+ if (!isRequired) {
1770
+ var _requesting = '`' + requestingName + '`';
1771
+ var requested = '`' + requestedName + '`';
1772
+ console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
1773
+ }
1774
+ return isRequired;
1775
+ }
1776
+
1777
+ /**
1778
+ * @function
1779
+ * @memberof Modifiers
1780
+ * @argument {Object} data - The data object generated by update method
1781
+ * @argument {Object} options - Modifiers configuration and options
1782
+ * @returns {Object} The data object, properly modified
1783
+ */
1784
+ function arrow(data, options) {
1785
+ // arrow depends on keepTogether in order to work
1786
+ if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
1787
+ return data;
1788
+ }
1789
+
1790
+ var arrowElement = options.element;
1791
+
1792
+ // if arrowElement is a string, suppose it's a CSS selector
1793
+ if (typeof arrowElement === 'string') {
1794
+ arrowElement = data.instance.popper.querySelector(arrowElement);
1795
+
1796
+ // if arrowElement is not found, don't run the modifier
1797
+ if (!arrowElement) {
1798
+ return data;
1799
+ }
1800
+ } else {
1801
+ // if the arrowElement isn't a query selector we must check that the
1802
+ // provided DOM node is child of its popper node
1803
+ if (!data.instance.popper.contains(arrowElement)) {
1804
+ console.warn('WARNING: `arrow.element` must be child of its popper element!');
1805
+ return data;
1806
+ }
1807
+ }
1808
+
1809
+ var placement = data.placement.split('-')[0];
1810
+ var _data$offsets = data.offsets,
1811
+ popper = _data$offsets.popper,
1812
+ reference = _data$offsets.reference;
1813
+
1814
+ var isVertical = ['left', 'right'].indexOf(placement) !== -1;
1815
+
1816
+ var len = isVertical ? 'height' : 'width';
1817
+ var side = isVertical ? 'top' : 'left';
1818
+ var altSide = isVertical ? 'left' : 'top';
1819
+ var opSide = isVertical ? 'bottom' : 'right';
1820
+ var arrowElementSize = getOuterSizes(arrowElement)[len];
1821
+
1822
+ //
1823
+ // extends keepTogether behavior making sure the popper and its reference have enough pixels in conjuction
1824
+ //
1825
+
1826
+ // top/left side
1827
+ if (reference[opSide] - arrowElementSize < popper[side]) {
1828
+ data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
1829
+ }
1830
+ // bottom/right side
1831
+ if (reference[side] + arrowElementSize > popper[opSide]) {
1832
+ data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
1833
+ }
1834
+
1835
+ // compute center of the popper
1836
+ var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
1837
+
1838
+ // Compute the sideValue using the updated popper offsets
1839
+ var sideValue = center - getClientRect(data.offsets.popper)[side];
1840
+
1841
+ // prevent arrowElement from being placed not contiguously to its popper
1842
+ sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
1843
+
1844
+ data.arrowElement = arrowElement;
1845
+ data.offsets.arrow = {};
1846
+ data.offsets.arrow[side] = Math.round(sideValue);
1847
+ data.offsets.arrow[altSide] = ''; // make sure to unset any eventual altSide value from the DOM node
1848
+
1849
+ return data;
1850
+ }
1851
+
1852
+ /**
1853
+ * Get the opposite placement variation of the given one
1854
+ * @method
1855
+ * @memberof Popper.Utils
1856
+ * @argument {String} placement variation
1857
+ * @returns {String} flipped placement variation
1858
+ */
1859
+ function getOppositeVariation(variation) {
1860
+ if (variation === 'end') {
1861
+ return 'start';
1862
+ } else if (variation === 'start') {
1863
+ return 'end';
1864
+ }
1865
+ return variation;
1866
+ }
1867
+
1868
+ /**
1869
+ * List of accepted placements to use as values of the `placement` option.<br />
1870
+ * Valid placements are:
1871
+ * - `auto`
1872
+ * - `top`
1873
+ * - `right`
1874
+ * - `bottom`
1875
+ * - `left`
1876
+ *
1877
+ * Each placement can have a variation from this list:
1878
+ * - `-start`
1879
+ * - `-end`
1880
+ *
1881
+ * Variations are interpreted easily if you think of them as the left to right
1882
+ * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
1883
+ * is right.<br />
1884
+ * Vertically (`left` and `right`), `start` is top and `end` is bottom.
1885
+ *
1886
+ * Some valid examples are:
1887
+ * - `top-end` (on top of reference, right aligned)
1888
+ * - `right-start` (on right of reference, top aligned)
1889
+ * - `bottom` (on bottom, centered)
1890
+ * - `auto-right` (on the side with more space available, alignment depends by placement)
1891
+ *
1892
+ * @static
1893
+ * @type {Array}
1894
+ * @enum {String}
1895
+ * @readonly
1896
+ * @method placements
1897
+ * @memberof Popper
1898
+ */
1899
+ 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'];
1900
+
1901
+ // Get rid of `auto` `auto-start` and `auto-end`
1902
+ var validPlacements = placements.slice(3);
1903
+
1904
+ /**
1905
+ * Given an initial placement, returns all the subsequent placements
1906
+ * clockwise (or counter-clockwise).
1907
+ *
1908
+ * @method
1909
+ * @memberof Popper.Utils
1910
+ * @argument {String} placement - A valid placement (it accepts variations)
1911
+ * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
1912
+ * @returns {Array} placements including their variations
1913
+ */
1914
+ function clockwise(placement) {
1915
+ var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1916
+
1917
+ var index = validPlacements.indexOf(placement);
1918
+ var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
1919
+ return counter ? arr.reverse() : arr;
1920
+ }
1921
+
1922
+ var BEHAVIORS = {
1923
+ FLIP: 'flip',
1924
+ CLOCKWISE: 'clockwise',
1925
+ COUNTERCLOCKWISE: 'counterclockwise'
1926
+ };
1927
+
1928
+ /**
1929
+ * @function
1930
+ * @memberof Modifiers
1931
+ * @argument {Object} data - The data object generated by update method
1932
+ * @argument {Object} options - Modifiers configuration and options
1933
+ * @returns {Object} The data object, properly modified
1934
+ */
1935
+ function flip(data, options) {
1936
+ // if `inner` modifier is enabled, we can't use the `flip` modifier
1937
+ if (isModifierEnabled(data.instance.modifiers, 'inner')) {
1938
+ return data;
1939
+ }
1940
+
1941
+ if (data.flipped && data.placement === data.originalPlacement) {
1942
+ // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
1943
+ return data;
1944
+ }
1945
+
1946
+ var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement);
1947
+
1948
+ var placement = data.placement.split('-')[0];
1949
+ var placementOpposite = getOppositePlacement(placement);
1950
+ var variation = data.placement.split('-')[1] || '';
1951
+
1952
+ var flipOrder = [];
1953
+
1954
+ switch (options.behavior) {
1955
+ case BEHAVIORS.FLIP:
1956
+ flipOrder = [placement, placementOpposite];
1957
+ break;
1958
+ case BEHAVIORS.CLOCKWISE:
1959
+ flipOrder = clockwise(placement);
1960
+ break;
1961
+ case BEHAVIORS.COUNTERCLOCKWISE:
1962
+ flipOrder = clockwise(placement, true);
1963
+ break;
1964
+ default:
1965
+ flipOrder = options.behavior;
1966
+ }
1967
+
1968
+ flipOrder.forEach(function (step, index) {
1969
+ if (placement !== step || flipOrder.length === index + 1) {
1970
+ return data;
1971
+ }
1972
+
1973
+ placement = data.placement.split('-')[0];
1974
+ placementOpposite = getOppositePlacement(placement);
1975
+
1976
+ var popperOffsets = data.offsets.popper;
1977
+ var refOffsets = data.offsets.reference;
1978
+
1979
+ // using floor because the reference offsets may contain decimals we are not going to consider here
1980
+ var floor = Math.floor;
1981
+ 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);
1982
+
1983
+ var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
1984
+ var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
1985
+ var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
1986
+ var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
1987
+
1988
+ var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
1989
+
1990
+ // flip the variation if required
1991
+ var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
1992
+ var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
1993
+
1994
+ if (overlapsRef || overflowsBoundaries || flippedVariation) {
1995
+ // this boolean to detect any flip loop
1996
+ data.flipped = true;
1997
+
1998
+ if (overlapsRef || overflowsBoundaries) {
1999
+ placement = flipOrder[index + 1];
2000
+ }
2001
+
2002
+ if (flippedVariation) {
2003
+ variation = getOppositeVariation(variation);
2004
+ }
2005
+
2006
+ data.placement = placement + (variation ? '-' + variation : '');
2007
+
2008
+ // this object contains `position`, we want to preserve it along with
2009
+ // any additional property we may add in the future
2010
+ data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
2011
+
2012
+ data = runModifiers(data.instance.modifiers, data, 'flip');
2013
+ }
2014
+ });
2015
+ return data;
2016
+ }
2017
+
2018
+ /**
2019
+ * @function
2020
+ * @memberof Modifiers
2021
+ * @argument {Object} data - The data object generated by update method
2022
+ * @argument {Object} options - Modifiers configuration and options
2023
+ * @returns {Object} The data object, properly modified
2024
+ */
2025
+ function keepTogether(data) {
2026
+ var _data$offsets = data.offsets,
2027
+ popper = _data$offsets.popper,
2028
+ reference = _data$offsets.reference;
2029
+
2030
+ var placement = data.placement.split('-')[0];
2031
+ var floor = Math.floor;
2032
+ var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
2033
+ var side = isVertical ? 'right' : 'bottom';
2034
+ var opSide = isVertical ? 'left' : 'top';
2035
+ var measurement = isVertical ? 'width' : 'height';
2036
+
2037
+ if (popper[side] < floor(reference[opSide])) {
2038
+ data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
2039
+ }
2040
+ if (popper[opSide] > floor(reference[side])) {
2041
+ data.offsets.popper[opSide] = floor(reference[side]);
2042
+ }
2043
+
2044
+ return data;
2045
+ }
2046
+
2047
+ /**
2048
+ * Converts a string containing value + unit into a px value number
2049
+ * @function
2050
+ * @memberof {modifiers~offset}
2051
+ * @private
2052
+ * @argument {String} str - Value + unit string
2053
+ * @argument {String} measurement - `height` or `width`
2054
+ * @argument {Object} popperOffsets
2055
+ * @argument {Object} referenceOffsets
2056
+ * @returns {Number|String}
2057
+ * Value in pixels, or original string if no values were extracted
2058
+ */
2059
+ function toValue(str, measurement, popperOffsets, referenceOffsets) {
2060
+ // separate value from unit
2061
+ var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
2062
+ var value = +split[1];
2063
+ var unit = split[2];
2064
+
2065
+ // If it's not a number it's an operator, I guess
2066
+ if (!value) {
2067
+ return str;
2068
+ }
2069
+
2070
+ if (unit.indexOf('%') === 0) {
2071
+ var element = void 0;
2072
+ switch (unit) {
2073
+ case '%p':
2074
+ element = popperOffsets;
2075
+ break;
2076
+ case '%':
2077
+ case '%r':
2078
+ default:
2079
+ element = referenceOffsets;
2080
+ }
2081
+
2082
+ var rect = getClientRect(element);
2083
+ return rect[measurement] / 100 * value;
2084
+ } else if (unit === 'vh' || unit === 'vw') {
2085
+ // if is a vh or vw, we calculate the size based on the viewport
2086
+ var size = void 0;
2087
+ if (unit === 'vh') {
2088
+ size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
2089
+ } else {
2090
+ size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
2091
+ }
2092
+ return size / 100 * value;
2093
+ } else {
2094
+ // if is an explicit pixel unit, we get rid of the unit and keep the value
2095
+ // if is an implicit unit, it's px, and we return just the value
2096
+ return value;
2097
+ }
2098
+ }
2099
+
2100
+ /**
2101
+ * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
2102
+ * @function
2103
+ * @memberof {modifiers~offset}
2104
+ * @private
2105
+ * @argument {String} offset
2106
+ * @argument {Object} popperOffsets
2107
+ * @argument {Object} referenceOffsets
2108
+ * @argument {String} basePlacement
2109
+ * @returns {Array} a two cells array with x and y offsets in numbers
2110
+ */
2111
+ function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
2112
+ var offsets = [0, 0];
2113
+
2114
+ // Use height if placement is left or right and index is 0 otherwise use width
2115
+ // in this way the first offset will use an axis and the second one
2116
+ // will use the other one
2117
+ var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
2118
+
2119
+ // Split the offset string to obtain a list of values and operands
2120
+ // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
2121
+ var fragments = offset.split(/(\+|\-)/).map(function (frag) {
2122
+ return frag.trim();
2123
+ });
2124
+
2125
+ // Detect if the offset string contains a pair of values or a single one
2126
+ // they could be separated by comma or space
2127
+ var divider = fragments.indexOf(find$1(fragments, function (frag) {
2128
+ return frag.search(/,|\s/) !== -1;
2129
+ }));
2130
+
2131
+ if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
2132
+ console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
2133
+ }
2134
+
2135
+ // If divider is found, we divide the list of values and operands to divide
2136
+ // them by ofset X and Y.
2137
+ var splitRegex = /\s*,\s*|\s+/;
2138
+ 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];
2139
+
2140
+ // Convert the values with units to absolute pixels to allow our computations
2141
+ ops = ops.map(function (op, index) {
2142
+ // Most of the units rely on the orientation of the popper
2143
+ var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
2144
+ var mergeWithPrevious = false;
2145
+ return op
2146
+ // This aggregates any `+` or `-` sign that aren't considered operators
2147
+ // e.g.: 10 + +5 => [10, +, +5]
2148
+ .reduce(function (a, b) {
2149
+ if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
2150
+ a[a.length - 1] = b;
2151
+ mergeWithPrevious = true;
2152
+ return a;
2153
+ } else if (mergeWithPrevious) {
2154
+ a[a.length - 1] += b;
2155
+ mergeWithPrevious = false;
2156
+ return a;
2157
+ } else {
2158
+ return a.concat(b);
2159
+ }
2160
+ }, [])
2161
+ // Here we convert the string values into number values (in px)
2162
+ .map(function (str) {
2163
+ return toValue(str, measurement, popperOffsets, referenceOffsets);
2164
+ });
2165
+ });
2166
+
2167
+ // Loop trough the offsets arrays and execute the operations
2168
+ ops.forEach(function (op, index) {
2169
+ op.forEach(function (frag, index2) {
2170
+ if (isNumeric(frag)) {
2171
+ offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
2172
+ }
2173
+ });
2174
+ });
2175
+ return offsets;
2176
+ }
2177
+
2178
+ /**
2179
+ * @function
2180
+ * @memberof Modifiers
2181
+ * @argument {Object} data - The data object generated by update method
2182
+ * @argument {Object} options - Modifiers configuration and options
2183
+ * @argument {Number|String} options.offset=0
2184
+ * The offset value as described in the modifier description
2185
+ * @returns {Object} The data object, properly modified
2186
+ */
2187
+ function offset(data, _ref) {
2188
+ var offset = _ref.offset;
2189
+ var placement = data.placement,
2190
+ _data$offsets = data.offsets,
2191
+ popper = _data$offsets.popper,
2192
+ reference = _data$offsets.reference;
2193
+
2194
+ var basePlacement = placement.split('-')[0];
2195
+
2196
+ var offsets = void 0;
2197
+ if (isNumeric(+offset)) {
2198
+ offsets = [+offset, 0];
2199
+ } else {
2200
+ offsets = parseOffset(offset, popper, reference, basePlacement);
2201
+ }
2202
+
2203
+ if (basePlacement === 'left') {
2204
+ popper.top += offsets[0];
2205
+ popper.left -= offsets[1];
2206
+ } else if (basePlacement === 'right') {
2207
+ popper.top += offsets[0];
2208
+ popper.left += offsets[1];
2209
+ } else if (basePlacement === 'top') {
2210
+ popper.left += offsets[0];
2211
+ popper.top -= offsets[1];
2212
+ } else if (basePlacement === 'bottom') {
2213
+ popper.left += offsets[0];
2214
+ popper.top += offsets[1];
2215
+ }
2216
+
2217
+ data.popper = popper;
2218
+ return data;
2219
+ }
2220
+
2221
+ /**
2222
+ * @function
2223
+ * @memberof Modifiers
2224
+ * @argument {Object} data - The data object generated by `update` method
2225
+ * @argument {Object} options - Modifiers configuration and options
2226
+ * @returns {Object} The data object, properly modified
2227
+ */
2228
+ function preventOverflow(data, options) {
2229
+ var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
2230
+
2231
+ // If offsetParent is the reference element, we really want to
2232
+ // go one step up and use the next offsetParent as reference to
2233
+ // avoid to make this modifier completely useless and look like broken
2234
+ if (data.instance.reference === boundariesElement) {
2235
+ boundariesElement = getOffsetParent(boundariesElement);
2236
+ }
2237
+
2238
+ var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement);
2239
+ options.boundaries = boundaries;
2240
+
2241
+ var order = options.priority;
2242
+ var popper = data.offsets.popper;
2243
+
2244
+ var check = {
2245
+ primary: function primary(placement) {
2246
+ var value = popper[placement];
2247
+ if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
2248
+ value = Math.max(popper[placement], boundaries[placement]);
2249
+ }
2250
+ return defineProperty({}, placement, value);
2251
+ },
2252
+ secondary: function secondary(placement) {
2253
+ var mainSide = placement === 'right' ? 'left' : 'top';
2254
+ var value = popper[mainSide];
2255
+ if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
2256
+ value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
2257
+ }
2258
+ return defineProperty({}, mainSide, value);
2259
+ }
2260
+ };
2261
+
2262
+ order.forEach(function (placement) {
2263
+ var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
2264
+ popper = _extends({}, popper, check[side](placement));
2265
+ });
2266
+
2267
+ data.offsets.popper = popper;
2268
+
2269
+ return data;
2270
+ }
2271
+
2272
+ /**
2273
+ * @function
2274
+ * @memberof Modifiers
2275
+ * @argument {Object} data - The data object generated by `update` method
2276
+ * @argument {Object} options - Modifiers configuration and options
2277
+ * @returns {Object} The data object, properly modified
2278
+ */
2279
+ function shift(data) {
2280
+ var placement = data.placement;
2281
+ var basePlacement = placement.split('-')[0];
2282
+ var shiftvariation = placement.split('-')[1];
2283
+
2284
+ // if shift shiftvariation is specified, run the modifier
2285
+ if (shiftvariation) {
2286
+ var _data$offsets = data.offsets,
2287
+ reference = _data$offsets.reference,
2288
+ popper = _data$offsets.popper;
2289
+
2290
+ var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
2291
+ var side = isVertical ? 'left' : 'top';
2292
+ var measurement = isVertical ? 'width' : 'height';
2293
+
2294
+ var shiftOffsets = {
2295
+ start: defineProperty({}, side, reference[side]),
2296
+ end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
2297
+ };
2298
+
2299
+ data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
2300
+ }
2301
+
2302
+ return data;
2303
+ }
2304
+
2305
+ /**
2306
+ * @function
2307
+ * @memberof Modifiers
2308
+ * @argument {Object} data - The data object generated by update method
2309
+ * @argument {Object} options - Modifiers configuration and options
2310
+ * @returns {Object} The data object, properly modified
2311
+ */
2312
+ function hide(data) {
2313
+ if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
2314
+ return data;
2315
+ }
2316
+
2317
+ var refRect = data.offsets.reference;
2318
+ var bound = find$1(data.instance.modifiers, function (modifier) {
2319
+ return modifier.name === 'preventOverflow';
2320
+ }).boundaries;
2321
+
2322
+ if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
2323
+ // Avoid unnecessary DOM access if visibility hasn't changed
2324
+ if (data.hide === true) {
2325
+ return data;
2326
+ }
2327
+
2328
+ data.hide = true;
2329
+ data.attributes['x-out-of-boundaries'] = '';
2330
+ } else {
2331
+ // Avoid unnecessary DOM access if visibility hasn't changed
2332
+ if (data.hide === false) {
2333
+ return data;
2334
+ }
2335
+
2336
+ data.hide = false;
2337
+ data.attributes['x-out-of-boundaries'] = false;
2338
+ }
2339
+
2340
+ return data;
2341
+ }
2342
+
2343
+ /**
2344
+ * @function
2345
+ * @memberof Modifiers
2346
+ * @argument {Object} data - The data object generated by `update` method
2347
+ * @argument {Object} options - Modifiers configuration and options
2348
+ * @returns {Object} The data object, properly modified
2349
+ */
2350
+ function inner(data) {
2351
+ var placement = data.placement;
2352
+ var basePlacement = placement.split('-')[0];
2353
+ var _data$offsets = data.offsets,
2354
+ popper = _data$offsets.popper,
2355
+ reference = _data$offsets.reference;
2356
+
2357
+ var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
2358
+
2359
+ var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
2360
+
2361
+ popper[isHoriz ? 'left' : 'top'] = reference[placement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
2362
+
2363
+ data.placement = getOppositePlacement(placement);
2364
+ data.offsets.popper = getClientRect(popper);
2365
+
2366
+ return data;
2367
+ }
2368
+
2369
+ /**
2370
+ * Modifier function, each modifier can have a function of this type assigned
2371
+ * to its `fn` property.<br />
2372
+ * These functions will be called on each update, this means that you must
2373
+ * make sure they are performant enough to avoid performance bottlenecks.
2374
+ *
2375
+ * @function ModifierFn
2376
+ * @argument {dataObject} data - The data object generated by `update` method
2377
+ * @argument {Object} options - Modifiers configuration and options
2378
+ * @returns {dataObject} The data object, properly modified
2379
+ */
2380
+
2381
+ /**
2382
+ * Modifiers are plugins used to alter the behavior of your poppers.<br />
2383
+ * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
2384
+ * needed by the library.
2385
+ *
2386
+ * Usually you don't want to override the `order`, `fn` and `onLoad` props.
2387
+ * All the other properties are configurations that could be tweaked.
2388
+ * @namespace modifiers
2389
+ */
2390
+ var modifiers = {
2391
+ /**
2392
+ * Modifier used to shift the popper on the start or end of its reference
2393
+ * element.<br />
2394
+ * It will read the variation of the `placement` property.<br />
2395
+ * It can be one either `-end` or `-start`.
2396
+ * @memberof modifiers
2397
+ * @inner
2398
+ */
2399
+ shift: {
2400
+ /** @prop {number} order=100 - Index used to define the order of execution */
2401
+ order: 100,
2402
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2403
+ enabled: true,
2404
+ /** @prop {ModifierFn} */
2405
+ fn: shift
2406
+ },
2407
+
2408
+ /**
2409
+ * The `offset` modifier can shift your popper on both its axis.
2410
+ *
2411
+ * It accepts the following units:
2412
+ * - `px` or unitless, interpreted as pixels
2413
+ * - `%` or `%r`, percentage relative to the length of the reference element
2414
+ * - `%p`, percentage relative to the length of the popper element
2415
+ * - `vw`, CSS viewport width unit
2416
+ * - `vh`, CSS viewport height unit
2417
+ *
2418
+ * For length is intended the main axis relative to the placement of the popper.<br />
2419
+ * This means that if the placement is `top` or `bottom`, the length will be the
2420
+ * `width`. In case of `left` or `right`, it will be the height.
2421
+ *
2422
+ * You can provide a single value (as `Number` or `String`), or a pair of values
2423
+ * as `String` divided by a comma or one (or more) white spaces.<br />
2424
+ * The latter is a deprecated method because it leads to confusion and will be
2425
+ * removed in v2.<br />
2426
+ * Additionally, it accepts additions and subtractions between different units.
2427
+ * Note that multiplications and divisions aren't supported.
2428
+ *
2429
+ * Valid examples are:
2430
+ * ```
2431
+ * 10
2432
+ * '10%'
2433
+ * '10, 10'
2434
+ * '10%, 10'
2435
+ * '10 + 10%'
2436
+ * '10 - 5vh + 3%'
2437
+ * '-10px + 5vh, 5px - 6%'
2438
+ * ```
2439
+ *
2440
+ * @memberof modifiers
2441
+ * @inner
2442
+ */
2443
+ offset: {
2444
+ /** @prop {number} order=200 - Index used to define the order of execution */
2445
+ order: 200,
2446
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2447
+ enabled: true,
2448
+ /** @prop {ModifierFn} */
2449
+ fn: offset,
2450
+ /** @prop {Number|String} offset=0
2451
+ * The offset value as described in the modifier description
2452
+ */
2453
+ offset: 0
2454
+ },
2455
+
2456
+ /**
2457
+ * Modifier used to prevent the popper from being positioned outside the boundary.
2458
+ *
2459
+ * An scenario exists where the reference itself is not within the boundaries.<br />
2460
+ * We can say it has "escaped the boundaries" — or just "escaped".<br />
2461
+ * In this case we need to decide whether the popper should either:
2462
+ *
2463
+ * - detach from the reference and remain "trapped" in the boundaries, or
2464
+ * - if it should ignore the boundary and "escape with its reference"
2465
+ *
2466
+ * When `escapeWithReference` is set to`true` and reference is completely
2467
+ * outside its boundaries, the popper will overflow (or completely leave)
2468
+ * the boundaries in order to remain attached to the edge of the reference.
2469
+ *
2470
+ * @memberof modifiers
2471
+ * @inner
2472
+ */
2473
+ preventOverflow: {
2474
+ /** @prop {number} order=300 - Index used to define the order of execution */
2475
+ order: 300,
2476
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2477
+ enabled: true,
2478
+ /** @prop {ModifierFn} */
2479
+ fn: preventOverflow,
2480
+ /**
2481
+ * @prop {Array} [priority=['left','right','top','bottom']]
2482
+ * Popper will try to prevent overflow following these priorities by default,
2483
+ * then, it could overflow on the left and on top of the `boundariesElement`
2484
+ */
2485
+ priority: ['left', 'right', 'top', 'bottom'],
2486
+ /**
2487
+ * @prop {number} padding=5
2488
+ * Amount of pixel used to define a minimum distance between the boundaries
2489
+ * and the popper this makes sure the popper has always a little padding
2490
+ * between the edges of its container
2491
+ */
2492
+ padding: 5,
2493
+ /**
2494
+ * @prop {String|HTMLElement} boundariesElement='scrollParent'
2495
+ * Boundaries used by the modifier, can be `scrollParent`, `window`,
2496
+ * `viewport` or any DOM element.
2497
+ */
2498
+ boundariesElement: 'scrollParent'
2499
+ },
2500
+
2501
+ /**
2502
+ * Modifier used to make sure the reference and its popper stay near eachothers
2503
+ * without leaving any gap between the two. Expecially useful when the arrow is
2504
+ * enabled and you want to assure it to point to its reference element.
2505
+ * It cares only about the first axis, you can still have poppers with margin
2506
+ * between the popper and its reference element.
2507
+ * @memberof modifiers
2508
+ * @inner
2509
+ */
2510
+ keepTogether: {
2511
+ /** @prop {number} order=400 - Index used to define the order of execution */
2512
+ order: 400,
2513
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2514
+ enabled: true,
2515
+ /** @prop {ModifierFn} */
2516
+ fn: keepTogether
2517
+ },
2518
+
2519
+ /**
2520
+ * This modifier is used to move the `arrowElement` of the popper to make
2521
+ * sure it is positioned between the reference element and its popper element.
2522
+ * It will read the outer size of the `arrowElement` node to detect how many
2523
+ * pixels of conjuction are needed.
2524
+ *
2525
+ * It has no effect if no `arrowElement` is provided.
2526
+ * @memberof modifiers
2527
+ * @inner
2528
+ */
2529
+ arrow: {
2530
+ /** @prop {number} order=500 - Index used to define the order of execution */
2531
+ order: 500,
2532
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2533
+ enabled: true,
2534
+ /** @prop {ModifierFn} */
2535
+ fn: arrow,
2536
+ /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
2537
+ element: '[x-arrow]'
2538
+ },
2539
+
2540
+ /**
2541
+ * Modifier used to flip the popper's placement when it starts to overlap its
2542
+ * reference element.
2543
+ *
2544
+ * Requires the `preventOverflow` modifier before it in order to work.
2545
+ *
2546
+ * **NOTE:** this modifier will interrupt the current update cycle and will
2547
+ * restart it if it detects the need to flip the placement.
2548
+ * @memberof modifiers
2549
+ * @inner
2550
+ */
2551
+ flip: {
2552
+ /** @prop {number} order=600 - Index used to define the order of execution */
2553
+ order: 600,
2554
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2555
+ enabled: true,
2556
+ /** @prop {ModifierFn} */
2557
+ fn: flip,
2558
+ /**
2559
+ * @prop {String|Array} behavior='flip'
2560
+ * The behavior used to change the popper's placement. It can be one of
2561
+ * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
2562
+ * placements (with optional variations).
2563
+ */
2564
+ behavior: 'flip',
2565
+ /**
2566
+ * @prop {number} padding=5
2567
+ * The popper will flip if it hits the edges of the `boundariesElement`
2568
+ */
2569
+ padding: 5,
2570
+ /**
2571
+ * @prop {String|HTMLElement} boundariesElement='viewport'
2572
+ * The element which will define the boundaries of the popper position,
2573
+ * the popper will never be placed outside of the defined boundaries
2574
+ * (except if keepTogether is enabled)
2575
+ */
2576
+ boundariesElement: 'viewport'
2577
+ },
2578
+
2579
+ /**
2580
+ * Modifier used to make the popper flow toward the inner of the reference element.
2581
+ * By default, when this modifier is disabled, the popper will be placed outside
2582
+ * the reference element.
2583
+ * @memberof modifiers
2584
+ * @inner
2585
+ */
2586
+ inner: {
2587
+ /** @prop {number} order=700 - Index used to define the order of execution */
2588
+ order: 700,
2589
+ /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
2590
+ enabled: false,
2591
+ /** @prop {ModifierFn} */
2592
+ fn: inner
2593
+ },
2594
+
2595
+ /**
2596
+ * Modifier used to hide the popper when its reference element is outside of the
2597
+ * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
2598
+ * be used to hide with a CSS selector the popper when its reference is
2599
+ * out of boundaries.
2600
+ *
2601
+ * Requires the `preventOverflow` modifier before it in order to work.
2602
+ * @memberof modifiers
2603
+ * @inner
2604
+ */
2605
+ hide: {
2606
+ /** @prop {number} order=800 - Index used to define the order of execution */
2607
+ order: 800,
2608
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2609
+ enabled: true,
2610
+ /** @prop {ModifierFn} */
2611
+ fn: hide
2612
+ },
2613
+
2614
+ /**
2615
+ * Computes the style that will be applied to the popper element to gets
2616
+ * properly positioned.
2617
+ *
2618
+ * Note that this modifier will not touch the DOM, it just prepares the styles
2619
+ * so that `applyStyle` modifier can apply it. This separation is useful
2620
+ * in case you need to replace `applyStyle` with a custom implementation.
2621
+ *
2622
+ * This modifier has `850` as `order` value to maintain backward compatibility
2623
+ * with previous versions of Popper.js. Expect the modifiers ordering method
2624
+ * to change in future major versions of the library.
2625
+ *
2626
+ * @memberof modifiers
2627
+ * @inner
2628
+ */
2629
+ computeStyle: {
2630
+ /** @prop {number} order=850 - Index used to define the order of execution */
2631
+ order: 850,
2632
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2633
+ enabled: true,
2634
+ /** @prop {ModifierFn} */
2635
+ fn: computeStyle,
2636
+ /**
2637
+ * @prop {Boolean} gpuAcceleration=true
2638
+ * If true, it uses the CSS 3d transformation to position the popper.
2639
+ * Otherwise, it will use the `top` and `left` properties.
2640
+ */
2641
+ gpuAcceleration: true,
2642
+ /**
2643
+ * @prop {string} [x='bottom']
2644
+ * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
2645
+ * Change this if your popper should grow in a direction different from `bottom`
2646
+ */
2647
+ x: 'bottom',
2648
+ /**
2649
+ * @prop {string} [x='left']
2650
+ * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
2651
+ * Change this if your popper should grow in a direction different from `right`
2652
+ */
2653
+ y: 'right'
2654
+ },
2655
+
2656
+ /**
2657
+ * Applies the computed styles to the popper element.
2658
+ *
2659
+ * All the DOM manipulations are limited to this modifier. This is useful in case
2660
+ * you want to integrate Popper.js inside a framework or view library and you
2661
+ * want to delegate all the DOM manipulations to it.
2662
+ *
2663
+ * Note that if you disable this modifier, you must make sure the popper element
2664
+ * has its position set to `absolute` before Popper.js can do its work!
2665
+ *
2666
+ * Just disable this modifier and define you own to achieve the desired effect.
2667
+ *
2668
+ * @memberof modifiers
2669
+ * @inner
2670
+ */
2671
+ applyStyle: {
2672
+ /** @prop {number} order=900 - Index used to define the order of execution */
2673
+ order: 900,
2674
+ /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
2675
+ enabled: true,
2676
+ /** @prop {ModifierFn} */
2677
+ fn: applyStyle,
2678
+ /** @prop {Function} */
2679
+ onLoad: applyStyleOnLoad,
2680
+ /**
2681
+ * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
2682
+ * @prop {Boolean} gpuAcceleration=true
2683
+ * If true, it uses the CSS 3d transformation to position the popper.
2684
+ * Otherwise, it will use the `top` and `left` properties.
2685
+ */
2686
+ gpuAcceleration: undefined
2687
+ }
2688
+ };
2689
+
2690
+ /**
2691
+ * The `dataObject` is an object containing all the informations used by Popper.js
2692
+ * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
2693
+ * @name dataObject
2694
+ * @property {Object} data.instance The Popper.js instance
2695
+ * @property {String} data.placement Placement applied to popper
2696
+ * @property {String} data.originalPlacement Placement originally defined on init
2697
+ * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
2698
+ * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.
2699
+ * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
2700
+ * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)
2701
+ * @property {Object} data.boundaries Offsets of the popper boundaries
2702
+ * @property {Object} data.offsets The measurements of popper, reference and arrow elements.
2703
+ * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
2704
+ * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
2705
+ * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
2706
+ */
2707
+
2708
+ /**
2709
+ * Default options provided to Popper.js constructor.<br />
2710
+ * These can be overriden using the `options` argument of Popper.js.<br />
2711
+ * To override an option, simply pass as 3rd argument an object with the same
2712
+ * structure of this object, example:
2713
+ * ```
2714
+ * new Popper(ref, pop, {
2715
+ * modifiers: {
2716
+ * preventOverflow: { enabled: false }
2717
+ * }
2718
+ * })
2719
+ * ```
2720
+ * @type {Object}
2721
+ * @static
2722
+ * @memberof Popper
2723
+ */
2724
+ var Defaults$1 = {
2725
+ /**
2726
+ * Popper's placement
2727
+ * @prop {Popper.placements} placement='bottom'
2728
+ */
2729
+ placement: 'bottom',
2730
+
2731
+ /**
2732
+ * Whether events (resize, scroll) are initially enabled
2733
+ * @prop {Boolean} eventsEnabled=true
2734
+ */
2735
+ eventsEnabled: true,
2736
+
2737
+ /**
2738
+ * Set to true if you want to automatically remove the popper when
2739
+ * you call the `destroy` method.
2740
+ * @prop {Boolean} removeOnDestroy=false
2741
+ */
2742
+ removeOnDestroy: false,
2743
+
2744
+ /**
2745
+ * Callback called when the popper is created.<br />
2746
+ * By default, is set to no-op.<br />
2747
+ * Access Popper.js instance with `data.instance`.
2748
+ * @prop {onCreate}
2749
+ */
2750
+ onCreate: function onCreate() {},
2751
+
2752
+ /**
2753
+ * Callback called when the popper is updated, this callback is not called
2754
+ * on the initialization/creation of the popper, but only on subsequent
2755
+ * updates.<br />
2756
+ * By default, is set to no-op.<br />
2757
+ * Access Popper.js instance with `data.instance`.
2758
+ * @prop {onUpdate}
2759
+ */
2760
+ onUpdate: function onUpdate() {},
2761
+
2762
+ /**
2763
+ * List of modifiers used to modify the offsets before they are applied to the popper.
2764
+ * They provide most of the functionalities of Popper.js
2765
+ * @prop {modifiers}
2766
+ */
2767
+ modifiers: modifiers
2768
+ };
2769
+
2770
+ /**
2771
+ * @callback onCreate
2772
+ * @param {dataObject} data
2773
+ */
2774
+
2775
+ /**
2776
+ * @callback onUpdate
2777
+ * @param {dataObject} data
2778
+ */
2779
+
2780
+ // Utils
2781
+ // Methods
2782
+ var Popper = function () {
2783
+ /**
2784
+ * Create a new Popper.js instance
2785
+ * @class Popper
2786
+ * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper
2787
+ * @param {HTMLElement} popper - The HTML element used as popper.
2788
+ * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
2789
+ * @return {Object} instance - The generated Popper.js instance
2790
+ */
2791
+ function Popper(reference, popper) {
2792
+ var _this = this;
2793
+
2794
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2795
+ classCallCheck(this, Popper);
2796
+
2797
+ this.scheduleUpdate = function () {
2798
+ return requestAnimationFrame(_this.update);
2799
+ };
2800
+
2801
+ // make update() debounced, so that it only runs at most once-per-tick
2802
+ this.update = debounce(this.update.bind(this));
2803
+
2804
+ // with {} we create a new object with the options inside it
2805
+ this.options = _extends({}, Popper.Defaults, options);
2806
+
2807
+ // init state
2808
+ this.state = {
2809
+ isDestroyed: false,
2810
+ isCreated: false,
2811
+ scrollParents: []
2812
+ };
2813
+
2814
+ // get reference and popper elements (allow jQuery wrappers)
2815
+ this.reference = reference.jquery ? reference[0] : reference;
2816
+ this.popper = popper.jquery ? popper[0] : popper;
2817
+
2818
+ // Deep merge modifiers options
2819
+ this.options.modifiers = {};
2820
+ Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
2821
+ _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
2822
+ });
2823
+
2824
+ // Refactoring modifiers' list (Object => Array)
2825
+ this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
2826
+ return _extends({
2827
+ name: name
2828
+ }, _this.options.modifiers[name]);
2829
+ })
2830
+ // sort the modifiers by order
2831
+ .sort(function (a, b) {
2832
+ return a.order - b.order;
2833
+ });
2834
+
2835
+ // modifiers have the ability to execute arbitrary code when Popper.js get inited
2836
+ // such code is executed in the same order of its modifier
2837
+ // they could add new properties to their options configuration
2838
+ // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
2839
+ this.modifiers.forEach(function (modifierOptions) {
2840
+ if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
2841
+ modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
2842
+ }
2843
+ });
2844
+
2845
+ // fire the first update to position the popper in the right place
2846
+ this.update();
2847
+
2848
+ var eventsEnabled = this.options.eventsEnabled;
2849
+ if (eventsEnabled) {
2850
+ // setup event listeners, they will take care of update the position in specific situations
2851
+ this.enableEventListeners();
2852
+ }
2853
+
2854
+ this.state.eventsEnabled = eventsEnabled;
2855
+ }
2856
+
2857
+ // We can't use class properties because they don't get listed in the
2858
+ // class prototype and break stuff like Sinon stubs
2859
+
2860
+
2861
+ createClass(Popper, [{
2862
+ key: 'update',
2863
+ value: function update$$1() {
2864
+ return update.call(this);
2865
+ }
2866
+ }, {
2867
+ key: 'destroy',
2868
+ value: function destroy$$1() {
2869
+ return destroy.call(this);
2870
+ }
2871
+ }, {
2872
+ key: 'enableEventListeners',
2873
+ value: function enableEventListeners$$1() {
2874
+ return enableEventListeners.call(this);
2875
+ }
2876
+ }, {
2877
+ key: 'disableEventListeners',
2878
+ value: function disableEventListeners$$1() {
2879
+ return disableEventListeners.call(this);
2880
+ }
2881
+
2882
+ /**
2883
+ * Schedule an update, it will run on the next UI update available
2884
+ * @method scheduleUpdate
2885
+ * @memberof Popper
2886
+ */
2887
+
2888
+ /**
2889
+ * Collection of utilities useful when writing custom modifiers.
2890
+ * Starting from version 1.7, this method is available only if you
2891
+ * include `popper-utils.js` before `popper.js`.
2892
+ *
2893
+ * **DEPRECATION**: This way to access PopperUtils is deprecated
2894
+ * and will be removed in v2! Use the PopperUtils module directly instead.
2895
+ * Due to the high instability of the methods contained in Utils, we can't
2896
+ * guarantee them to follow semver. Use them at your own risk!
2897
+ * @static
2898
+ * @private
2899
+ * @type {Object}
2900
+ * @deprecated since version 1.8
2901
+ * @member Utils
2902
+ * @memberof Popper
2903
+ */
2904
+
2905
+ }]);
2906
+ return Popper;
2907
+ }();
2908
+
2909
+ /**
2910
+ * The `referenceObject` is an object that provides an interface compatible with Popper.js
2911
+ * and lets you use it as replacement of a real DOM node.<br />
2912
+ * You can use this method to position a popper relatively to a set of coordinates
2913
+ * in case you don't have a DOM node to use as reference.
2914
+ *
2915
+ * ```
2916
+ * new Popper(referenceObject, popperNode);
2917
+ * ```
2918
+ *
2919
+ * NB: This feature isn't supported in Internet Explorer 10
2920
+ * @name referenceObject
2921
+ * @property {Function} data.getBoundingClientRect
2922
+ * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
2923
+ * @property {number} data.clientWidth
2924
+ * An ES6 getter that will return the width of the virtual reference element.
2925
+ * @property {number} data.clientHeight
2926
+ * An ES6 getter that will return the height of the virtual reference element.
2927
+ */
2928
+
2929
+ Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
2930
+ Popper.placements = placements;
2931
+ Popper.Defaults = Defaults$1;
2932
+
2933
+ /**
2934
+ * Returns the distance taking into account the default distance due to
2935
+ * the transform: translate setting in CSS
2936
+ * @param {Number} distance
2937
+ * @return {String}
2938
+ */
2939
+ function getOffsetDistanceInPx(distance) {
2940
+ return -(distance - Defaults.distance) + 'px';
2941
+ }
2942
+
2943
+ var classCallCheck$1 = function (instance, Constructor) {
2944
+ if (!(instance instanceof Constructor)) {
2945
+ throw new TypeError("Cannot call a class as a function");
2946
+ }
2947
+ };
2948
+
2949
+ var createClass$1 = function () {
2950
+ function defineProperties(target, props) {
2951
+ for (var i = 0; i < props.length; i++) {
2952
+ var descriptor = props[i];
2953
+ descriptor.enumerable = descriptor.enumerable || false;
2954
+ descriptor.configurable = true;
2955
+ if ("value" in descriptor) descriptor.writable = true;
2956
+ Object.defineProperty(target, descriptor.key, descriptor);
2957
+ }
2958
+ }
2959
+
2960
+ return function (Constructor, protoProps, staticProps) {
2961
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
2962
+ if (staticProps) defineProperties(Constructor, staticProps);
2963
+ return Constructor;
2964
+ };
2965
+ }();
2966
+
2967
+
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+ var _extends$1 = Object.assign || function (target) {
2974
+ for (var i = 1; i < arguments.length; i++) {
2975
+ var source = arguments[i];
2976
+
2977
+ for (var key in source) {
2978
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
2979
+ target[key] = source[key];
2980
+ }
2981
+ }
2982
+ }
2983
+
2984
+ return target;
2985
+ };
2986
+
2987
+ /**
2988
+ * Creates a new popper instance
2989
+ * @param {Object} refData
2990
+ * @return {Object} - the popper instance
2991
+ */
2992
+ function createPopperInstance(refData) {
2993
+ var el = refData.el,
2994
+ popper = refData.popper,
2995
+ _refData$settings = refData.settings,
2996
+ position = _refData$settings.position,
2997
+ popperOptions = _refData$settings.popperOptions,
2998
+ offset = _refData$settings.offset,
2999
+ distance = _refData$settings.distance,
3000
+ flipDuration = _refData$settings.flipDuration;
3001
+
3002
+
3003
+ var tooltip = popper.querySelector(Selectors.TOOLTIP);
3004
+
3005
+ var config = _extends$1({
3006
+ placement: position
3007
+ }, popperOptions || {}, {
3008
+ modifiers: _extends$1({}, popperOptions ? popperOptions.modifiers : {}, {
3009
+ flip: _extends$1({
3010
+ padding: distance + 5 /* 5px from viewport boundary */
3011
+ }, popperOptions && popperOptions.modifiers ? popperOptions.modifiers.flip : {}),
3012
+ offset: _extends$1({
3013
+ offset: offset
3014
+ }, popperOptions && popperOptions.modifiers ? popperOptions.modifiers.offset : {})
3015
+ }),
3016
+ onUpdate: function onUpdate() {
3017
+ var styles = tooltip.style;
3018
+ styles.top = '';
3019
+ styles.bottom = '';
3020
+ styles.left = '';
3021
+ styles.right = '';
3022
+ styles[getCorePlacement(popper.getAttribute('x-placement'))] = getOffsetDistanceInPx(distance);
3023
+ }
3024
+ });
3025
+
3026
+ return new Popper(el, popper, config);
3027
+ }
3028
+
3029
+ /**
3030
+ * Appends the popper and creates a popper instance if one does not exist
3031
+ * Also updates its position if need be and enables event listeners
3032
+ * @param {Object} refData - the element/popper reference data
3033
+ */
3034
+ function mountPopper(refData) {
3035
+ var el = refData.el,
3036
+ popper = refData.popper,
3037
+ _refData$settings = refData.settings,
3038
+ appendTo = _refData$settings.appendTo,
3039
+ followCursor = _refData$settings.followCursor,
3040
+ flipDuration = _refData$settings.flipDuration;
3041
+
3042
+ // Already on the DOM
3043
+
3044
+ if (appendTo.contains(popper)) return;
3045
+
3046
+ appendTo.appendChild(popper);
3047
+
3048
+ if (!refData.popperInstance) {
3049
+ // Create instance if it hasn't been created yet
3050
+ refData.popperInstance = createPopperInstance(refData);
3051
+
3052
+ // Update the popper's position whenever its content changes
3053
+ // Not supported in IE10 unless polyfilled
3054
+ if (window.MutationObserver) {
3055
+ var styles = popper.style;
3056
+ var observer = new MutationObserver(function () {
3057
+ styles[prefix('transitionDuration')] = '0ms';
3058
+ refData.popperInstance.update();
3059
+ queueExecution(function () {
3060
+ styles[prefix('transitionDuration')] = flipDuration + 'ms';
3061
+ });
3062
+ });
3063
+ observer.observe(popper, {
3064
+ childList: true,
3065
+ subtree: true,
3066
+ characterData: true
3067
+ });
3068
+ refData._mutationObserver = observer;
3069
+ }
3070
+ } else {
3071
+ refData.popperInstance.update();
3072
+
3073
+ if (!followCursor || Browser.touch) {
3074
+ refData.popperInstance.enableEventListeners();
3075
+ }
3076
+ }
3077
+
3078
+ // Since touch is determined dynamically, followCursor setting
3079
+ // is set on mount
3080
+ if (followCursor && !Browser.touch) {
3081
+ el.addEventListener('mousemove', followCursorHandler);
3082
+ refData.popperInstance.disableEventListeners();
3083
+ }
3084
+ }
3085
+
3086
+ /**
3087
+ * Updates a popper's position on each animation frame to make it stick to a moving element
3088
+ * @param {Object} refData
3089
+ */
3090
+ function makeSticky(refData) {
3091
+ var popper = refData.popper,
3092
+ popperInstance = refData.popperInstance,
3093
+ stickyDuration = refData.settings.stickyDuration;
3094
+
3095
+
3096
+ var applyTransitionDuration = function applyTransitionDuration() {
3097
+ return popper.style[prefix('transitionDuration')] = stickyDuration + 'ms';
3098
+ };
3099
+
3100
+ var removeTransitionDuration = function removeTransitionDuration() {
3101
+ return popper.style[prefix('transitionDuration')] = '';
3102
+ };
3103
+
3104
+ var updatePosition = function updatePosition() {
3105
+ popperInstance && popperInstance.scheduleUpdate();
3106
+
3107
+ applyTransitionDuration();
3108
+
3109
+ isVisible(popper) ? window.requestAnimationFrame(updatePosition) : removeTransitionDuration();
3110
+ };
3111
+
3112
+ // Wait until Popper's position has been updated initially
3113
+ queueExecution(updatePosition);
3114
+ }
3115
+
3116
+ /**
3117
+ * Returns an object of settings to override global settings
3118
+ * @param {Element} el - the tooltipped element
3119
+ * @param {Object} instanceSettings
3120
+ * @return {Object} - individual settings
3121
+ */
3122
+ function getIndividualSettings(el, instanceSettings) {
3123
+ var settings = DefaultsKeys.reduce(function (acc, key) {
3124
+ var val = el.getAttribute('data-' + key.toLowerCase()) || instanceSettings[key];
3125
+
3126
+ // Convert strings to booleans
3127
+ if (val === 'false') val = false;
3128
+ if (val === 'true') val = true;
3129
+
3130
+ // Convert number strings to true numbers
3131
+ if (isFinite(val) && !isNaN(parseFloat(val))) {
3132
+ val = parseFloat(val);
3133
+ }
3134
+
3135
+ // Convert array strings to actual arrays
3136
+ if (typeof val === 'string' && val.trim().charAt(0) === '[') {
3137
+ val = JSON.parse(val);
3138
+ }
3139
+
3140
+ acc[key] = val;
3141
+
3142
+ return acc;
3143
+ }, {});
3144
+
3145
+ return _extends$1({}, instanceSettings, settings);
3146
+ }
3147
+
3148
+ /**
3149
+ * Creates a popper element then returns it
3150
+ * @param {Number} id - the popper id
3151
+ * @param {String} title - the tooltip's `title` attribute
3152
+ * @param {Object} settings - individual settings
3153
+ * @return {Element} - the popper element
3154
+ */
3155
+ function createPopperElement(id, title, settings) {
3156
+ var position = settings.position,
3157
+ distance = settings.distance,
3158
+ arrow = settings.arrow,
3159
+ animateFill = settings.animateFill,
3160
+ inertia = settings.inertia,
3161
+ animation = settings.animation,
3162
+ arrowSize = settings.arrowSize,
3163
+ size = settings.size,
3164
+ theme = settings.theme,
3165
+ html = settings.html,
3166
+ zIndex = settings.zIndex,
3167
+ interactive = settings.interactive;
3168
+
3169
+
3170
+ var popper = document.createElement('div');
3171
+ popper.setAttribute('class', 'tippy-popper');
3172
+ popper.setAttribute('role', 'tooltip');
3173
+ popper.setAttribute('aria-hidden', 'true');
3174
+ popper.setAttribute('id', 'tippy-tooltip-' + id);
3175
+ popper.style.zIndex = zIndex;
3176
+
3177
+ var tooltip = document.createElement('div');
3178
+ tooltip.setAttribute('class', 'tippy-tooltip tippy-tooltip--' + size + ' leave');
3179
+ tooltip.setAttribute('data-animation', animation);
3180
+
3181
+ theme.split(' ').forEach(function (t) {
3182
+ tooltip.classList.add(t + '-theme');
3183
+ });
3184
+
3185
+ if (arrow) {
3186
+ // Add an arrow
3187
+ var _arrow = document.createElement('div');
3188
+ _arrow.setAttribute('class', 'arrow-' + arrowSize);
3189
+ _arrow.setAttribute('x-arrow', '');
3190
+ tooltip.appendChild(_arrow);
3191
+ }
3192
+
3193
+ if (animateFill) {
3194
+ // Create animateFill circle element for animation
3195
+ tooltip.setAttribute('data-animatefill', '');
3196
+ var circle = document.createElement('div');
3197
+ circle.setAttribute('class', 'leave');
3198
+ circle.setAttribute('x-circle', '');
3199
+ tooltip.appendChild(circle);
3200
+ }
3201
+
3202
+ if (inertia) {
3203
+ // Change transition timing function cubic bezier
3204
+ tooltip.setAttribute('data-inertia', '');
3205
+ }
3206
+
3207
+ if (interactive) {
3208
+ tooltip.setAttribute('data-interactive', '');
3209
+ }
3210
+
3211
+ // Tooltip content (text or HTML)
3212
+ var content = document.createElement('div');
3213
+ content.setAttribute('class', 'tippy-tooltip-content');
3214
+
3215
+ if (html) {
3216
+ var templateId = void 0;
3217
+
3218
+ if (html instanceof Element) {
3219
+ content.appendChild(html);
3220
+ templateId = '#' + html.id || 'tippy-html-template';
3221
+ } else {
3222
+ content.innerHTML = document.getElementById(html.replace('#', '')).innerHTML;
3223
+ templateId = html;
3224
+ }
3225
+
3226
+ popper.classList.add('html-template');
3227
+ interactive && popper.setAttribute('tabindex', '-1');
3228
+ tooltip.setAttribute('data-template-id', templateId);
3229
+ } else {
3230
+ content.innerHTML = title;
3231
+ }
3232
+
3233
+ // Init distance. Further updates are made in the popper instance's `onUpdate()` method
3234
+ tooltip.style[getCorePlacement(position)] = getOffsetDistanceInPx(distance);
3235
+
3236
+ tooltip.appendChild(content);
3237
+ popper.appendChild(tooltip);
3238
+
3239
+ return popper;
3240
+ }
3241
+
3242
+ /**
3243
+ * Creates a trigger
3244
+ * @param {Object} event - the custom event specified in the `trigger` setting
3245
+ * @param {Element} el - tooltipped element
3246
+ * @param {Object} handlers - the handlers for each listener
3247
+ * @param {Boolean} touchHold
3248
+ * @return {Array} - array of listener objects
3249
+ */
3250
+ function createTrigger(event, el, handlers, touchHold) {
3251
+ var listeners = [];
3252
+
3253
+ if (event === 'manual') return listeners;
3254
+
3255
+ // Enter
3256
+ el.addEventListener(event, handlers.handleTrigger);
3257
+ listeners.push({
3258
+ event: event,
3259
+ handler: handlers.handleTrigger
3260
+ });
3261
+
3262
+ // Leave
3263
+ if (event === 'mouseenter') {
3264
+ if (Browser.SUPPORTS_TOUCH && touchHold) {
3265
+ el.addEventListener('touchstart', handlers.handleTrigger);
3266
+ listeners.push({
3267
+ event: 'touchstart',
3268
+ handler: handlers.handleTrigger
3269
+ });
3270
+ el.addEventListener('touchend', handlers.handleMouseleave);
3271
+ listeners.push({
3272
+ event: 'touchend',
3273
+ handler: handlers.handleMouseleave
3274
+ });
3275
+ }
3276
+
3277
+ el.addEventListener('mouseleave', handlers.handleMouseleave);
3278
+ listeners.push({
3279
+ event: 'mouseleave',
3280
+ handler: handlers.handleMouseleave
3281
+ });
3282
+ }
3283
+
3284
+ if (event === 'focus') {
3285
+ el.addEventListener('blur', handlers.handleBlur);
3286
+ listeners.push({
3287
+ event: 'blur',
3288
+ handler: handlers.handleBlur
3289
+ });
3290
+ }
3291
+
3292
+ return listeners;
3293
+ }
3294
+
3295
+ /**
3296
+ * Determines if the mouse's cursor is outside the interactive border
3297
+ * @param {MouseEvent} event
3298
+ * @param {Element} popper
3299
+ * @param {Object} settings
3300
+ * @return {Boolean}
3301
+ */
3302
+ function cursorIsOutsideInteractiveBorder(event, popper, settings) {
3303
+ if (!popper.getAttribute('x-placement')) return true;
3304
+
3305
+ var x = event.clientX,
3306
+ y = event.clientY;
3307
+ var interactiveBorder = settings.interactiveBorder,
3308
+ distance = settings.distance;
3309
+
3310
+
3311
+ var rect = popper.getBoundingClientRect();
3312
+ var corePosition = getCorePlacement(popper.getAttribute('x-placement'));
3313
+ var borderWithDistance = interactiveBorder + distance;
3314
+
3315
+ var exceeds = {
3316
+ top: rect.top - y > interactiveBorder,
3317
+ bottom: y - rect.bottom > interactiveBorder,
3318
+ left: rect.left - x > interactiveBorder,
3319
+ right: x - rect.right > interactiveBorder
3320
+ };
3321
+
3322
+ switch (corePosition) {
3323
+ case 'top':
3324
+ exceeds.top = rect.top - y > borderWithDistance;
3325
+ break;
3326
+ case 'bottom':
3327
+ exceeds.bottom = y - rect.bottom > borderWithDistance;
3328
+ break;
3329
+ case 'left':
3330
+ exceeds.left = rect.left - x > borderWithDistance;
3331
+ break;
3332
+ case 'right':
3333
+ exceeds.right = x - rect.right > borderWithDistance;
3334
+ break;
3335
+ }
3336
+
3337
+ return exceeds.top || exceeds.bottom || exceeds.left || exceeds.right;
3338
+ }
3339
+
3340
+ /**
3341
+ * Returns relevant listener callbacks for each ref
3342
+ * @param {Element} el
3343
+ * @param {Element} popper
3344
+ * @param {Object} settings
3345
+ * @return {Object} - relevant listener handlers
3346
+ */
3347
+ function getEventListenerHandlers(el, popper, settings) {
3348
+ var _this = this;
3349
+
3350
+ var position = settings.position,
3351
+ delay = settings.delay,
3352
+ duration = settings.duration,
3353
+ interactive = settings.interactive,
3354
+ interactiveBorder = settings.interactiveBorder,
3355
+ distance = settings.distance,
3356
+ hideOnClick = settings.hideOnClick,
3357
+ trigger = settings.trigger,
3358
+ touchHold = settings.touchHold,
3359
+ touchWait = settings.touchWait;
3360
+
3361
+
3362
+ var showDelay = void 0,
3363
+ hideDelay = void 0;
3364
+
3365
+ var clearTimeouts = function clearTimeouts() {
3366
+ clearTimeout(showDelay);
3367
+ clearTimeout(hideDelay);
3368
+ };
3369
+
3370
+ var _show = function _show() {
3371
+ clearTimeouts();
3372
+
3373
+ // Not hidden. For clicking when it also has a `focus` event listener
3374
+ if (isVisible(popper)) return;
3375
+
3376
+ var _delay = Array.isArray(delay) ? delay[0] : delay;
3377
+
3378
+ if (delay) {
3379
+ showDelay = setTimeout(function () {
3380
+ return _this.show(popper);
3381
+ }, _delay);
3382
+ } else {
3383
+ _this.show(popper);
3384
+ }
3385
+ };
3386
+
3387
+ var show = function show(event) {
3388
+ return _this.callbacks.wait ? _this.callbacks.wait.call(popper, _show, event) : _show();
3389
+ };
3390
+
3391
+ var hide = function hide() {
3392
+ clearTimeouts();
3393
+
3394
+ var _delay = Array.isArray(delay) ? delay[1] : delay;
3395
+
3396
+ if (delay) {
3397
+ hideDelay = setTimeout(function () {
3398
+ return _this.hide(popper);
3399
+ }, _delay);
3400
+ } else {
3401
+ _this.hide(popper);
3402
+ }
3403
+ };
3404
+
3405
+ var handleTrigger = function handleTrigger(event) {
3406
+ var mouseenterTouch = event.type === 'mouseenter' && Browser.SUPPORTS_TOUCH && Browser.touch;
3407
+
3408
+ if (mouseenterTouch && touchHold) return;
3409
+
3410
+ // Toggle show/hide when clicking click-triggered tooltips
3411
+ var isClick = event.type === 'click';
3412
+ var isNotPersistent = hideOnClick !== 'persistent';
3413
+
3414
+ isClick && isVisible(popper) && isNotPersistent ? hide() : show(event);
3415
+
3416
+ if (mouseenterTouch && Browser.iOS() && el.click) {
3417
+ el.click();
3418
+ }
3419
+ };
3420
+
3421
+ var handleMouseleave = function handleMouseleave(event) {
3422
+
3423
+ // Don't fire 'mouseleave', use the 'touchend'
3424
+ if (event.type === 'mouseleave' && Browser.SUPPORTS_TOUCH && Browser.touch && touchHold) {
3425
+ return;
3426
+ }
3427
+
3428
+ if (interactive) {
3429
+ // Temporarily handle mousemove to check if the mouse left somewhere
3430
+ // other than its popper
3431
+ var handleMousemove = function handleMousemove(event) {
3432
+
3433
+ var triggerHide = function triggerHide() {
3434
+ document.body.removeEventListener('mouseleave', hide);
3435
+ document.removeEventListener('mousemove', handleMousemove);
3436
+ hide();
3437
+ };
3438
+
3439
+ var closestTooltippedEl = closest(event.target, Selectors.TOOLTIPPED_EL);
3440
+
3441
+ var isOverPopper = closest(event.target, Selectors.POPPER) === popper;
3442
+ var isOverEl = closestTooltippedEl === el;
3443
+ var isClickTriggered = trigger.indexOf('click') !== -1;
3444
+ var isOverOtherTooltippedEl = closestTooltippedEl && closestTooltippedEl !== el;
3445
+
3446
+ if (isOverOtherTooltippedEl) {
3447
+ return triggerHide();
3448
+ }
3449
+
3450
+ if (isOverPopper || isOverEl || isClickTriggered) return;
3451
+
3452
+ if (cursorIsOutsideInteractiveBorder(event, popper, settings)) {
3453
+ triggerHide();
3454
+ }
3455
+ };
3456
+
3457
+ document.body.addEventListener('mouseleave', hide);
3458
+ document.addEventListener('mousemove', handleMousemove);
3459
+
3460
+ return;
3461
+ }
3462
+
3463
+ // If it's not interactive, just hide it
3464
+ hide();
3465
+ };
3466
+
3467
+ var handleBlur = function handleBlur(event) {
3468
+ // Ignore blur on touch devices, if there is no `relatedTarget`, hide
3469
+ // If the related target is a popper, ignore
3470
+ if (!event.relatedTarget || Browser.touch) return;
3471
+ if (closest(event.relatedTarget, Selectors.POPPER)) return;
3472
+
3473
+ hide();
3474
+ };
3475
+
3476
+ return {
3477
+ handleTrigger: handleTrigger,
3478
+ handleMouseleave: handleMouseleave,
3479
+ handleBlur: handleBlur
3480
+ };
3481
+ }
3482
+
3483
+ var idCounter = 1;
3484
+
3485
+ /**
3486
+ * Creates tooltips for all el elements that match the instance's selector
3487
+ * @param {Element[]} els
3488
+ * @return {Object[]} Array of ref data objects
3489
+ */
3490
+ function createTooltips(els) {
3491
+ var _this = this;
3492
+
3493
+ return els.reduce(function (a, el) {
3494
+ var id = idCounter;
3495
+
3496
+ var settings = _this.settings.performance ? _this.settings : getIndividualSettings(el, _this.settings);
3497
+ // animateFill is disabled if an arrow is true
3498
+ if (settings.arrow) settings.animateFill = false;
3499
+
3500
+ var html = settings.html,
3501
+ trigger = settings.trigger,
3502
+ touchHold = settings.touchHold;
3503
+
3504
+
3505
+ var title = el.getAttribute('title');
3506
+ if (!title && !html) return a;
3507
+
3508
+ el.setAttribute('data-tooltipped', '');
3509
+ el.setAttribute('aria-describedby', 'tippy-tooltip-' + id);
3510
+ removeTitle(el);
3511
+
3512
+ var popper = createPopperElement(id, title, settings);
3513
+ var handlers = getEventListenerHandlers.call(_this, el, popper, settings);
3514
+
3515
+ var listeners = [];
3516
+
3517
+ trigger.trim().split(' ').forEach(function (event) {
3518
+ return listeners = listeners.concat(createTrigger(event, el, handlers, touchHold));
3519
+ });
3520
+
3521
+ a.push({
3522
+ id: id,
3523
+ el: el,
3524
+ popper: popper,
3525
+ settings: settings,
3526
+ listeners: listeners,
3527
+ tippyInstance: _this
3528
+ });
3529
+
3530
+ idCounter++;
3531
+
3532
+ return a;
3533
+ }, []);
3534
+ }
3535
+
3536
+ /* Utility functions */
3537
+ /* Core library functions */
3538
+ /**
3539
+ * @param {String|Element|Element[]} selector
3540
+ * @param {Object} settings (optional) - the object of settings to be applied to the instance
3541
+ */
3542
+
3543
+ var Tippy = function () {
3544
+ function Tippy(selector) {
3545
+ var settings = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3546
+ classCallCheck$1(this, Tippy);
3547
+
3548
+ // Use default browser tooltip on unsupported browsers
3549
+ if (!Browser.SUPPORTED) return;
3550
+
3551
+ // DOM is presumably mostly ready (for document.body) by instantiation time
3552
+ init();
3553
+
3554
+ this.state = {
3555
+ destroyed: false
3556
+ };
3557
+
3558
+ this.selector = selector;
3559
+
3560
+ this.settings = _extends$1({}, Defaults, settings);
3561
+
3562
+ // DEPRECATION: `on` prefixed callbacks are now preferred over non-
3563
+ // as it better indicates it's a callback function
3564
+ this.callbacks = {
3565
+ wait: settings.wait,
3566
+ show: settings.onShow || settings.show || noop,
3567
+ shown: settings.onShown || settings.shown || noop,
3568
+ hide: settings.onHide || settings.hide || noop,
3569
+ hidden: settings.onHidden || settings.hidden || noop
3570
+ };
3571
+
3572
+ this.store = createTooltips.call(this, getArrayOfElements(selector));
3573
+ Store.push.apply(Store, this.store);
3574
+ }
3575
+
3576
+ /**
3577
+ * Returns the reference element's popper element
3578
+ * @param {Element} el
3579
+ * @return {Element}
3580
+ */
3581
+
3582
+
3583
+ createClass$1(Tippy, [{
3584
+ key: 'getPopperElement',
3585
+ value: function getPopperElement(el) {
3586
+ try {
3587
+ return find(this.store, function (refData) {
3588
+ return refData.el === el;
3589
+ }).popper;
3590
+ } catch (e) {
3591
+ console.error('[getPopperElement]: Element passed as the argument does not exist in the instance');
3592
+ }
3593
+ }
3594
+
3595
+ /**
3596
+ * Returns a popper's reference element
3597
+ * @param {Element} popper
3598
+ * @return {Element}
3599
+ */
3600
+
3601
+ }, {
3602
+ key: 'getReferenceElement',
3603
+ value: function getReferenceElement(popper) {
3604
+ try {
3605
+ return find(this.store, function (refData) {
3606
+ return refData.popper === popper;
3607
+ }).el;
3608
+ } catch (e) {
3609
+ console.error('[getReferenceElement]: Popper passed as the argument does not exist in the instance');
3610
+ }
3611
+ }
3612
+
3613
+ /**
3614
+ * Returns the reference data object from either the reference element or popper element
3615
+ * @param {Element} x (reference element or popper)
3616
+ * @return {Object}
3617
+ */
3618
+
3619
+ }, {
3620
+ key: 'getReferenceData',
3621
+ value: function getReferenceData(x) {
3622
+ return find(this.store, function (refData) {
3623
+ return refData.el === x || refData.popper === x;
3624
+ });
3625
+ }
3626
+
3627
+ /**
3628
+ * Shows a popper
3629
+ * @param {Element} popper
3630
+ * @param {Number} customDuration (optional)
3631
+ */
3632
+
3633
+ }, {
3634
+ key: 'show',
3635
+ value: function show(popper, customDuration) {
3636
+ var _this = this;
3637
+
3638
+ if (this.state.destroyed) return;
3639
+
3640
+ this.callbacks.show.call(popper);
3641
+
3642
+ var refData = find(this.store, function (refData) {
3643
+ return refData.popper === popper;
3644
+ });
3645
+ var tooltip = popper.querySelector(Selectors.TOOLTIP);
3646
+ var circle = popper.querySelector(Selectors.CIRCLE);
3647
+ var content = popper.querySelector(Selectors.CONTENT);
3648
+
3649
+ var el = refData.el,
3650
+ _refData$settings = refData.settings,
3651
+ appendTo = _refData$settings.appendTo,
3652
+ sticky = _refData$settings.sticky,
3653
+ interactive = _refData$settings.interactive,
3654
+ followCursor = _refData$settings.followCursor,
3655
+ flipDuration = _refData$settings.flipDuration,
3656
+ duration = _refData$settings.duration,
3657
+ dynamicTitle = _refData$settings.dynamicTitle;
3658
+
3659
+
3660
+ if (dynamicTitle) {
3661
+ var title = el.getAttribute('title');
3662
+ if (title) {
3663
+ content.innerHTML = title;
3664
+ removeTitle(el);
3665
+ }
3666
+ }
3667
+
3668
+ var _duration = customDuration !== undefined ? customDuration : Array.isArray(duration) ? duration[0] : duration;
3669
+
3670
+ // Remove transition duration (prevent a transition when popper changes position)
3671
+ applyTransitionDuration([popper, tooltip, circle], 0);
3672
+
3673
+ mountPopper(refData);
3674
+
3675
+ popper.style.visibility = 'visible';
3676
+ popper.setAttribute('aria-hidden', 'false');
3677
+
3678
+ // Wait for popper to update position and alter x-placement
3679
+ queueExecution(function () {
3680
+ if (!isVisible(popper)) return;
3681
+
3682
+ // Sometimes the arrow will not be in the correct position,
3683
+ // force another update
3684
+ if (!followCursor || Browser.touch) {
3685
+ refData.popperInstance.update();
3686
+ }
3687
+
3688
+ // Re-apply transition durations
3689
+ applyTransitionDuration([tooltip, circle], _duration);
3690
+ if (!followCursor || Browser.touch) {
3691
+ applyTransitionDuration([popper], flipDuration);
3692
+ }
3693
+
3694
+ // Make content fade out a bit faster than the tooltip if `animateFill`
3695
+ if (circle) content.style.opacity = 1;
3696
+
3697
+ // Interactive tooltips receive a class of 'active'
3698
+ interactive && el.classList.add('active');
3699
+
3700
+ // Update popper's position on every animation frame
3701
+ sticky && makeSticky(refData);
3702
+
3703
+ // Repaint/reflow is required for CSS transition when appending
3704
+ triggerReflow(tooltip, circle);
3705
+
3706
+ modifyClassList([tooltip, circle], function (list) {
3707
+ list.contains('tippy-notransition') && list.remove('tippy-notransition');
3708
+ list.remove('leave');
3709
+ list.add('enter');
3710
+ });
3711
+
3712
+ // Wait for transitions to complete
3713
+ onTransitionEnd(refData, _duration, function () {
3714
+ if (!isVisible(popper) || refData._onShownFired) return;
3715
+
3716
+ // Focus interactive tooltips only
3717
+ interactive && popper.focus();
3718
+
3719
+ // Remove transitions from tooltip
3720
+ tooltip.classList.add('tippy-notransition');
3721
+
3722
+ // Prevents shown() from firing more than once from early transition cancellations
3723
+ refData._onShownFired = true;
3724
+
3725
+ _this.callbacks.shown.call(popper);
3726
+ });
3727
+ });
3728
+ }
3729
+
3730
+ /**
3731
+ * Hides a popper
3732
+ * @param {Element} popper
3733
+ * @param {Number} customDuration (optional)
3734
+ */
3735
+
3736
+ }, {
3737
+ key: 'hide',
3738
+ value: function hide(popper, customDuration) {
3739
+ var _this2 = this;
3740
+
3741
+ if (this.state.destroyed) return;
3742
+
3743
+ this.callbacks.hide.call(popper);
3744
+
3745
+ var refData = find(this.store, function (refData) {
3746
+ return refData.popper === popper;
3747
+ });
3748
+ var tooltip = popper.querySelector(Selectors.TOOLTIP);
3749
+ var circle = popper.querySelector(Selectors.CIRCLE);
3750
+ var content = popper.querySelector(Selectors.CONTENT);
3751
+
3752
+ var el = refData.el,
3753
+ _refData$settings2 = refData.settings,
3754
+ appendTo = _refData$settings2.appendTo,
3755
+ sticky = _refData$settings2.sticky,
3756
+ interactive = _refData$settings2.interactive,
3757
+ followCursor = _refData$settings2.followCursor,
3758
+ html = _refData$settings2.html,
3759
+ trigger = _refData$settings2.trigger,
3760
+ duration = _refData$settings2.duration;
3761
+
3762
+
3763
+ var _duration = customDuration !== undefined ? customDuration : Array.isArray(duration) ? duration[1] : duration;
3764
+
3765
+ refData._onShownFired = false;
3766
+ interactive && el.classList.remove('active');
3767
+
3768
+ popper.style.visibility = 'hidden';
3769
+ popper.setAttribute('aria-hidden', 'true');
3770
+
3771
+ applyTransitionDuration([tooltip, circle, circle ? content : null], _duration);
3772
+
3773
+ if (circle) content.style.opacity = 0;
3774
+
3775
+ modifyClassList([tooltip, circle], function (list) {
3776
+ list.contains('tippy-tooltip') && list.remove('tippy-notransition');
3777
+ list.remove('enter');
3778
+ list.add('leave');
3779
+ });
3780
+
3781
+ // Re-focus click-triggered html elements
3782
+ // and the tooltipped element IS in the viewport (otherwise it causes unsightly scrolling
3783
+ // if the tooltip is closed and the element isn't in the viewport anymore)
3784
+ if (html && trigger.indexOf('click') !== -1 && elementIsInViewport(el)) {
3785
+ el.focus();
3786
+ }
3787
+
3788
+ // Wait for transitions to complete
3789
+ onTransitionEnd(refData, _duration, function () {
3790
+ if (isVisible(popper) || !appendTo.contains(popper)) return;
3791
+
3792
+ el.removeEventListener('mousemove', followCursorHandler);
3793
+
3794
+ refData.popperInstance.disableEventListeners();
3795
+
3796
+ appendTo.removeChild(popper);
3797
+
3798
+ _this2.callbacks.hidden.call(popper);
3799
+ });
3800
+ }
3801
+
3802
+ /**
3803
+ * Updates a popper with new content
3804
+ * @param {Element} popper
3805
+ */
3806
+
3807
+ }, {
3808
+ key: 'update',
3809
+ value: function update(popper) {
3810
+ if (this.state.destroyed) return;
3811
+
3812
+ var refData = find(this.store, function (refData) {
3813
+ return refData.popper === popper;
3814
+ });
3815
+ var content = popper.querySelector(Selectors.CONTENT);
3816
+ var el = refData.el,
3817
+ html = refData.settings.html;
3818
+
3819
+
3820
+ if (html instanceof Element) {
3821
+ console.warn('Aborted: update() should not be used if `html` is a DOM element');
3822
+ return;
3823
+ }
3824
+
3825
+ content.innerHTML = html ? document.getElementById(html.replace('#', '')).innerHTML : el.getAttribute('title') || el.getAttribute('data-original-title');
3826
+
3827
+ if (!html) removeTitle(el);
3828
+ }
3829
+
3830
+ /**
3831
+ * Destroys a popper
3832
+ * @param {Element} popper
3833
+ * @param {Boolean} _isLast - private param used by destroyAll to optimize
3834
+ */
3835
+
3836
+ }, {
3837
+ key: 'destroy',
3838
+ value: function destroy(popper, _isLast) {
3839
+ var _this3 = this;
3840
+
3841
+ if (this.state.destroyed) return;
3842
+
3843
+ var refData = find(this.store, function (refData) {
3844
+ return refData.popper === popper;
3845
+ });
3846
+
3847
+ var el = refData.el,
3848
+ popperInstance = refData.popperInstance,
3849
+ listeners = refData.listeners,
3850
+ _mutationObserver = refData._mutationObserver;
3851
+
3852
+ // Ensure the popper is hidden
3853
+
3854
+ if (isVisible(popper)) {
3855
+ this.hide(popper, 0);
3856
+ }
3857
+
3858
+ // Remove Tippy-only event listeners from tooltipped element
3859
+ listeners.forEach(function (listener) {
3860
+ return el.removeEventListener(listener.event, listener.handler);
3861
+ });
3862
+
3863
+ // Restore original title
3864
+ el.setAttribute('title', el.getAttribute('data-original-title'));
3865
+
3866
+ el.removeAttribute('data-original-title');
3867
+ el.removeAttribute('data-tooltipped');
3868
+ el.removeAttribute('aria-describedby');
3869
+
3870
+ popperInstance && popperInstance.destroy();
3871
+ _mutationObserver && _mutationObserver.disconnect();
3872
+
3873
+ // Remove from store
3874
+ Store.splice(findIndex(Store, function (refData) {
3875
+ return refData.popper === popper;
3876
+ }), 1);
3877
+
3878
+ // Ensure filter is called only once
3879
+ if (_isLast === undefined || _isLast) {
3880
+ this.store = Store.filter(function (refData) {
3881
+ return refData.tippyInstance === _this3;
3882
+ });
3883
+ }
3884
+ }
3885
+
3886
+ /**
3887
+ * Destroys all tooltips created by the instance
3888
+ */
3889
+
3890
+ }, {
3891
+ key: 'destroyAll',
3892
+ value: function destroyAll() {
3893
+ var _this4 = this;
3894
+
3895
+ if (this.state.destroyed) return;
3896
+
3897
+ var storeLength = this.store.length;
3898
+
3899
+ this.store.forEach(function (_ref, index) {
3900
+ var popper = _ref.popper;
3901
+
3902
+ _this4.destroy(popper, index === storeLength - 1);
3903
+ });
3904
+
3905
+ this.store = null;
3906
+ this.state.destroyed = true;
3907
+ }
3908
+ }]);
3909
+ return Tippy;
3910
+ }();
3911
+
3912
+ function tippy$2(selector, settings) {
3913
+ return new Tippy(selector, settings);
3914
+ }
3915
+
3916
+ tippy$2.Browser = Browser;
3917
+ tippy$2.Defaults = Defaults;
3918
+ tippy$2.disableDynamicInputDetection = function () {
3919
+ return Browser.dynamicInputDetection = false;
3920
+ };
3921
+ tippy$2.enableDynamicInputDetection = function () {
3922
+ return Browser.dynamicInputDetection = true;
3923
+ };
3924
+
3925
+ return tippy$2;
3926
+
3927
+ })));