{"version":3,"file":"tether.min.js","sources":["../../src/js/utils/type-check.js","../../src/js/utils/classes.js","../../src/js/utils/deferred.js","../../src/js/utils/general.js","../../src/js/utils/bounds.js","../../src/js/abutment.js","../../src/js/constraint.js","../../src/js/shift.js","../../src/js/evented.js","../../src/js/utils/offset.js","../../src/js/utils/parents.js","../../src/js/tether.js"],"sourcesContent":["/**\n * Checks if `value` is classified as a `Function` object.\n * @param {*} value The param to check if it is a function\n */\nexport function isFunction(value) {\n return typeof value === 'function';\n}\n\n/**\n * Checks if `value` is classified as a `Number` object.\n * @param {*} value The param to check if it is a number\n */\nexport function isNumber(value) {\n return typeof value === 'number';\n}\n\n/**\n * Checks if `value` is classified as an `Object`.\n * @param {*} value The param to check if it is an object\n */\nexport function isObject(value) {\n return typeof value === 'object';\n}\n\n/**\n * Checks if `value` is classified as a `String` object.\n * @param {*} value The param to check if it is a string\n */\nexport function isString(value) {\n return typeof value === 'string';\n}\n\n/**\n * Checks if `value` is undefined.\n * @param {*} value The param to check if it is undefined\n */\nexport function isUndefined(value) {\n return value === undefined;\n}\n","import { isUndefined } from './type-check';\n\nexport function addClass(el, name) {\n name.split(' ').forEach((cls) => {\n if (cls.trim()) {\n el.classList.add(cls);\n }\n });\n}\n\n/**\n * Get class string based on previously determined classes\n * @param {String} [key=''] - default value for the classes object\n * @param {Object} classes\n * @param {String} classPrefix\n */\nexport function getClass(key = '', classes, classPrefix) {\n if (!isUndefined(classes) && !isUndefined(classes[key])) {\n if (classes[key] === false) {\n return '';\n }\n return classes[key];\n } else if (classPrefix) {\n return `${classPrefix}-${key}`;\n } else {\n return key;\n }\n}\n\nexport function removeClass(el, name) {\n name.split(' ').forEach((cls) => {\n if (cls.trim()) {\n el.classList.remove(cls);\n }\n });\n}\n\nexport function updateClasses(el, add, all) {\n // Of the set of 'all' classes, we need the 'add' classes, and only the\n // 'add' classes to be set.\n all.forEach((cls) => {\n if (add.indexOf(cls) === -1 && el.classList.contains(cls)) {\n removeClass(el, cls);\n }\n });\n\n add.forEach((cls) => {\n if (!el.classList.contains(cls)) {\n addClass(el, cls);\n }\n });\n}\n","const deferred = [];\n\nexport function defer(fn) {\n deferred.push(fn);\n}\n\nexport function flush() {\n let fn;\n // eslint-disable-next-line\n while (fn = deferred.pop()) {\n fn();\n }\n}\n","let _scrollBarSize = null;\n\nexport function extend(out = {}) {\n const args = [];\n\n Array.prototype.push.apply(args, arguments);\n\n args.slice(1).forEach((obj) => {\n if (obj) {\n for (let key in obj) {\n if ({}.hasOwnProperty.call(obj, key)) {\n out[key] = obj[key];\n }\n }\n }\n });\n\n return out;\n}\n\nexport function getScrollBarSize() {\n if (_scrollBarSize) {\n return _scrollBarSize;\n }\n const inner = document.createElement('div');\n inner.style.width = '100%';\n inner.style.height = '200px';\n\n const outer = document.createElement('div');\n extend(outer.style, {\n position: 'absolute',\n top: 0,\n left: 0,\n pointerEvents: 'none',\n visibility: 'hidden',\n width: '200px',\n height: '150px',\n overflow: 'hidden'\n });\n\n outer.appendChild(inner);\n\n document.body.appendChild(outer);\n\n const widthContained = inner.offsetWidth;\n outer.style.overflow = 'scroll';\n let widthScroll = inner.offsetWidth;\n\n if (widthContained === widthScroll) {\n widthScroll = outer.clientWidth;\n }\n\n document.body.removeChild(outer);\n\n const width = widthContained - widthScroll;\n\n _scrollBarSize = { width, height: width };\n return _scrollBarSize;\n}\n\nexport const uniqueId = (() => {\n let id = 0;\n return () => ++id;\n})();\n","import { defer } from './deferred';\nimport { extend, uniqueId } from './general';\nimport { isUndefined } from './type-check';\n\nconst zeroPosCache = {};\nlet zeroElement = null;\n\nexport function getBounds(body, el) {\n let doc;\n if (el === document) {\n doc = document;\n el = document.documentElement;\n } else {\n doc = el.ownerDocument;\n }\n\n const docEl = doc.documentElement;\n\n const box = _getActualBoundingClientRect(el);\n\n const origin = _getOrigin(body);\n\n box.top -= origin.top;\n box.left -= origin.left;\n\n if (isUndefined(box.width)) {\n box.width = document.body.scrollWidth - box.left - box.right;\n }\n if (isUndefined(box.height)) {\n box.height = document.body.scrollHeight - box.top - box.bottom;\n }\n\n box.top = box.top - docEl.clientTop;\n box.left = box.left - docEl.clientLeft;\n box.right = doc.body.clientWidth - box.width - box.left;\n box.bottom = doc.body.clientHeight - box.height - box.top;\n\n return box;\n}\n\n/**\n * Gets bounds for when target modifiier is 'scroll-handle'\n * @param target\n * @return {{left: number, width: number, height: number}}\n */\nexport function getScrollHandleBounds(body, target) {\n let bounds;\n // We have to do the check for the scrollTop and if target === document.body here and set to variables\n // because we may reset target below.\n const targetScrollTop = target.scrollTop;\n const targetIsBody = target === document.body;\n\n if (targetIsBody) {\n target = document.documentElement;\n\n bounds = {\n left: pageXOffset,\n top: pageYOffset,\n height: innerHeight,\n width: innerWidth\n };\n } else {\n bounds = getBounds(body, target);\n }\n\n const style = getComputedStyle(target);\n\n const hasBottomScroll = (\n target.scrollWidth > target.clientWidth ||\n [style.overflow, style.overflowX].indexOf('scroll') >= 0 ||\n !targetIsBody\n );\n\n let scrollBottom = 0;\n if (hasBottomScroll) {\n scrollBottom = 15;\n }\n\n const height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom;\n\n const out = {\n width: 15,\n height: height * 0.975 * (height / target.scrollHeight),\n left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15\n };\n\n let fitAdj = 0;\n if (height < 408 && targetIsBody) {\n fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58;\n }\n\n if (!targetIsBody) {\n out.height = Math.max(out.height, 24);\n }\n\n const scrollPercentage = targetScrollTop / (target.scrollHeight - height);\n out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth);\n\n if (targetIsBody) {\n out.height = Math.max(out.height, 24);\n }\n\n return out;\n}\n\n/**\n * Gets bounds for when target modifiier is 'visible\n * @param target\n * @return {{top: *, left: *, width: *, height: *}}\n */\nexport function getVisibleBounds(body, target) {\n if (target === document.body) {\n return { top: pageYOffset, left: pageXOffset, height: innerHeight, width: innerWidth };\n } else {\n const bounds = getBounds(body, target);\n\n const out = {\n height: bounds.height,\n width: bounds.width,\n top: bounds.top,\n left: bounds.left\n };\n\n out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top));\n out.height = Math.min(out.height, bounds.height - ((bounds.top + bounds.height) - (pageYOffset + innerHeight)));\n out.height = Math.min(innerHeight, out.height);\n out.height -= 2;\n\n out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left));\n out.width = Math.min(out.width, bounds.width - ((bounds.left + bounds.width) - (pageXOffset + innerWidth)));\n out.width = Math.min(innerWidth, out.width);\n out.width -= 2;\n\n if (out.top < pageYOffset) {\n out.top = pageYOffset;\n }\n if (out.left < pageXOffset) {\n out.left = pageXOffset;\n }\n\n return out;\n }\n}\n\nexport function removeUtilElements(body) {\n if (zeroElement) {\n body.removeChild(zeroElement);\n }\n zeroElement = null;\n}\n\n/**\n * Same as native getBoundingClientRect, except it takes into account parent offsets\n * if the element lies within a nested document ( or