tippy_rails 1.2.1.2 → 1.2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ })));