PluginProbe
UpdraftCentral Dashboard / trunk
UpdraftCentral Dashboard vtrunk
0.8.33 0.7.2 0.7.3 0.7.4 0.8.0 0.8.1 0.8.10 0.8.11 0.8.12 0.8.13 0.8.14 0.8.15 0.8.16 0.8.17 0.8.18 0.8.19 0.8.2 0.8.20 0.8.21 0.8.22 0.8.23 0.8.24 0.8.25 0.8.26 0.8.27 All 51 releases
updraftcentral / js / tether / tether.js

tether.js in UpdraftCentral Dashboard trunk, at js/tether/tether.js

1,821 lines 55.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! tether 1.4.7 */
2
3 (function(root, factory) {
4 if (typeof define === 'function' && define.amd) {
5 define([], factory);
6 } else if (typeof exports === 'object') {
7 module.exports = factory();
8 } else {
9 root.Tether = factory();
10 }
11 }(this, function() {
12
13 'use strict';
14
15 var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
16
17 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
18
19 var TetherBase = undefined;
20 if (typeof TetherBase === 'undefined') {
21 TetherBase = { modules: [] };
22 }
23
24 var zeroElement = null;
25
26 // Same as native getBoundingClientRect, except it takes into account parent <frame> offsets
27 // if the element lies within a nested document (<frame> or <iframe>-like).
28 function getActualBoundingClientRect(node) {
29 var boundingRect = node.getBoundingClientRect();
30
31 // The original object returned by getBoundingClientRect is immutable, so we clone it
32 // We can't use extend because the properties are not considered part of the object by hasOwnProperty in IE9
33 var rect = {};
34 for (var k in boundingRect) {
35 rect[k] = boundingRect[k];
36 }
37
38 try {
39 if (node.ownerDocument !== document) {
40 var _frameElement = node.ownerDocument.defaultView.frameElement;
41 if (_frameElement) {
42 var frameRect = getActualBoundingClientRect(_frameElement);
43 rect.top += frameRect.top;
44 rect.bottom += frameRect.top;
45 rect.left += frameRect.left;
46 rect.right += frameRect.left;
47 }
48 }
49 } catch (err) {
50 // Ignore "Access is denied" in IE11/Edge
51 }
52
53 return rect;
54 }
55
56 function getScrollParents(el) {
57 // In firefox if the el is inside an iframe with display: none; window.getComputedStyle() will return null;
58 // https://bugzilla.mozilla.org/show_bug.cgi?id=548397
59 var computedStyle = getComputedStyle(el) || {};
60 var position = computedStyle.position;
61 var parents = [];
62
63 if (position === 'fixed') {
64 return [el];
65 }
66
67 var parent = el;
68 while ((parent = parent.parentNode) && parent && parent.nodeType === 1) {
69 var style = undefined;
70 try {
71 style = getComputedStyle(parent);
72 } catch (err) {}
73
74 if (typeof style === 'undefined' || style === null) {
75 parents.push(parent);
76 return parents;
77 }
78
79 var _style = style;
80 var overflow = _style.overflow;
81 var overflowX = _style.overflowX;
82 var overflowY = _style.overflowY;
83
84 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
85 if (position !== 'absolute' || ['relative', 'absolute', 'fixed'].indexOf(style.position) >= 0) {
86 parents.push(parent);
87 }
88 }
89 }
90
91 parents.push(el.ownerDocument.body);
92
93 // If the node is within a frame, account for the parent window scroll
94 if (el.ownerDocument !== document) {
95 parents.push(el.ownerDocument.defaultView);
96 }
97
98 return parents;
99 }
100
101 var uniqueId = (function () {
102 var id = 0;
103 return function () {
104 return ++id;
105 };
106 })();
107
108 var zeroPosCache = {};
109 var getOrigin = function getOrigin() {
110 // getBoundingClientRect is unfortunately too accurate. It introduces a pixel or two of
111 // jitter as the user scrolls that messes with our ability to detect if two positions
112 // are equivilant or not. We place an element at the top left of the page that will
113 // get the same jitter, so we can cancel the two out.
114 var node = zeroElement;
115 if (!node || !document.body.contains(node)) {
116 node = document.createElement('div');
117 node.setAttribute('data-tether-id', uniqueId());
118 extend(node.style, {
119 top: 0,
120 left: 0,
121 position: 'absolute'
122 });
123
124 document.body.appendChild(node);
125
126 zeroElement = node;
127 }
128
129 var id = node.getAttribute('data-tether-id');
130 if (typeof zeroPosCache[id] === 'undefined') {
131 zeroPosCache[id] = getActualBoundingClientRect(node);
132
133 // Clear the cache when this position call is done
134 defer(function () {
135 delete zeroPosCache[id];
136 });
137 }
138
139 return zeroPosCache[id];
140 };
141
142 function removeUtilElements() {
143 if (zeroElement) {
144 document.body.removeChild(zeroElement);
145 }
146 zeroElement = null;
147 };
148
149 function getBounds(el) {
150 var doc = undefined;
151 if (el === document) {
152 doc = document;
153 el = document.documentElement;
154 } else {
155 doc = el.ownerDocument;
156 }
157
158 var docEl = doc.documentElement;
159
160 var box = getActualBoundingClientRect(el);
161
162 var origin = getOrigin();
163
164 box.top -= origin.top;
165 box.left -= origin.left;
166
167 if (typeof box.width === 'undefined') {
168 box.width = document.body.scrollWidth - box.left - box.right;
169 }
170 if (typeof box.height === 'undefined') {
171 box.height = document.body.scrollHeight - box.top - box.bottom;
172 }
173
174 box.top = box.top - docEl.clientTop;
175 box.left = box.left - docEl.clientLeft;
176 box.right = doc.body.clientWidth - box.width - box.left;
177 box.bottom = doc.body.clientHeight - box.height - box.top;
178
179 return box;
180 }
181
182 function getOffsetParent(el) {
183 return el.offsetParent || document.documentElement;
184 }
185
186 var _scrollBarSize = null;
187 function getScrollBarSize() {
188 if (_scrollBarSize) {
189 return _scrollBarSize;
190 }
191 var inner = document.createElement('div');
192 inner.style.width = '100%';
193 inner.style.height = '200px';
194
195 var outer = document.createElement('div');
196 extend(outer.style, {
197 position: 'absolute',
198 top: 0,
199 left: 0,
200 pointerEvents: 'none',
201 visibility: 'hidden',
202 width: '200px',
203 height: '150px',
204 overflow: 'hidden'
205 });
206
207 outer.appendChild(inner);
208
209 document.body.appendChild(outer);
210
211 var widthContained = inner.offsetWidth;
212 outer.style.overflow = 'scroll';
213 var widthScroll = inner.offsetWidth;
214
215 if (widthContained === widthScroll) {
216 widthScroll = outer.clientWidth;
217 }
218
219 document.body.removeChild(outer);
220
221 var width = widthContained - widthScroll;
222
223 _scrollBarSize = { width: width, height: width };
224 return _scrollBarSize;
225 }
226
227 function extend() {
228 var out = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
229
230 var args = [];
231
232 Array.prototype.push.apply(args, arguments);
233
234 args.slice(1).forEach(function (obj) {
235 if (obj) {
236 for (var key in obj) {
237 if (({}).hasOwnProperty.call(obj, key)) {
238 out[key] = obj[key];
239 }
240 }
241 }
242 });
243
244 return out;
245 }
246
247 function removeClass(el, name) {
248 if (typeof el.classList !== 'undefined') {
249 name.split(' ').forEach(function (cls) {
250 if (cls.trim()) {
251 el.classList.remove(cls);
252 }
253 });
254 } else {
255 var regex = new RegExp('(^| )' + name.split(' ').join('|') + '( |$)', 'gi');
256 var className = getClassName(el).replace(regex, ' ');
257 setClassName(el, className);
258 }
259 }
260
261 function addClass(el, name) {
262 if (typeof el.classList !== 'undefined') {
263 name.split(' ').forEach(function (cls) {
264 if (cls.trim()) {
265 el.classList.add(cls);
266 }
267 });
268 } else {
269 removeClass(el, name);
270 var cls = getClassName(el) + (' ' + name);
271 setClassName(el, cls);
272 }
273 }
274
275 function hasClass(el, name) {
276 if (typeof el.classList !== 'undefined') {
277 return el.classList.contains(name);
278 }
279 var className = getClassName(el);
280 return new RegExp('(^| )' + name + '( |$)', 'gi').test(className);
281 }
282
283 function getClassName(el) {
284 // Can't use just SVGAnimatedString here since nodes within a Frame in IE have
285 // completely separately SVGAnimatedString base classes
286 if (el.className instanceof el.ownerDocument.defaultView.SVGAnimatedString) {
287 return el.className.baseVal;
288 }
289 return el.className;
290 }
291
292 function setClassName(el, className) {
293 el.setAttribute('class', className);
294 }
295
296 function updateClasses(el, add, all) {
297 // Of the set of 'all' classes, we need the 'add' classes, and only the
298 // 'add' classes to be set.
299 all.forEach(function (cls) {
300 if (add.indexOf(cls) === -1 && hasClass(el, cls)) {
301 removeClass(el, cls);
302 }
303 });
304
305 add.forEach(function (cls) {
306 if (!hasClass(el, cls)) {
307 addClass(el, cls);
308 }
309 });
310 }
311
312 var deferred = [];
313
314 var defer = function defer(fn) {
315 deferred.push(fn);
316 };
317
318 var flush = function flush() {
319 var fn = undefined;
320 while (fn = deferred.pop()) {
321 fn();
322 }
323 };
324
325 var Evented = (function () {
326 function Evented() {
327 _classCallCheck(this, Evented);
328 }
329
330 _createClass(Evented, [{
331 key: 'on',
332 value: function on(event, handler, ctx) {
333 var once = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
334
335 if (typeof this.bindings === 'undefined') {
336 this.bindings = {};
337 }
338 if (typeof this.bindings[event] === 'undefined') {
339 this.bindings[event] = [];
340 }
341 this.bindings[event].push({ handler: handler, ctx: ctx, once: once });
342 }
343 }, {
344 key: 'once',
345 value: function once(event, handler, ctx) {
346 this.on(event, handler, ctx, true);
347 }
348 }, {
349 key: 'off',
350 value: function off(event, handler) {
351 if (typeof this.bindings === 'undefined' || typeof this.bindings[event] === 'undefined') {
352 return;
353 }
354
355 if (typeof handler === 'undefined') {
356 delete this.bindings[event];
357 } else {
358 var i = 0;
359 while (i < this.bindings[event].length) {
360 if (this.bindings[event][i].handler === handler) {
361 this.bindings[event].splice(i, 1);
362 } else {
363 ++i;
364 }
365 }
366 }
367 }
368 }, {
369 key: 'trigger',
370 value: function trigger(event) {
371 if (typeof this.bindings !== 'undefined' && this.bindings[event]) {
372 var i = 0;
373
374 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
375 args[_key - 1] = arguments[_key];
376 }
377
378 while (i < this.bindings[event].length) {
379 var _bindings$event$i = this.bindings[event][i];
380 var handler = _bindings$event$i.handler;
381 var ctx = _bindings$event$i.ctx;
382 var once = _bindings$event$i.once;
383
384 var context = ctx;
385 if (typeof context === 'undefined') {
386 context = this;
387 }
388
389 handler.apply(context, args);
390
391 if (once) {
392 this.bindings[event].splice(i, 1);
393 } else {
394 ++i;
395 }
396 }
397 }
398 }
399 }]);
400
401 return Evented;
402 })();
403
404 TetherBase.Utils = {
405 getActualBoundingClientRect: getActualBoundingClientRect,
406 getScrollParents: getScrollParents,
407 getBounds: getBounds,
408 getOffsetParent: getOffsetParent,
409 extend: extend,
410 addClass: addClass,
411 removeClass: removeClass,
412 hasClass: hasClass,
413 updateClasses: updateClasses,
414 defer: defer,
415 flush: flush,
416 uniqueId: uniqueId,
417 Evented: Evented,
418 getScrollBarSize: getScrollBarSize,
419 removeUtilElements: removeUtilElements
420 };
421 /* globals TetherBase, performance */
422
423 'use strict';
424
425 var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
426
427 var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
428
429 var _get = function get(_x6, _x7, _x8) { var _again = true; _function: while (_again) { var object = _x6, property = _x7, receiver = _x8; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x6 = parent; _x7 = property; _x8 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
430
431 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
432
433 function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
434
435 if (typeof TetherBase === 'undefined') {
436 throw new Error('You must include the utils.js file before tether.js');
437 }
438
439 var _TetherBase$Utils = TetherBase.Utils;
440 var getScrollParents = _TetherBase$Utils.getScrollParents;
441 var getBounds = _TetherBase$Utils.getBounds;
442 var getOffsetParent = _TetherBase$Utils.getOffsetParent;
443 var extend = _TetherBase$Utils.extend;
444 var addClass = _TetherBase$Utils.addClass;
445 var removeClass = _TetherBase$Utils.removeClass;
446 var updateClasses = _TetherBase$Utils.updateClasses;
447 var defer = _TetherBase$Utils.defer;
448 var flush = _TetherBase$Utils.flush;
449 var getScrollBarSize = _TetherBase$Utils.getScrollBarSize;
450 var removeUtilElements = _TetherBase$Utils.removeUtilElements;
451
452 function within(a, b) {
453 var diff = arguments.length <= 2 || arguments[2] === undefined ? 1 : arguments[2];
454
455 return a + diff >= b && b >= a - diff;
456 }
457
458 var transformKey = (function () {
459 if (typeof document === 'undefined') {
460 return '';
461 }
462 var el = document.createElement('div');
463
464 var transforms = ['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform'];
465 for (var i = 0; i < transforms.length; ++i) {
466 var key = transforms[i];
467 if (el.style[key] !== undefined) {
468 return key;
469 }
470 }
471 })();
472
473 var tethers = [];
474
475 var position = function position() {
476 tethers.forEach(function (tether) {
477 tether.position(false);
478 });
479 flush();
480 };
481
482 function now() {
483 if (typeof performance === 'object' && typeof performance.now === 'function') {
484 return performance.now();
485 }
486 return +new Date();
487 }
488
489 (function () {
490 var lastCall = null;
491 var lastDuration = null;
492 var pendingTimeout = null;
493
494 var tick = function tick() {
495 if (typeof lastDuration !== 'undefined' && lastDuration > 16) {
496 // We voluntarily throttle ourselves if we can't manage 60fps
497 lastDuration = Math.min(lastDuration - 16, 250);
498
499 // Just in case this is the last event, remember to position just once more
500 pendingTimeout = setTimeout(tick, 250);
501 return;
502 }
503
504 if (typeof lastCall !== 'undefined' && now() - lastCall < 10) {
505 // Some browsers call events a little too frequently, refuse to run more than is reasonable
506 return;
507 }
508
509 if (pendingTimeout != null) {
510 clearTimeout(pendingTimeout);
511 pendingTimeout = null;
512 }
513
514 lastCall = now();
515 position();
516 lastDuration = now() - lastCall;
517 };
518
519 if (typeof window !== 'undefined' && typeof window.addEventListener !== 'undefined') {
520 ['resize', 'scroll', 'touchmove'].forEach(function (event) {
521 window.addEventListener(event, tick);
522 });
523 }
524 })();
525
526 var MIRROR_LR = {
527 center: 'center',
528 left: 'right',
529 right: 'left'
530 };
531
532 var MIRROR_TB = {
533 middle: 'middle',
534 top: 'bottom',
535 bottom: 'top'
536 };
537
538 var OFFSET_MAP = {
539 top: 0,
540 left: 0,
541 middle: '50%',
542 center: '50%',
543 bottom: '100%',
544 right: '100%'
545 };
546
547 var autoToFixedAttachment = function autoToFixedAttachment(attachment, relativeToAttachment) {
548 var left = attachment.left;
549 var top = attachment.top;
550
551 if (left === 'auto') {
552 left = MIRROR_LR[relativeToAttachment.left];
553 }
554
555 if (top === 'auto') {
556 top = MIRROR_TB[relativeToAttachment.top];
557 }
558
559 return { left: left, top: top };
560 };
561
562 var attachmentToOffset = function attachmentToOffset(attachment) {
563 var left = attachment.left;
564 var top = attachment.top;
565
566 if (typeof OFFSET_MAP[attachment.left] !== 'undefined') {
567 left = OFFSET_MAP[attachment.left];
568 }
569
570 if (typeof OFFSET_MAP[attachment.top] !== 'undefined') {
571 top = OFFSET_MAP[attachment.top];
572 }
573
574 return { left: left, top: top };
575 };
576
577 function addOffset() {
578 var out = { top: 0, left: 0 };
579
580 for (var _len = arguments.length, offsets = Array(_len), _key = 0; _key < _len; _key++) {
581 offsets[_key] = arguments[_key];
582 }
583
584 offsets.forEach(function (_ref) {
585 var top = _ref.top;
586 var left = _ref.left;
587
588 if (typeof top === 'string') {
589 top = parseFloat(top, 10);
590 }
591 if (typeof left === 'string') {
592 left = parseFloat(left, 10);
593 }
594
595 out.top += top;
596 out.left += left;
597 });
598
599 return out;
600 }
601
602 function offsetToPx(offset, size) {
603 if (typeof offset.left === 'string' && offset.left.indexOf('%') !== -1) {
604 offset.left = parseFloat(offset.left, 10) / 100 * size.width;
605 }
606 if (typeof offset.top === 'string' && offset.top.indexOf('%') !== -1) {
607 offset.top = parseFloat(offset.top, 10) / 100 * size.height;
608 }
609
610 return offset;
611 }
612
613 var parseOffset = function parseOffset(value) {
614 var _value$split = value.split(' ');
615
616 var _value$split2 = _slicedToArray(_value$split, 2);
617
618 var top = _value$split2[0];
619 var left = _value$split2[1];
620
621 return { top: top, left: left };
622 };
623 var parseAttachment = parseOffset;
624
625 var TetherClass = (function (_Evented) {
626 _inherits(TetherClass, _Evented);
627
628 function TetherClass(options) {
629 var _this = this;
630
631 _classCallCheck(this, TetherClass);
632
633 _get(Object.getPrototypeOf(TetherClass.prototype), 'constructor', this).call(this);
634 this.position = this.position.bind(this);
635
636 tethers.push(this);
637
638 this.history = [];
639
640 this.setOptions(options, false);
641
642 TetherBase.modules.forEach(function (module) {
643 if (typeof module.initialize !== 'undefined') {
644 module.initialize.call(_this);
645 }
646 });
647
648 this.position();
649 }
650
651 _createClass(TetherClass, [{
652 key: 'getClass',
653 value: function getClass() {
654 var key = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
655 var classes = this.options.classes;
656
657 if (typeof classes !== 'undefined' && classes[key]) {
658 return this.options.classes[key];
659 } else if (this.options.classPrefix) {
660 return this.options.classPrefix + '-' + key;
661 } else {
662 return key;
663 }
664 }
665 }, {
666 key: 'setOptions',
667 value: function setOptions(options) {
668 var _this2 = this;
669
670 var pos = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
671
672 var defaults = {
673 offset: '0 0',
674 targetOffset: '0 0',
675 targetAttachment: 'auto auto',
676 classPrefix: 'tether'
677 };
678
679 this.options = extend(defaults, options);
680
681 var _options = this.options;
682 var element = _options.element;
683 var target = _options.target;
684 var targetModifier = _options.targetModifier;
685
686 this.element = element;
687 this.target = target;
688 this.targetModifier = targetModifier;
689
690 if (this.target === 'viewport') {
691 this.target = document.body;
692 this.targetModifier = 'visible';
693 } else if (this.target === 'scroll-handle') {
694 this.target = document.body;
695 this.targetModifier = 'scroll-handle';
696 }
697
698 ['element', 'target'].forEach(function (key) {
699 if (typeof _this2[key] === 'undefined') {
700 throw new Error('Tether Error: Both element and target must be defined');
701 }
702
703 if (typeof _this2[key].jquery !== 'undefined') {
704 _this2[key] = _this2[key][0];
705 } else if (typeof _this2[key] === 'string') {
706 _this2[key] = document.querySelector(_this2[key]);
707 }
708 });
709
710 addClass(this.element, this.getClass('element'));
711 if (!(this.options.addTargetClasses === false)) {
712 addClass(this.target, this.getClass('target'));
713 }
714
715 if (!this.options.attachment) {
716 throw new Error('Tether Error: You must provide an attachment');
717 }
718
719 this.targetAttachment = parseAttachment(this.options.targetAttachment);
720 this.attachment = parseAttachment(this.options.attachment);
721 this.offset = parseOffset(this.options.offset);
722 this.targetOffset = parseOffset(this.options.targetOffset);
723
724 if (typeof this.scrollParents !== 'undefined') {
725 this.disable();
726 }
727
728 if (this.targetModifier === 'scroll-handle') {
729 this.scrollParents = [this.target];
730 } else {
731 this.scrollParents = getScrollParents(this.target);
732 }
733
734 if (!(this.options.enabled === false)) {
735 this.enable(pos);
736 }
737 }
738 }, {
739 key: 'getTargetBounds',
740 value: function getTargetBounds() {
741 if (typeof this.targetModifier !== 'undefined') {
742 if (this.targetModifier === 'visible') {
743 if (this.target === document.body) {
744 return { top: pageYOffset, left: pageXOffset, height: innerHeight, width: innerWidth };
745 } else {
746 var bounds = getBounds(this.target);
747
748 var out = {
749 height: bounds.height,
750 width: bounds.width,
751 top: bounds.top,
752 left: bounds.left
753 };
754
755 out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top));
756 out.height = Math.min(out.height, bounds.height - (bounds.top + bounds.height - (pageYOffset + innerHeight)));
757 out.height = Math.min(innerHeight, out.height);
758 out.height -= 2;
759
760 out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left));
761 out.width = Math.min(out.width, bounds.width - (bounds.left + bounds.width - (pageXOffset + innerWidth)));
762 out.width = Math.min(innerWidth, out.width);
763 out.width -= 2;
764
765 if (out.top < pageYOffset) {
766 out.top = pageYOffset;
767 }
768 if (out.left < pageXOffset) {
769 out.left = pageXOffset;
770 }
771
772 return out;
773 }
774 } else if (this.targetModifier === 'scroll-handle') {
775 var bounds = undefined;
776 var target = this.target;
777 if (target === document.body) {
778 target = document.documentElement;
779
780 bounds = {
781 left: pageXOffset,
782 top: pageYOffset,
783 height: innerHeight,
784 width: innerWidth
785 };
786 } else {
787 bounds = getBounds(target);
788 }
789
790 var style = getComputedStyle(target);
791
792 var hasBottomScroll = target.scrollWidth > target.clientWidth || [style.overflow, style.overflowX].indexOf('scroll') >= 0 || this.target !== document.body;
793
794 var scrollBottom = 0;
795 if (hasBottomScroll) {
796 scrollBottom = 15;
797 }
798
799 var height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom;
800
801 var out = {
802 width: 15,
803 height: height * 0.975 * (height / target.scrollHeight),
804 left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15
805 };
806
807 var fitAdj = 0;
808 if (height < 408 && this.target === document.body) {
809 fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58;
810 }
811
812 if (this.target !== document.body) {
813 out.height = Math.max(out.height, 24);
814 }
815
816 var scrollPercentage = this.target.scrollTop / (target.scrollHeight - height);
817 out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth);
818
819 if (this.target === document.body) {
820 out.height = Math.max(out.height, 24);
821 }
822
823 return out;
824 }
825 } else {
826 return getBounds(this.target);
827 }
828 }
829 }, {
830 key: 'clearCache',
831 value: function clearCache() {
832 this._cache = {};
833 }
834 }, {
835 key: 'cache',
836 value: function cache(k, getter) {
837 // More than one module will often need the same DOM info, so
838 // we keep a cache which is cleared on each position call
839 if (typeof this._cache === 'undefined') {
840 this._cache = {};
841 }
842
843 if (typeof this._cache[k] === 'undefined') {
844 this._cache[k] = getter.call(this);
845 }
846
847 return this._cache[k];
848 }
849 }, {
850 key: 'enable',
851 value: function enable() {
852 var _this3 = this;
853
854 var pos = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
855
856 if (!(this.options.addTargetClasses === false)) {
857 addClass(this.target, this.getClass('enabled'));
858 }
859 addClass(this.element, this.getClass('enabled'));
860 this.enabled = true;
861
862 this.scrollParents.forEach(function (parent) {
863 if (parent !== _this3.target.ownerDocument) {
864 parent.addEventListener('scroll', _this3.position);
865 }
866 });
867
868 if (pos) {
869 this.position();
870 }
871 }
872 }, {
873 key: 'disable',
874 value: function disable() {
875 var _this4 = this;
876
877 removeClass(this.target, this.getClass('enabled'));
878 removeClass(this.element, this.getClass('enabled'));
879 this.enabled = false;
880
881 if (typeof this.scrollParents !== 'undefined') {
882 this.scrollParents.forEach(function (parent) {
883 parent.removeEventListener('scroll', _this4.position);
884 });
885 }
886 }
887 }, {
888 key: 'destroy',
889 value: function destroy() {
890 var _this5 = this;
891
892 this.disable();
893
894 tethers.forEach(function (tether, i) {
895 if (tether === _this5) {
896 tethers.splice(i, 1);
897 }
898 });
899
900 // Remove any elements we were using for convenience from the DOM
901 if (tethers.length === 0) {
902 removeUtilElements();
903 }
904 }
905 }, {
906 key: 'updateAttachClasses',
907 value: function updateAttachClasses(elementAttach, targetAttach) {
908 var _this6 = this;
909
910 elementAttach = elementAttach || this.attachment;
911 targetAttach = targetAttach || this.targetAttachment;
912 var sides = ['left', 'top', 'bottom', 'right', 'middle', 'center'];
913
914 if (typeof this._addAttachClasses !== 'undefined' && this._addAttachClasses.length) {
915 // updateAttachClasses can be called more than once in a position call, so
916 // we need to clean up after ourselves such that when the last defer gets
917 // ran it doesn't add any extra classes from previous calls.
918 this._addAttachClasses.splice(0, this._addAttachClasses.length);
919 }
920
921 if (typeof this._addAttachClasses === 'undefined') {
922 this._addAttachClasses = [];
923 }
924 var add = this._addAttachClasses;
925
926 if (elementAttach.top) {
927 add.push(this.getClass('element-attached') + '-' + elementAttach.top);
928 }
929 if (elementAttach.left) {
930 add.push(this.getClass('element-attached') + '-' + elementAttach.left);
931 }
932 if (targetAttach.top) {
933 add.push(this.getClass('target-attached') + '-' + targetAttach.top);
934 }
935 if (targetAttach.left) {
936 add.push(this.getClass('target-attached') + '-' + targetAttach.left);
937 }
938
939 var all = [];
940 sides.forEach(function (side) {
941 all.push(_this6.getClass('element-attached') + '-' + side);
942 all.push(_this6.getClass('target-attached') + '-' + side);
943 });
944
945 defer(function () {
946 if (!(typeof _this6._addAttachClasses !== 'undefined')) {
947 return;
948 }
949
950 updateClasses(_this6.element, _this6._addAttachClasses, all);
951 if (!(_this6.options.addTargetClasses === false)) {
952 updateClasses(_this6.target, _this6._addAttachClasses, all);
953 }
954
955 delete _this6._addAttachClasses;
956 });
957 }
958 }, {
959 key: 'position',
960 value: function position() {
961 var _this7 = this;
962
963 var flushChanges = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
964
965 // flushChanges commits the changes immediately, leave true unless you are positioning multiple
966 // tethers (in which case call Tether.Utils.flush yourself when you're done)
967
968 if (!this.enabled) {
969 return;
970 }
971
972 this.clearCache();
973
974 // Turn 'auto' attachments into the appropriate corner or edge
975 var targetAttachment = autoToFixedAttachment(this.targetAttachment, this.attachment);
976
977 this.updateAttachClasses(this.attachment, targetAttachment);
978
979 var elementPos = this.cache('element-bounds', function () {
980 return getBounds(_this7.element);
981 });
982
983 var width = elementPos.width;
984 var height = elementPos.height;
985
986 if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {
987 var _lastSize = this.lastSize;
988
989 // We cache the height and width to make it possible to position elements that are
990 // getting hidden.
991 width = _lastSize.width;
992 height = _lastSize.height;
993 } else {
994 this.lastSize = { width: width, height: height };
995 }
996
997 var targetPos = this.cache('target-bounds', function () {
998 return _this7.getTargetBounds();
999 });
1000 var targetSize = targetPos;
1001
1002 // Get an actual px offset from the attachment
1003 var offset = offsetToPx(attachmentToOffset(this.attachment), { width: width, height: height });
1004 var targetOffset = offsetToPx(attachmentToOffset(targetAttachment), targetSize);
1005
1006 var manualOffset = offsetToPx(this.offset, { width: width, height: height });
1007 var manualTargetOffset = offsetToPx(this.targetOffset, targetSize);
1008
1009 // Add the manually provided offset
1010 offset = addOffset(offset, manualOffset);
1011 targetOffset = addOffset(targetOffset, manualTargetOffset);
1012
1013 // It's now our goal to make (element position + offset) == (target position + target offset)
1014 var left = targetPos.left + targetOffset.left - offset.left;
1015 var top = targetPos.top + targetOffset.top - offset.top;
1016
1017 for (var i = 0; i < TetherBase.modules.length; ++i) {
1018 var _module2 = TetherBase.modules[i];
1019 var ret = _module2.position.call(this, {
1020 left: left,
1021 top: top,
1022 targetAttachment: targetAttachment,
1023 targetPos: targetPos,
1024 elementPos: elementPos,
1025 offset: offset,
1026 targetOffset: targetOffset,
1027 manualOffset: manualOffset,
1028 manualTargetOffset: manualTargetOffset,
1029 scrollbarSize: scrollbarSize,
1030 attachment: this.attachment
1031 });
1032
1033 if (ret === false) {
1034 return false;
1035 } else if (typeof ret === 'undefined' || typeof ret !== 'object') {
1036 continue;
1037 } else {
1038 top = ret.top;
1039 left = ret.left;
1040 }
1041 }
1042
1043 // We describe the position three different ways to give the optimizer
1044 // a chance to decide the best possible way to position the element
1045 // with the fewest repaints.
1046 var next = {
1047 // It's position relative to the page (absolute positioning when
1048 // the element is a child of the body)
1049 page: {
1050 top: top,
1051 left: left
1052 },
1053
1054 // It's position relative to the viewport (fixed positioning)
1055 viewport: {
1056 top: top - pageYOffset,
1057 bottom: pageYOffset - top - height + innerHeight,
1058 left: left - pageXOffset,
1059 right: pageXOffset - left - width + innerWidth
1060 }
1061 };
1062
1063 var doc = this.target.ownerDocument;
1064 var win = doc.defaultView;
1065
1066 var scrollbarSize = undefined;
1067 if (win.innerHeight > doc.documentElement.clientHeight) {
1068 scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
1069 next.viewport.bottom -= scrollbarSize.height;
1070 }
1071
1072 if (win.innerWidth > doc.documentElement.clientWidth) {
1073 scrollbarSize = this.cache('scrollbar-size', getScrollBarSize);
1074 next.viewport.right -= scrollbarSize.width;
1075 }
1076
1077 if (['', 'static'].indexOf(doc.body.style.position) === -1 || ['', 'static'].indexOf(doc.body.parentElement.style.position) === -1) {
1078 // Absolute positioning in the body will be relative to the page, not the 'initial containing block'
1079 next.page.bottom = doc.body.scrollHeight - top - height;
1080 next.page.right = doc.body.scrollWidth - left - width;
1081 }
1082
1083 if (typeof this.options.optimizations !== 'undefined' && this.options.optimizations.moveElement !== false && !(typeof this.targetModifier !== 'undefined')) {
1084 (function () {
1085 var offsetParent = _this7.cache('target-offsetparent', function () {
1086 return getOffsetParent(_this7.target);
1087 });
1088 var offsetPosition = _this7.cache('target-offsetparent-bounds', function () {
1089 return getBounds(offsetParent);
1090 });
1091 var offsetParentStyle = getComputedStyle(offsetParent);
1092 var offsetParentSize = offsetPosition;
1093
1094 var offsetBorder = {};
1095 ['Top', 'Left', 'Bottom', 'Right'].forEach(function (side) {
1096 offsetBorder[side.toLowerCase()] = parseFloat(offsetParentStyle['border' + side + 'Width']);
1097 });
1098
1099 offsetPosition.right = doc.body.scrollWidth - offsetPosition.left - offsetParentSize.width + offsetBorder.right;
1100 offsetPosition.bottom = doc.body.scrollHeight - offsetPosition.top - offsetParentSize.height + offsetBorder.bottom;
1101
1102 if (next.page.top >= offsetPosition.top + offsetBorder.top && next.page.bottom >= offsetPosition.bottom) {
1103 if (next.page.left >= offsetPosition.left + offsetBorder.left && next.page.right >= offsetPosition.right) {
1104 // We're within the visible part of the target's scroll parent
1105 var scrollTop = offsetParent.scrollTop;
1106 var scrollLeft = offsetParent.scrollLeft;
1107
1108 // It's position relative to the target's offset parent (absolute positioning when
1109 // the element is moved to be a child of the target's offset parent).
1110 next.offset = {
1111 top: next.page.top - offsetPosition.top + scrollTop - offsetBorder.top,
1112 left: next.page.left - offsetPosition.left + scrollLeft - offsetBorder.left
1113 };
1114 }
1115 }
1116 })();
1117 }
1118
1119 // We could also travel up the DOM and try each containing context, rather than only
1120 // looking at the body, but we're gonna get diminishing returns.
1121
1122 this.move(next);
1123
1124 this.history.unshift(next);
1125
1126 if (this.history.length > 3) {
1127 this.history.pop();
1128 }
1129
1130 if (flushChanges) {
1131 flush();
1132 }
1133
1134 return true;
1135 }
1136
1137 // THE ISSUE
1138 }, {
1139 key: 'move',
1140 value: function move(pos) {
1141 var _this8 = this;
1142
1143 if (!(typeof this.element.parentNode !== 'undefined')) {
1144 return;
1145 }
1146
1147 var same = {};
1148
1149 for (var type in pos) {
1150 same[type] = {};
1151
1152 for (var key in pos[type]) {
1153 var found = false;
1154
1155 for (var i = 0; i < this.history.length; ++i) {
1156 var point = this.history[i];
1157 if (typeof point[type] !== 'undefined' && !within(point[type][key], pos[type][key])) {
1158 found = true;
1159 break;
1160 }
1161 }
1162
1163 if (!found) {
1164 same[type][key] = true;
1165 }
1166 }
1167 }
1168
1169 var css = { top: '', left: '', right: '', bottom: '' };
1170
1171 var transcribe = function transcribe(_same, _pos) {
1172 var hasOptimizations = typeof _this8.options.optimizations !== 'undefined';
1173 var gpu = hasOptimizations ? _this8.options.optimizations.gpu : null;
1174 if (gpu !== false) {
1175 var yPos = undefined,
1176 xPos = undefined;
1177 if (_same.top) {
1178 css.top = 0;
1179 yPos = _pos.top;
1180 } else {
1181 css.bottom = 0;
1182 yPos = -_pos.bottom;
1183 }
1184
1185 if (_same.left) {
1186 css.left = 0;
1187 xPos = _pos.left;
1188 } else {
1189 css.right = 0;
1190 xPos = -_pos.right;
1191 }
1192
1193 if (typeof window.devicePixelRatio === 'number' && devicePixelRatio % 1 === 0) {
1194 xPos = Math.round(xPos * devicePixelRatio) / devicePixelRatio;
1195 yPos = Math.round(yPos * devicePixelRatio) / devicePixelRatio;
1196 }
1197
1198 css[transformKey] = 'translateX(' + xPos + 'px) translateY(' + yPos + 'px)';
1199
1200 if (transformKey !== 'msTransform') {
1201 // The Z transform will keep this in the GPU (faster, and prevents artifacts),
1202 // but IE9 doesn't support 3d transforms and will choke.
1203 css[transformKey] += " translateZ(0)";
1204 }
1205 } else {
1206 if (_same.top) {
1207 css.top = _pos.top + 'px';
1208 } else {
1209 css.bottom = _pos.bottom + 'px';
1210 }
1211
1212 if (_same.left) {
1213 css.left = _pos.left + 'px';
1214 } else {
1215 css.right = _pos.right + 'px';
1216 }
1217 }
1218 };
1219
1220 var moved = false;
1221 if ((same.page.top || same.page.bottom) && (same.page.left || same.page.right)) {
1222 css.position = 'absolute';
1223 transcribe(same.page, pos.page);
1224 } else if ((same.viewport.top || same.viewport.bottom) && (same.viewport.left || same.viewport.right)) {
1225 css.position = 'fixed';
1226 transcribe(same.viewport, pos.viewport);
1227 } else if (typeof same.offset !== 'undefined' && same.offset.top && same.offset.left) {
1228 (function () {
1229 css.position = 'absolute';
1230 var offsetParent = _this8.cache('target-offsetparent', function () {
1231 return getOffsetParent(_this8.target);
1232 });
1233
1234 if (getOffsetParent(_this8.element) !== offsetParent) {
1235 defer(function () {
1236 _this8.element.parentNode.removeChild(_this8.element);
1237 offsetParent.appendChild(_this8.element);
1238 });
1239 }
1240
1241 transcribe(same.offset, pos.offset);
1242 moved = true;
1243 })();
1244 } else {
1245 css.position = 'absolute';
1246 transcribe({ top: true, left: true }, pos.page);
1247 }
1248
1249 if (!moved) {
1250 if (this.options.bodyElement) {
1251 if (this.element.parentNode !== this.options.bodyElement) {
1252 this.options.bodyElement.appendChild(this.element);
1253 }
1254 } else {
1255 var isFullscreenElement = function isFullscreenElement(e) {
1256 var d = e.ownerDocument;
1257 var fe = d.fullscreenElement || d.webkitFullscreenElement || d.mozFullScreenElement || d.msFullscreenElement;
1258 return fe === e;
1259 };
1260
1261 var offsetParentIsBody = true;
1262
1263 var currentNode = this.element.parentNode;
1264 while (currentNode && currentNode.nodeType === 1 && currentNode.tagName !== 'BODY' && !isFullscreenElement(currentNode)) {
1265 if (getComputedStyle(currentNode).position !== 'static') {
1266 offsetParentIsBody = false;
1267 break;
1268 }
1269
1270 currentNode = currentNode.parentNode;
1271 }
1272
1273 if (!offsetParentIsBody) {
1274 this.element.parentNode.removeChild(this.element);
1275 this.element.ownerDocument.body.appendChild(this.element);
1276 }
1277 }
1278 }
1279
1280 // Any css change will trigger a repaint, so let's avoid one if nothing changed
1281 var writeCSS = {};
1282 var write = false;
1283 for (var key in css) {
1284 var val = css[key];
1285 var elVal = this.element.style[key];
1286
1287 if (elVal !== val) {
1288 write = true;
1289 writeCSS[key] = val;
1290 }
1291 }
1292
1293 if (write) {
1294 defer(function () {
1295 extend(_this8.element.style, writeCSS);
1296 _this8.trigger('repositioned');
1297 });
1298 }
1299 }
1300 }]);
1301
1302 return TetherClass;
1303 })(Evented);
1304
1305 TetherClass.modules = [];
1306
1307 TetherBase.position = position;
1308
1309 var Tether = extend(TetherClass, TetherBase);
1310 /* globals TetherBase */
1311
1312 'use strict';
1313
1314 var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
1315
1316 var _TetherBase$Utils = TetherBase.Utils;
1317 var getBounds = _TetherBase$Utils.getBounds;
1318 var extend = _TetherBase$Utils.extend;
1319 var updateClasses = _TetherBase$Utils.updateClasses;
1320 var defer = _TetherBase$Utils.defer;
1321
1322 var BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom'];
1323
1324 function getBoundingRect(tether, to) {
1325 if (to === 'scrollParent') {
1326 to = tether.scrollParents[0];
1327 } else if (to === 'window') {
1328 to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset];
1329 }
1330
1331 if (to === document) {
1332 to = to.documentElement;
1333 }
1334
1335 if (typeof to.nodeType !== 'undefined') {
1336 (function () {
1337 var node = to;
1338 var size = getBounds(to);
1339 var pos = size;
1340 var style = getComputedStyle(to);
1341
1342 to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top];
1343
1344 // Account any parent Frames scroll offset
1345 if (node.ownerDocument !== document) {
1346 var win = node.ownerDocument.defaultView;
1347 to[0] += win.pageXOffset;
1348 to[1] += win.pageYOffset;
1349 to[2] += win.pageXOffset;
1350 to[3] += win.pageYOffset;
1351 }
1352
1353 BOUNDS_FORMAT.forEach(function (side, i) {
1354 side = side[0].toUpperCase() + side.substr(1);
1355 if (side === 'Top' || side === 'Left') {
1356 to[i] += parseFloat(style['border' + side + 'Width']);
1357 } else {
1358 to[i] -= parseFloat(style['border' + side + 'Width']);
1359 }
1360 });
1361 })();
1362 }
1363
1364 return to;
1365 }
1366
1367 TetherBase.modules.push({
1368 position: function position(_ref) {
1369 var _this = this;
1370
1371 var top = _ref.top;
1372 var left = _ref.left;
1373 var targetAttachment = _ref.targetAttachment;
1374
1375 if (!this.options.constraints) {
1376 return true;
1377 }
1378
1379 var _cache = this.cache('element-bounds', function () {
1380 return getBounds(_this.element);
1381 });
1382
1383 var height = _cache.height;
1384 var width = _cache.width;
1385
1386 if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') {
1387 var _lastSize = this.lastSize;
1388
1389 // Handle the item getting hidden as a result of our positioning without glitching
1390 // the classes in and out
1391 width = _lastSize.width;
1392 height = _lastSize.height;
1393 }
1394
1395 var targetSize = this.cache('target-bounds', function () {
1396 return _this.getTargetBounds();
1397 });
1398
1399 var targetHeight = targetSize.height;
1400 var targetWidth = targetSize.width;
1401
1402 var allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')];
1403
1404 this.options.constraints.forEach(function (constraint) {
1405 var outOfBoundsClass = constraint.outOfBoundsClass;
1406 var pinnedClass = constraint.pinnedClass;
1407
1408 if (outOfBoundsClass) {
1409 allClasses.push(outOfBoundsClass);
1410 }
1411 if (pinnedClass) {
1412 allClasses.push(pinnedClass);
1413 }
1414 });
1415
1416 allClasses.forEach(function (cls) {
1417 ['left', 'top', 'right', 'bottom'].forEach(function (side) {
1418 allClasses.push(cls + '-' + side);
1419 });
1420 });
1421
1422 var addClasses = [];
1423
1424 var tAttachment = extend({}, targetAttachment);
1425 var eAttachment = extend({}, this.attachment);
1426
1427 this.options.constraints.forEach(function (constraint) {
1428 var to = constraint.to;
1429 var attachment = constraint.attachment;
1430 var pin = constraint.pin;
1431
1432 if (typeof attachment === 'undefined') {
1433 attachment = '';
1434 }
1435
1436 var changeAttachX = undefined,
1437 changeAttachY = undefined;
1438 if (attachment.indexOf(' ') >= 0) {
1439 var _attachment$split = attachment.split(' ');
1440
1441 var _attachment$split2 = _slicedToArray(_attachment$split, 2);
1442
1443 changeAttachY = _attachment$split2[0];
1444 changeAttachX = _attachment$split2[1];
1445 } else {
1446 changeAttachX = changeAttachY = attachment;
1447 }
1448
1449 var bounds = getBoundingRect(_this, to);
1450
1451 if (changeAttachY === 'target' || changeAttachY === 'both') {
1452 if (top < bounds[1] && tAttachment.top === 'top') {
1453 top += targetHeight;
1454 tAttachment.top = 'bottom';
1455 }
1456
1457 if (top + height > bounds[3] && tAttachment.top === 'bottom') {
1458 top -= targetHeight;
1459 tAttachment.top = 'top';
1460 }
1461 }
1462
1463 if (changeAttachY === 'together') {
1464 if (tAttachment.top === 'top') {
1465 if (eAttachment.top === 'bottom' && top < bounds[1]) {
1466 top += targetHeight;
1467 tAttachment.top = 'bottom';
1468
1469 top += height;
1470 eAttachment.top = 'top';
1471 } else if (eAttachment.top === 'top' && top + height > bounds[3] && top - (height - targetHeight) >= bounds[1]) {
1472 top -= height - targetHeight;
1473 tAttachment.top = 'bottom';
1474
1475 eAttachment.top = 'bottom';
1476 }
1477 }
1478
1479 if (tAttachment.top === 'bottom') {
1480 if (eAttachment.top === 'top' && top + height > bounds[3]) {
1481 top -= targetHeight;
1482 tAttachment.top = 'top';
1483
1484 top -= height;
1485 eAttachment.top = 'bottom';
1486 } else if (eAttachment.top === 'bottom' && top < bounds[1] && top + (height * 2 - targetHeight) <= bounds[3]) {
1487 top += height - targetHeight;
1488 tAttachment.top = 'top';
1489
1490 eAttachment.top = 'top';
1491 }
1492 }
1493
1494 if (tAttachment.top === 'middle') {
1495 if (top + height > bounds[3] && eAttachment.top === 'top') {
1496 top -= height;
1497 eAttachment.top = 'bottom';
1498 } else if (top < bounds[1] && eAttachment.top === 'bottom') {
1499 top += height;
1500 eAttachment.top = 'top';
1501 }
1502 }
1503 }
1504
1505 if (changeAttachX === 'target' || changeAttachX === 'both') {
1506 if (left < bounds[0] && tAttachment.left === 'left') {
1507 left += targetWidth;
1508 tAttachment.left = 'right';
1509 }
1510
1511 if (left + width > bounds[2] && tAttachment.left === 'right') {
1512 left -= targetWidth;
1513 tAttachment.left = 'left';
1514 }
1515 }
1516
1517 if (changeAttachX === 'together') {
1518 if (left < bounds[0] && tAttachment.left === 'left') {
1519 if (eAttachment.left === 'right') {
1520 left += targetWidth;
1521 tAttachment.left = 'right';
1522
1523 left += width;
1524 eAttachment.left = 'left';
1525 } else if (eAttachment.left === 'left') {
1526 left += targetWidth;
1527 tAttachment.left = 'right';
1528
1529 left -= width;
1530 eAttachment.left = 'right';
1531 }
1532 } else if (left + width > bounds[2] && tAttachment.left === 'right') {
1533 if (eAttachment.left === 'left') {
1534 left -= targetWidth;
1535 tAttachment.left = 'left';
1536
1537 left -= width;
1538 eAttachment.left = 'right';
1539 } else if (eAttachment.left === 'right') {
1540 left -= targetWidth;
1541 tAttachment.left = 'left';
1542
1543 left += width;
1544 eAttachment.left = 'left';
1545 }
1546 } else if (tAttachment.left === 'center') {
1547 if (left + width > bounds[2] && eAttachment.left === 'left') {
1548 left -= width;
1549 eAttachment.left = 'right';
1550 } else if (left < bounds[0] && eAttachment.left === 'right') {
1551 left += width;
1552 eAttachment.left = 'left';
1553 }
1554 }
1555 }
1556
1557 if (changeAttachY === 'element' || changeAttachY === 'both') {
1558 if (top < bounds[1] && eAttachment.top === 'bottom') {
1559 top += height;
1560 eAttachment.top = 'top';
1561 }
1562
1563 if (top + height > bounds[3] && eAttachment.top === 'top') {
1564 top -= height;
1565 eAttachment.top = 'bottom';
1566 }
1567 }
1568
1569 if (changeAttachX === 'element' || changeAttachX === 'both') {
1570 if (left < bounds[0]) {
1571 if (eAttachment.left === 'right') {
1572 left += width;
1573 eAttachment.left = 'left';
1574 } else if (eAttachment.left === 'center') {
1575 left += width / 2;
1576 eAttachment.left = 'left';
1577 }
1578 }
1579
1580 if (left + width > bounds[2]) {
1581 if (eAttachment.left === 'left') {
1582 left -= width;
1583 eAttachment.left = 'right';
1584 } else if (eAttachment.left === 'center') {
1585 left -= width / 2;
1586 eAttachment.left = 'right';
1587 }
1588 }
1589 }
1590
1591 if (typeof pin === 'string') {
1592 pin = pin.split(',').map(function (p) {
1593 return p.trim();
1594 });
1595 } else if (pin === true) {
1596 pin = ['top', 'left', 'right', 'bottom'];
1597 }
1598
1599 pin = pin || [];
1600
1601 var pinned = [];
1602 var oob = [];
1603
1604 if (top < bounds[1]) {
1605 if (pin.indexOf('top') >= 0) {
1606 top = bounds[1];
1607 pinned.push('top');
1608 } else {
1609 oob.push('top');
1610 }
1611 }
1612
1613 if (top + height > bounds[3]) {
1614 if (pin.indexOf('bottom') >= 0) {
1615 top = bounds[3] - height;
1616 pinned.push('bottom');
1617 } else {
1618 oob.push('bottom');
1619 }
1620 }
1621
1622 if (left < bounds[0]) {
1623 if (pin.indexOf('left') >= 0) {
1624 left = bounds[0];
1625 pinned.push('left');
1626 } else {
1627 oob.push('left');
1628 }
1629 }
1630
1631 if (left + width > bounds[2]) {
1632 if (pin.indexOf('right') >= 0) {
1633 left = bounds[2] - width;
1634 pinned.push('right');
1635 } else {
1636 oob.push('right');
1637 }
1638 }
1639
1640 if (pinned.length) {
1641 (function () {
1642 var pinnedClass = undefined;
1643 if (typeof _this.options.pinnedClass !== 'undefined') {
1644 pinnedClass = _this.options.pinnedClass;
1645 } else {
1646 pinnedClass = _this.getClass('pinned');
1647 }
1648
1649 addClasses.push(pinnedClass);
1650 pinned.forEach(function (side) {
1651 addClasses.push(pinnedClass + '-' + side);
1652 });
1653 })();
1654 }
1655
1656 if (oob.length) {
1657 (function () {
1658 var oobClass = undefined;
1659 if (typeof _this.options.outOfBoundsClass !== 'undefined') {
1660 oobClass = _this.options.outOfBoundsClass;
1661 } else {
1662 oobClass = _this.getClass('out-of-bounds');
1663 }
1664
1665 addClasses.push(oobClass);
1666 oob.forEach(function (side) {
1667 addClasses.push(oobClass + '-' + side);
1668 });
1669 })();
1670 }
1671
1672 if (pinned.indexOf('left') >= 0 || pinned.indexOf('right') >= 0) {
1673 eAttachment.left = tAttachment.left = false;
1674 }
1675 if (pinned.indexOf('top') >= 0 || pinned.indexOf('bottom') >= 0) {
1676 eAttachment.top = tAttachment.top = false;
1677 }
1678
1679 if (tAttachment.top !== targetAttachment.top || tAttachment.left !== targetAttachment.left || eAttachment.top !== _this.attachment.top || eAttachment.left !== _this.attachment.left) {
1680 _this.updateAttachClasses(eAttachment, tAttachment);
1681 _this.trigger('update', {
1682 attachment: eAttachment,
1683 targetAttachment: tAttachment
1684 });
1685 }
1686 });
1687
1688 defer(function () {
1689 if (!(_this.options.addTargetClasses === false)) {
1690 updateClasses(_this.target, addClasses, allClasses);
1691 }
1692 updateClasses(_this.element, addClasses, allClasses);
1693 });
1694
1695 return { top: top, left: left };
1696 }
1697 });
1698 /* globals TetherBase */
1699
1700 'use strict';
1701
1702 var _TetherBase$Utils = TetherBase.Utils;
1703 var getBounds = _TetherBase$Utils.getBounds;
1704 var updateClasses = _TetherBase$Utils.updateClasses;
1705 var defer = _TetherBase$Utils.defer;
1706
1707 TetherBase.modules.push({
1708 position: function position(_ref) {
1709 var _this = this;
1710
1711 var top = _ref.top;
1712 var left = _ref.left;
1713
1714 var _cache = this.cache('element-bounds', function () {
1715 return getBounds(_this.element);
1716 });
1717
1718 var height = _cache.height;
1719 var width = _cache.width;
1720
1721 var targetPos = this.getTargetBounds();
1722
1723 var bottom = top + height;
1724 var right = left + width;
1725
1726 var abutted = [];
1727 if (top <= targetPos.bottom && bottom >= targetPos.top) {
1728 ['left', 'right'].forEach(function (side) {
1729 var targetPosSide = targetPos[side];
1730 if (targetPosSide === left || targetPosSide === right) {
1731 abutted.push(side);
1732 }
1733 });
1734 }
1735
1736 if (left <= targetPos.right && right >= targetPos.left) {
1737 ['top', 'bottom'].forEach(function (side) {
1738 var targetPosSide = targetPos[side];
1739 if (targetPosSide === top || targetPosSide === bottom) {
1740 abutted.push(side);
1741 }
1742 });
1743 }
1744
1745 var allClasses = [];
1746 var addClasses = [];
1747
1748 var sides = ['left', 'top', 'right', 'bottom'];
1749 allClasses.push(this.getClass('abutted'));
1750 sides.forEach(function (side) {
1751 allClasses.push(_this.getClass('abutted') + '-' + side);
1752 });
1753
1754 if (abutted.length) {
1755 addClasses.push(this.getClass('abutted'));
1756 }
1757
1758 abutted.forEach(function (side) {
1759 addClasses.push(_this.getClass('abutted') + '-' + side);
1760 });
1761
1762 defer(function () {
1763 if (!(_this.options.addTargetClasses === false)) {
1764 updateClasses(_this.target, addClasses, allClasses);
1765 }
1766 updateClasses(_this.element, addClasses, allClasses);
1767 });
1768
1769 return true;
1770 }
1771 });
1772 /* globals TetherBase */
1773
1774 'use strict';
1775
1776 var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
1777
1778 TetherBase.modules.push({
1779 position: function position(_ref) {
1780 var top = _ref.top;
1781 var left = _ref.left;
1782
1783 if (!this.options.shift) {
1784 return;
1785 }
1786
1787 var shift = this.options.shift;
1788 if (typeof this.options.shift === 'function') {
1789 shift = this.options.shift.call(this, { top: top, left: left });
1790 }
1791
1792 var shiftTop = undefined,
1793 shiftLeft = undefined;
1794 if (typeof shift === 'string') {
1795 shift = shift.split(' ');
1796 shift[1] = shift[1] || shift[0];
1797
1798 var _shift = shift;
1799
1800 var _shift2 = _slicedToArray(_shift, 2);
1801
1802 shiftTop = _shift2[0];
1803 shiftLeft = _shift2[1];
1804
1805 shiftTop = parseFloat(shiftTop, 10);
1806 shiftLeft = parseFloat(shiftLeft, 10);
1807 } else {
1808 shiftTop = shift.top;
1809 shiftLeft = shift.left;
1810 }
1811
1812 top += shiftTop;
1813 left += shiftLeft;
1814
1815 return { top: top, left: left };
1816 }
1817 });
1818 return Tether;
1819
1820 }));
1821