diff --git a/README.md b/README.md index b441dd0..f458cc9 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ kit.jquery ## Пример конфигурации ```js -kit.PluginManager.register('menu', { +__PluginManager__.register('menu', { path: kit.config.assetsPath + '/menu', module: '/menu.js', type: 'loader', @@ -121,6 +121,17 @@ PluginManager.ready(deps, callback) +## Глобальные переменные (window) + +переменная kit может быть задана любой, поэтому в некоторых местах корректно будет использовать универсальные глобальные переменные + +| name | link | description | +| --- | --- | --- | +| `__pmGlobal__` | аналог window.kit | | +| `__PluginManager__` |аналог window.kit.PluginManager | | +| `__pmConfig__` | аналог window.kit.config | | + + ## z-index map | z-index | plugin | selector | diff --git a/assets/align/align.js b/assets/align/align.js index c68265c..01ed178 100644 --- a/assets/align/align.js +++ b/assets/align/align.js @@ -1,220 +1,585 @@ -kit.PluginManager.register('align',function() { +/** @module align */ +kit.PluginManager.register('align',function(module, exports, require) { - var AlignClass = function(){ - - var Align = function() - { - this.reset(); - this.node = null; - this.parentNode = null; - this.offsetHorizontal = 0; - this.offsetVertical = 0; - this.offset = 0; - }; - - /** - * @param node HTMLElement - * @return {Align} - */ - Align.prototype.setNode = function(node){ - this.node = node; - return this; - }; - /** - * @param node HTMLElement - * @return {Align} - */ - Align.prototype.setParentNode = function(node){ - this.parentNode = node; - return this; - }; - /** - * @return {Align} - */ - Align.prototype.reset = function(hor = true, vert = true){ - if(hor) { - this.right = {applicability: 0, valid: false}; - this.left = {applicability: 0, valid: false}; - } - if(vert) { - this.top = {applicability: 0, valid: false}; - this.bottom = {applicability: 0, valid: false}; - } - return this; - }; - - Align.prototype.getContentSizes = function() { + /** + * @class Rect + * @param node + */ + var Rect = function (node) { + this.node = node; + this.get(); + }; + Rect.prototype.get = function () { + function getBoundingClientRect(node) { + var rect = node.getBoundingClientRect(); return { - InnerWidth: window.innerWidth, - InnerHeight: window.innerHeight, + top: rect.top, + right: rect.right, + bottom: rect.bottom, + left: rect.left, + width: rect.width, + height: rect.height, + x: rect.x, + y: rect.y }; + } + var metrics = {}; + if(this.node instanceof HTMLElement) { + metrics = { + offsetHeight: this.node.offsetHeight, + offsetWidth: this.node.offsetWidth, + clientHeight: this.node.clientHeight, + clientWidth: this.node.clientWidth, + offsetLeft: this.node.offsetLeft, + offsetTop: this.node.offsetTop, + clientLeft: this.node.clientLeft, + clientTop: this.node.clientTop, + clientRight: this.node.offsetWidth - this.node.clientWidth, + clientBottom: this.node.offsetHeight - this.node.clientHeight, + + offsetRight: document.body.offsetWidth - this.node.offsetLeft - this.node.offsetWidth, + offsetBottom: window.innerHeight - this.node.offsetTop - this.node.offsetHeight, + }; + metrics = Object.assign({}, getBoundingClientRect(this.node), metrics); + } + if(this.node instanceof Window) { + metrics = { + offsetHeight: window.innerHeight, + offsetWidth: document.body.offsetWidth, + clientHeight: window.innerHeight, + clientWidth: document.body.offsetWidth, + offsetLeft: 0, + offsetTop: 0, + clientLeft: 0, + clientTop: 0, + clientRight: 0, + clientBottom: 0, + + offsetRight: 0, + offsetBottom: 0, + }; + metrics = Object.assign({ + left: 0, + top: 0, + right: document.body.offsetWidth, + bottom: window.innerHeight, + x: 0, + y: 0, + width: document.body.offsetWidth, + height: window.innerHeight, + }, metrics) + } + Object.assign(this, metrics); + return this; + }; + Rect.prototype.getLine = function (axis = 'horizontal') { + var line = new Line(null, axis); + line.node = this.node; + line.rect = this; + line.setAxis(axis); + return line; + }; + + var viewLineDriver = { + horizontal: { + left: 'start', + right: 'end', + x: 'a', + width: 'length', + + offsetWidth: 'offset', + clientWidth: 'client', + offsetLeft: 'offsetStart', + clientLeft: 'clientStart', + offsetRight: 'offsetEnd', + clientRight: 'clientEnd', + }, + vertical: { + top: 'start', + bottom: 'end', + y: 'a', + height: 'length', + + offsetHeight: 'offset', + clientHeight: 'client', + offsetTop: 'offsetStart', + clientTop: 'clientStart', + offsetBottom: 'offsetEnd', + clientBottom: 'clientEnd', + }, + }; + + + /** + * @param node + * @param axis + * @property start + * @property end + * @property a + * @property length + * @property offset + * @property client + * @property offsetStart + * @property clientStart + * @property offsetEnd + * @property clientEnd + * + */ + var Line = function (node, axis = 'horizontal') { + this.axis = axis; + this.node = node; + this.update(); + }; + Line.prototype.setAxis = function(axis){ + this.axis = axis; + + for (var key in viewLineDriver[this.axis]) { + this[viewLineDriver[this.axis][key]] = this.rect[key]; + } + }; + Line.prototype.update = function () { + if(!this.node) { + return this; + } + this.rect = new Rect(this.node); + this.setAxis(this.axis); + return this; + }; + + var metric = { + Rect: Rect, + Line: Line, + }; + + /** + * + * @class {AlignCalc} + * @param limiterNode {HTMLElement} + * @param parentNode {HTMLElement} + * @param node {HTMLElement} + */ + var AlignCalc = function (node, parentNode, limiterNode = window) { + + var _this = this; + this.axis = 'horizontal'; + this.direction = 'bottom'; + this.align = 'bottom'; + this.offset = [0, 0]; + this.setLimiterNode(limiterNode); + this.setParentNode(parentNode); + this.setNode(node); + + this.style = { + start: function (extra) { + this.nodeMetricsLine.node.style[this.map.style.start()] = '' + ((!this.valid && extra)?this.shiftExtra:this.shift) + 'px'; + }.bind(this), + end: function (extra) { + this.nodeMetricsLine.node.style[this.map.style.end()] = 'unset'; + }.bind(this), }; - /** - * @param top bool - * @param inner bool - * @return {Align} - */ - Align.prototype.setVertical = function(top = false, inner = false){ - var contentSizes = this.getContentSizes(); - this.reset(false, true); - - if(top){ - !this.calcTop(contentSizes, inner) && this.calcBottom(contentSizes, inner); - } else { - !this.calcBottom(contentSizes, inner) && this.calcTop(contentSizes, inner); + this.map = { + style: { + start: function(){ + switch (_this.axis) { + case 'vertical': + return 'top'; + case 'horizontal': + return 'left'; + } + }, + end: function(){ + switch (_this.axis) { + case 'vertical': + return 'bottom'; + case 'horizontal': + return 'right'; + } + }, + }, + direction: { + get: function () { + switch (_this.direction) { + case 'start': + case 'left': + case 'top': + return 'start'; + case 'end': + case 'right': + case 'bottom': + return 'end'; + } + } + }, + align: { + get: function () { + switch (_this.align) { + case 'start': + case 'left': + case 'top': + return 'start'; + case 'end': + case 'right': + case 'bottom': + return 'end'; + } + } + }, + axisNumber: function () { + return _this.axis === 'horizontal' ? 0 : 1; } + }; - if(!this.top.valid && !this.bottom.valid) { - if(this.top.applicability > this.bottom.applicability || contentSizes.InnerHeight < this.node.offsetHeight) { - this.calcTop(contentSizes, inner, true); - } else { - this.calcBottom(contentSizes, inner, true); + var getShiftWhenHidingNodeUnderLimiterStart = function(shift) { + var d = this.parentMetricsLine.start + shift - this.limiterMetricsLine.start; + if(d < 0) { + shift = shift - d; + } + return shift; + }.bind(this); + + this.core = { + direction: { + start: { + shift: function () { + return - this.nodeMetricsLine.offset - this.offset[this.map.axisNumber()]; + }.bind(this), + applicability: function () { + return (this.parentMetricsLine.start + this.shift) - this.limiterMetricsLine.start; + }.bind(this), + valid: function () { + return (this.parentMetricsLine.start + this.shift) >= this.limiterMetricsLine.start; + }.bind(this), + shiftExtra: function () { + return getShiftWhenHidingNodeUnderLimiterStart(this.shift - this.applicability); + }.bind(this), + }, + end: { + shift: function () { + return this.offset[this.map.axisNumber()]; + }.bind(this), + applicability: function () { + return this.limiterMetricsLine.end - (this.parentMetricsLine.start + this.nodeMetricsLine.length + this.shift); + }.bind(this), + valid: function () { + return this.limiterMetricsLine.end >= (this.parentMetricsLine.start + this.nodeMetricsLine.length + this.shift); + }.bind(this), + shiftExtra: function () { + return getShiftWhenHidingNodeUnderLimiterStart(this.shift + this.applicability); + }.bind(this), + }, + }, + align: { + start: { + shift: function () { + return this.nodeMetricsLine.clientStart; + }.bind(this), + }, + end: { + shift: function () { + return this.parentMetricsLine.offset - this.parentMetricsLine.clientStart; + }.bind(this), + }, + }, + }; + + return this; + }; + /** + * @param node + * @return {AlignCalc} + */ + AlignCalc.prototype.setLimiterNode = function (node) { + if(!this.limiterMetricsLine || (this.limiterMetricsLine.node !== node)) { + this.limiterMetricsLine = new Line(node, this.axis); + } + return this; + }; + /** + * + * @param node + * @return {AlignCalc} + */ + AlignCalc.prototype.setParentNode = function (node) { + if(!this.parentMetricsLine || (this.parentMetricsLine.node !== node)) { + this.parentMetricsLine = new Line(node, this.axis); + } + return this; + }; + /** + * + * @param node + * @return {AlignCalc} + */ + AlignCalc.prototype.setNode = function (node) { + if(!this.nodeMetricsLine || (this.nodeMetricsLine.node !== node)) { + this.nodeMetricsLine = new Line(node, this.axis); + } + return this; + }; + + /** + * + * @param extra + * @return {AlignCalc} + */ + AlignCalc.prototype.render = function (extra = false) { + for (var key in this.style) { + if(this.style.hasOwnProperty(key)) { + this.style[key](extra); + } + } + return this; + }; + /** + * + * @return {AlignCalc} + */ + AlignCalc.prototype.updateMetrics = function(){ + this.limiterMetricsLine.update(); + this.parentMetricsLine.update(); + this.nodeMetricsLine.update(); + return this; + }; + /** + * + * @param direction + * @return {AlignCalc} + */ + AlignCalc.prototype.setDirection = function(direction){ + this.direction = direction; + return this; + }; + /** + * + * @param align + * @return {AlignCalc} + */ + AlignCalc.prototype.setAlign = function(align){ + this.align = align; + return this; + }; + /** + * + * @param axis + * @return {AlignCalc} + */ + AlignCalc.prototype.setAxis = function(axis){ + this.axis = axis; + this.limiterMetricsLine.setAxis(axis); + this.parentMetricsLine.setAxis(axis); + this.nodeMetricsLine.setAxis(axis); + return this; + }; + /** + * + * @param align + * @param direction + * @return {AlignCalc} + */ + AlignCalc.prototype.set = function(align, direction){ + this.align = align; + this.direction = direction; + return this; + }; + /** + * + * @return {AlignCalc} + */ + AlignCalc.prototype.calc = function () { + this.shift = + this.core.direction[this.map.direction.get()].shift() + + this.core.align[this.map.align.get()].shift(); + + this.applicability = this.core.direction[this.map.direction.get()].applicability(); + + this.valid = this.core.direction[this.map.direction.get()].valid(); + + this.shiftExtra = this.core.direction[this.map.direction.get()].shiftExtra(); + + return this; + }; + /** + * + * @return {{valid: *, shiftExtra: *, shift: *, applicability: *}} + */ + AlignCalc.prototype.getData = function () { + return { + shift: this.shift, + applicability: this.applicability, + valid: this.valid, + shiftExtra: this.shiftExtra, + }; + }; + + + /** + * @param node {HTMLElement} + * @param parentNode {HTMLElement} + * @param limiterNode {HTMLElement} + * @constructor + */ + var AlignClass = function(node, parentNode, limiterNode = window) + { + this.changeOfDirection = true; + this.withinTheScreen = true; + this.offset = [0, 0]; + + this.status = {vertical: {}, horizontal: {},}; + + this.setNode(node); + this.setParentNode(parentNode); + this.setLimiterNode(limiterNode); + + }; + + AlignClass.prototype.setNode = function(node){ + this.unset(); + this.node = node; + this.reset(); + if(node instanceof HTMLElement) { + this.node.kit = this.node.kit || {}; + this.node.kit.align = this; + } + if(this.calc) { + this.calc.setNode(this.node); + } + return this; + }; + + AlignClass.prototype.setParentNode = function(node){ + this.parentNode = node; + if(this.calc) { + this.calc.setParentNode(this.parentNode); + } + return this; + }; + AlignClass.prototype.setLimiterNode = function(node){ + this.limiterNode = node; + if(this.calc) { + this.calc.setLimiterNode(this.limiterNode); + } + return this; + }; + + AlignClass.prototype.unset = function(){ + if(this.node instanceof HTMLElement) { + if(this.node.kit && this.node.kit.align){ + delete this.node.kit.align; + } + this.node.removeAttribute('data-kit-align-horizontal-direction'); + this.node.removeAttribute('data-kit-align-horizontal-align'); + this.node.removeAttribute('data-kit-align-vertical-direction'); + this.node.removeAttribute('data-kit-align-vertical-align'); + } + }; + AlignClass.prototype.reset = function(bHorizontal = true, bVertical = true){ + if(bHorizontal) { + this.status.horizontal = {}; + if(this.node instanceof HTMLElement) { + this.node.style.left = ''; + this.node.style.right = ''; + this.node.removeAttribute('data-kit-align-horizontal-direction'); + this.node.removeAttribute('data-kit-align-horizontal-align'); + } + } + if(bVertical) { + this.status.vertical = {}; + if(this.node instanceof HTMLElement) { + this.node.style.top = ''; + this.node.style.bottom = ''; + this.node.removeAttribute('data-kit-align-vertical-direction'); + this.node.removeAttribute('data-kit-align-vertical-align'); + } + } + return this; + }; + + AlignClass.prototype.set = function(hAlign, vAlign, hDirection, vDirection){ + this.setEx('vertical', vDirection, vAlign); + this.setEx('horizontal', hDirection, hAlign); + return this; + }; + AlignClass.prototype.setVertical = function(direction, align){ + this.setEx('vertical', direction, align); + return this; + }; + + AlignClass.prototype.setHorizontal = function(direction, align){ + this.setEx('horizontal', direction, align); + return this; + }; + + AlignClass.prototype.setEx = function(axis, direction, align){ + + this.reset(axis === 'horizontal', axis === 'vertical'); + + this.status[axis].direction = direction; + this.status[axis].align = align; + + if(!this.calc) { + this.calc = new AlignCalc(this.node, this.parentNode, this.limiterNode); + } + + this.calc.offset = this.offset; + this.node.setAttribute('data-kit-align-'+axis+'-direction', direction); + this.node.setAttribute('data-kit-align-'+axis+'-align', align); + var defAlignResult = this.calc.updateMetrics().setAxis(axis).setDirection(direction).setAlign(align).calc().getData(); + // console.log('defAlignResult', axis, align, direction, defAlignResult); + if(this.changeOfDirection) { + if(!defAlignResult.valid) { + this.node.setAttribute('data-kit-align-'+axis+'-direction', this.getInverse(direction)); + this.node.setAttribute('data-kit-align-'+axis+'-align', this.getInverse(align)); + var inverseAlignResult = this.calc.updateMetrics().setDirection(this.getInverse(direction)).setAlign(this.getInverse(align)).calc().getData(); + // console.log('inverseAlignResult', axis, this.getInverse(align), this.getInverse(direction), inverseAlignResult); + this.status[axis].direction = this.getInverse(direction); + this.status[axis].align = this.getInverse(align); + if(!inverseAlignResult.valid && (defAlignResult.applicability > inverseAlignResult.applicability) ) { + this.node.setAttribute('data-kit-align-'+axis+'-direction', direction); + this.node.setAttribute('data-kit-align-'+axis+'-align', align); + this.status[axis].direction = direction; + this.status[axis].align = align; + this.calc.updateMetrics().setDirection(direction).setAlign(align).calc(); } } + } - return this; + this.calc.render(this.withinTheScreen); + return this; + }; + + AlignClass.prototype.getInverse = function(value){ + var inverseConfig = { + start: 'end', + left: 'right', + top: 'bottom', + end: 'start', + right: 'left', + bottom: 'top', }; - Align.prototype.calcTop = function (contentSizes, inner, extra = false) { - var top, offset; + if(inverseConfig.hasOwnProperty(value)) { + return inverseConfig[value]; + } + return value; + }; - this.node.setAttribute('data-kit-align-vertical','top'); - offset = this.offsetVertical || this.offset; - if(inner) { - top = 0 - this.node.offsetHeight + this.parentNode.offsetHeight - this.parentNode.clientTop - offset; - } else { - top = 0 - this.parentNode.clientTop - this.node.offsetHeight + this.node.clientTop - offset; + /** + * @memberof kitCore + * @instance + */ + var align = { + Class: AlignClass, + getInstance: function (node, parentNode) { + if(node instanceof HTMLElement && node.kit && node.kit.align) { + return node.kit.align; } + return new AlignClass(node, parentNode); + }, + metric: metric, + }; - this.node.style.top = '' + top + 'px'; - this.node.style.bottom = 'unset'; + module.exports = align; - if(extra) { - this.checkTop(contentSizes); - this.node.style.top = (top - this.top.applicability) + 'px'; - return false; - } - return this.checkTop(contentSizes); - }; - Align.prototype.calcBottom = function (contentSizes, inner, extra = false) { - - var top, offset; - this.node.setAttribute('data-kit-align-vertical','bottom'); - offset = this.offsetVertical || this.offset; - - if(inner) { - top = 0 - this.parentNode.clientTop + offset; - } else { - top = this.parentNode.offsetHeight - this.parentNode.clientTop + offset; - } - - this.node.style.top = '' + top + 'px'; - this.node.style.bottom = 'unset'; - - if(extra) { - this.checkBottom(contentSizes); - this.node.style.top = (top + this.bottom.applicability) + 'px'; - return false; - } - return this.checkBottom(contentSizes); - }; - Align.prototype.checkTop = function (contentSizes) { - var b = this.node.getBoundingClientRect(); - this.top.applicability = b.top - 0; - this.top.valid = b.top >= 0; - return this.top.valid; - }; - Align.prototype.checkBottom = function (contentSizes) { - var b = this.node.getBoundingClientRect(); - this.bottom.applicability = contentSizes.InnerHeight - (b.top + b.height); - this.bottom.valid = contentSizes.InnerHeight >= (b.top + b.height); - return this.bottom.valid; - }; - - /** - * @param right bool - * @param inner bool - * @return {Align} - */ - Align.prototype.setHorizontal = function(right = true, inner = false){ - var contentSizes = this.getContentSizes(); - this.reset(true, false); - - if(right){ - !this.calcRight(contentSizes, inner) && this.calcLeft(contentSizes, inner); - } else { - !this.calcLeft(contentSizes, inner) && this.calcRight(contentSizes, inner); - } - - if(!this.left.valid && !this.right.valid) { - if(this.left.applicability > this.right.applicability || contentSizes.InnerWidth < this.node.offsetWidth) { - this.calcLeft(contentSizes, inner, true); - } else { - this.calcRight(contentSizes, inner, true) - } - } - - return this; - }; - Align.prototype.calcLeft = function (contentSizes, inner, extra = false) { - var left, offset; - - this.node.setAttribute('data-kit-align-horizontal','left'); - offset = this.offsetHorizontal || this.offset; - - if(inner) { - left = 0 - this.node.offsetWidth + this.parentNode.offsetWidth - this.parentNode.clientLeft - offset; - } else { - left = 0 - this.parentNode.clientLeft - this.node.offsetWidth + this.node.clientLeft - offset; - } - - this.node.style.left = '' + left + 'px'; - this.node.style.right = 'unset'; - - if(extra) { - this.checkLeft(contentSizes); - this.node.style.left = (left - this.left.applicability) + 'px'; - return false; - } - return this.checkLeft(contentSizes); - }; - Align.prototype.calcRight = function (contentSizes, inner, extra = false) { - var left, offset; - this.node.setAttribute('data-kit-align-horizontal','right'); - offset = this.offsetHorizontal || this.offset; - - if(inner) { - left = 0 - this.parentNode.clientLeft + offset; - } else { - left = this.parentNode.offsetWidth - this.parentNode.clientLeft + offset; - } - - this.node.style.left = '' + left + 'px'; - this.node.style.right = 'unset'; - - if(extra) { - this.checkRight(contentSizes); - this.node.style.left = (left + this.right.applicability) + 'px'; - return false; - } - return this.checkRight(contentSizes); - }; - Align.prototype.checkLeft = function (contentSizes) { - var b = this.node.getBoundingClientRect(); - this.left.applicability = b.left - 0; - this.left.valid = b.left >= 0; - return this.left.valid; - }; - Align.prototype.checkRight = function (contentSizes) { - var b = this.node.getBoundingClientRect(); - this.right.applicability = contentSizes.InnerWidth - (b.left + b.width); - this.right.valid = contentSizes.InnerWidth >= (b.left + b.width); - return this.right.valid; - }; - return Align; - }(); - - this.Class = AlignClass; - return this; + return module.exports; }); diff --git a/assets/animations/animations.css b/assets/animations/animations.css new file mode 100644 index 0000000..f3163da --- /dev/null +++ b/assets/animations/animations.css @@ -0,0 +1,16 @@ +.anim-scale-in { + animation-name: scale-in; + animation-duration: .15s; + animation-timing-function: cubic-bezier(0.2, 0, 0.13, 1.5); +} + +@keyframes scale-in { + 0% { + opacity: 0; + transform: scale(0.5); + } + 100% { + opacity: 1; + transform: scale(1); + } +} \ No newline at end of file diff --git a/assets/animations/animations.js b/assets/animations/animations.js new file mode 100644 index 0000000..1027b59 --- /dev/null +++ b/assets/animations/animations.js @@ -0,0 +1,15 @@ +/** @module animations */ +kit.PluginManager.register('animations',function(module, exports, require, global) { + + /** + * @memberof kitCore + * @instance + */ + var animations = { + scaleIn: 'anim-scale-in', + }; + + Object.assign(animations, global.animations || {}); + + return module.exports = animations; +}); diff --git a/assets/collection/collection.js b/assets/collection/collection.js new file mode 100644 index 0000000..75ab199 --- /dev/null +++ b/assets/collection/collection.js @@ -0,0 +1,73 @@ +/** @module collection */ +kit.PluginManager.register('collection',function(module, exports, require, global) { + + function valueEx(value) { + if(typeof value === 'function') { + return value(); + } + return value; + } + function uniqueId (length = 32, firstLetter = true) { + var idStr = ''; + if(length < 1) return idStr; + if(firstLetter) { + length && (idStr = (Math.floor((Math.random() * 25)) + 10).toString(36)); + if (length === 1) return idStr; + } + do { + idStr += (Math.floor((Math.random() * 35))).toString(36); + } while (idStr.length < length); + return (idStr); + }; + + var ArrayCollection = function (data){ + this.data = data; + }; + ArrayCollection.prototype.all = function () { + return this.data; + }; + ArrayCollection.prototype.put = function (key, value) { + this.data[key] = value; + }; + ArrayCollection.prototype.push = function (value) { + this.data.push(value); + }; + ArrayCollection.prototype.get = function (key, defValue = undefined) { + if(this.data.hasOwnProperty(key)) { + return this.data[key]; + } + return valueEx(defValue); + }; + ArrayCollection.prototype.has = function (key) { + return this.data.hasOwnProperty(key); + }; + + + var ObjectCollection = function (data){ + this.data = data; + }; + ObjectCollection.prototype.all = ArrayCollection.prototype.all; + ObjectCollection.prototype.put = ArrayCollection.prototype.put; + ObjectCollection.prototype.push = function (value) { + this.data[uniqueId(8)] = value; + }; + ObjectCollection.prototype.get = ArrayCollection.prototype.get; + ObjectCollection.prototype.has = ArrayCollection.prototype.has; + + /** + * @memberof kitCore + * @instance + */ + var Collection = function (data) { + if(typeof data === 'object') { + return new ObjectCollection(data); + } + if(Array.isArray(data)) { + return new ArrayCollection(data); + } + return new ArrayCollection([data]); + } + + + return module.exports = Collection; +}); diff --git a/assets/config/config.js b/assets/config/config.js index 2a86578..ae89aef 100644 --- a/assets/config/config.js +++ b/assets/config/config.js @@ -1,5 +1,4 @@ /** - * @var kit * @type {kitCore} */ window.kit = window.kit || {}; diff --git a/assets/config/toolkit.config.css b/assets/config/toolkit.config.css index 0b67a1a..9c58b75 100644 --- a/assets/config/toolkit.config.css +++ b/assets/config/toolkit.config.css @@ -63,6 +63,8 @@ --kit-color: #1a1a1a; --kit-color-text-hover: var(--kit-color-primary); + --kit-color-primary-w5: hsl(210, 100%, 85%); + --kit-color-primary-w4: hsl(210, 100%, 80%); --kit-color-primary-w3: hsl(210, 100%, 70%); --kit-color-primary-w2: hsl(210, 100%, 65%); --kit-color-primary-w1: hsl(210, 100%, 60%); @@ -70,8 +72,12 @@ --kit-color-primary-b1: hsl(210, 100%, 50%); --kit-color-primary-b2: hsl(210, 100%, 45%); --kit-color-primary-b3: hsl(210, 100%, 40%); + --kit-color-primary-b4: hsl(210, 100%, 35%); + --kit-color-primary-b5: hsl(210, 100%, 30%); --kit-color-primary-text: #FFF; + --kit-color-secondary-w5: hsl(0, 0%, 80%); + --kit-color-secondary-w4: hsl(0, 0%, 75%); --kit-color-secondary-w3: hsl(0, 0%, 70%); --kit-color-secondary-w2: hsl(0, 0%, 65%); --kit-color-secondary-w1: hsl(0, 0%, 60%); @@ -79,6 +85,8 @@ --kit-color-secondary-b1: hsl(0, 0%, 50%); --kit-color-secondary-b2: hsl(0, 0%, 45%); --kit-color-secondary-b3: hsl(0, 0%, 40%); + --kit-color-secondary-b4: hsl(0, 0%, 35%); + --kit-color-secondary-b5: hsl(0, 0%, 30%); --kit-color-secondary-text: #FFF; diff --git a/assets/core/core.js b/assets/core/core.js index 39d0eca..88b06aa 100644 --- a/assets/core/core.js +++ b/assets/core/core.js @@ -399,11 +399,10 @@ window.kit = window.kit || {}; if(data === undefined) { return; } - if(!this.global.hasOwnProperty(key)) { - this.global[key] = data; - } else { - console.warn('PluginManager.install: plugin ' + pluginId + ' already exist in kit ('+plugin.state+')'); + if(this.global.hasOwnProperty(key)) { + console.warn(`PluginManager.install(${pluginId}): key ${key} overwritten in kit (${plugin.state}).`); } + this.global[key] = data; if(Array.isArray(aliasList) && aliasList.length) { aliasList.forEach(function (alias) { setGlobalExtension(alias, [], data) @@ -579,17 +578,16 @@ window.kit = window.kit || {}; if(this.plugins.hasOwnProperty(pluginId)) { return this.plugins[pluginId]; } - for (var _pluginId in this.plugins) { + var _pluginId; + for (_pluginId in this.plugins) { if(this.plugins.hasOwnProperty(_pluginId) && this.plugins[_pluginId].config.alias.indexOf(pluginId) !== -1) { return this.plugins[_pluginId]; } } - - var _pluginId = pluginId[0].toUpperCase() + pluginId.slice(1); + _pluginId = pluginId[0].toUpperCase() + pluginId.slice(1); if(_pluginId !== pluginId) { return this.__getPlugin(_pluginId); } - return undefined; }; diff --git a/assets/core/core.register.js b/assets/core/core.register.js index f808115..f2616be 100644 --- a/assets/core/core.register.js +++ b/assets/core/core.register.js @@ -6,7 +6,7 @@ __PluginManager__.registerPlugins({ '/menu.css' ], type: 'loader', - deps: ['lib', 'align', 'utils'] + deps: ['lib', 'align', 'utils', 'animations'] }, lib: { path: __pmConfig__.assetsPath + '/lib', @@ -141,6 +141,12 @@ __PluginManager__.registerPlugins({ module: '/cookie.js', type: 'loader', }, + animations: { + path: __pmConfig__.assetsPath + '/animations', + css: '/animations.css', + module: '/animations.js', + type: 'loader', + }, }); diff --git a/assets/core/doc.js b/assets/core/doc.js index 4d4dd02..4d2491c 100644 --- a/assets/core/doc.js +++ b/assets/core/doc.js @@ -15,6 +15,10 @@ * @property {kitCookie} cookie * @property {kitConfig} config * @property {kitTooltip} tooltip - * @property {kitPopover} popover + * @property {kitPopover} Popover * @property {kitPopper} popper - */ \ No newline at end of file + */ + +/** + * @namespace kit + */ diff --git a/assets/lib/lib.js b/assets/lib/lib.js index d3a023d..ca65ecd 100644 --- a/assets/lib/lib.js +++ b/assets/lib/lib.js @@ -1,9 +1,18 @@ -kit.PluginManager.register('lib',function() { +/** @module lib */ +kit.PluginManager.register('lib',function(module, exports, require, global) { - this.icon = { - options: '', - arrowMenu: '', + /** + * @memberof kitCore + * @instance + */ + var lib = { + svg: { + options: '', + arrowMenu: '', + } }; - return this; + Object.assign(lib, global.lib || {}); + + return module.exports = lib; }); diff --git a/assets/menu/menu.css b/assets/menu/menu.css index 0327a3f..81f3927 100644 --- a/assets/menu/menu.css +++ b/assets/menu/menu.css @@ -21,11 +21,11 @@ background: var(--kit-color-menu-content); display: none; } -.kit-menu[data-kit-align-horizontal="right"] { +.kit-menu[data-kit-align-horizontal-align="right"] { border-left: var(--kit-menu-border-width) solid var(--kit-color-primary, #3c9cdd); box-shadow: 0 0 10px 0 #00000033, inset 5px 0 5px -5px var(--kit-color-primary-b2, #2283c3); } -.kit-menu[data-kit-align-horizontal="left"] { +.kit-menu[data-kit-align-horizontal-align="left"] { border-right: var(--kit-menu-border-width) solid var(--kit-color-primary, #3c9cdd); box-shadow: 0 0 10px 0 #00000033, inset -5px 0 5px -5px var(--kit-color-primary-b2, #2283c3); } @@ -46,6 +46,7 @@ padding-left: 0.5em; padding-right: 0.5em;; min-width: calc(15 * 1em); + text-decoration: none; } .kit-menu-item > *:not(.kit-menu) { margin-left: 0.5em; @@ -104,8 +105,8 @@ .kit-menu-item__label:hover > a { color: var(--kit-color-menu-content-text-hover); } -.kit-menu[data-kit-align-horizontal="left"] .kit-menu-item:before, -.kit-menu[data-kit-align-horizontal="right"] .kit-menu-item:before +.kit-menu[data-kit-align-horizontal-align="left"] .kit-menu-item:before, +.kit-menu[data-kit-align-horizontal-align="right"] .kit-menu-item:before { content: ""; position: absolute; @@ -119,7 +120,7 @@ left: 0; right: unset; } -.kit-menu[data-kit-align-horizontal="left"] > .kit-menu-item:before { +.kit-menu[data-kit-align-horizontal-align="left"] > .kit-menu-item:before { right: 0; left: unset; } @@ -142,14 +143,14 @@ flex: 0 0 1.5em; order: 1000; } -.kit-menu[data-kit-align-horizontal="left"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__arrow { +.kit-menu[data-kit-align-horizontal-align="left"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__arrow { /*order: 10;*/ /*transform: rotate(180deg);*/ } -.kit-menu[data-kit-align-horizontal="left"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__icon { +.kit-menu[data-kit-align-horizontal-align="left"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__icon { /*order: 990;*/ } -.kit-menu[data-kit-align-horizontal="right"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__arrow { +.kit-menu[data-kit-align-horizontal-align="right"] > .kit-menu-item > .kit-menu ~ .kit-menu-item__arrow { } .kit-menu-item__arrow { diff --git a/assets/menu/menu.js b/assets/menu/menu.js index adb1528..255710f 100644 --- a/assets/menu/menu.js +++ b/assets/menu/menu.js @@ -1,18 +1,23 @@ -kit.PluginManager.register('menu',function(module, exports, require) { +/** @module menu */ +//todo: instance, options, auto-options-by-node, fast reCalc, fast reInit, userEventManager, collection +__PluginManager__.register('menu',function(module, exports, require) { - var AlignModule = require('align'); + + var align = require('align'); var libModule = require('lib'); var utils = require('utils'); - + /** + * @class kitMenuClassDefaultOptions + */ var defaultMenuOptions = { parent: null, - nodeProperty: 'kitMenu', + nodeProperty: 'menu', class: 'kit-menu', eventType: 'hover', + animation: '', hideDelay: 200, - offsetHorizontal: 0, - offsetVertical: 0, + alignOffset: [0, 0], click: (function (event, menu) { console.log('Menu click'); }), @@ -27,9 +32,24 @@ kit.PluginManager.register('menu',function(module, exports, require) { }; - var MenuList = []; - var MenuClass = (function () { + var MenuList = []; + var MenuListIncrement = 0; + + var MenuClass = (function () { + /** + * @typedef kitMenuItemHandler + * @param event {MouseEvent} + * @param menuItem {MenuItem} + * @param menu {Menu} + */ + + + /** + * @param options + * @param items + * @constructor + */ function Menu(options = {}, items = []) { //console.log('Menu: constructor'); @@ -38,12 +58,11 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.documentListenerHandler = this.documentListener.bind(this); this.nodeActionHandler = this.nodeAction.bind(this); - this.id = MenuList.length; + this.id = ++MenuListIncrement; MenuList[this.id] = this; - this.itemList = {}; - this.align = new AlignModule.Class(); + this.align = new align.Class(); this.node = null; this.bInit = false; this.deferredHideID = 0; @@ -85,17 +104,21 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.node.classList.add(this.options.class); this.node.style.display = 'none'; this.node.setAttribute('data-menu-id', this.id); - this.node[this.options.nodeProperty] = this; + this.node.kit = this.node.kit || {}; + this.node.kit[this.options.nodeProperty] = this; }; Menu.prototype.showNode = function () { - // console.log('Menu: showNode'); + // console.log('Menu: showNode ' + this.id, this.bActive); this.deferredHideCancel(); - this.node.style.display = ''; - this.node.classList.add('active'); - this.options.parent.classList.add('active'); - this.calcStyle(); - this.bActive = true; - document.addEventListener('click', this.documentListenerHandler, false); + if(!this.bActive) { + this.node.style.display = ''; + this.node.classList.add('active'); + this.options.parent.classList.add('active'); + this.calcStyle(); + this.bActive = true; + this.addDocumentEventListener(); + } + this.addAnimation(); }; Menu.prototype.hideNode = function () { // console.log('Menu: hideNode'); @@ -125,13 +148,25 @@ kit.PluginManager.register('menu',function(module, exports, require) { // console.log('Menu: hideNodeNow'); this.deferredHideCancel(); this.node.style.display = 'none'; + this.removeAnimation(); this.node.classList.remove('active'); this.options.parent.classList.remove('active'); this.bActive = false; - document.removeEventListener('click', this.documentListenerHandler, false); + this.removeDocumentEventListener(); return this; }; + Menu.prototype.removeAnimation = function(){ + if(this.options.animation && this.node && this.node.classList.contains(this.options.animation)){ + this.node.classList.remove(this.options.animation); + } + }; + Menu.prototype.addAnimation = function(){ + if(this.options.animation && this.node && !this.node.classList.contains(this.options.animation)){ + this.node.classList.add(this.options.animation); + } + }; + /** * @returns {Menu} */ @@ -143,7 +178,8 @@ kit.PluginManager.register('menu',function(module, exports, require) { } return this; }; - Menu.prototype.calcStyle = function () { + Menu.prototype.calcStyle = function (recursive = false) { + // console.log('calcStyle ' + this.id); if(!(this.options.parent instanceof Element)) { console.warn('Menu.options.parent NOT instanceof Element'); return false; @@ -155,35 +191,67 @@ kit.PluginManager.register('menu',function(module, exports, require) { //var parentNode = this.getParentMenuNode() || this.getParent(); var parentNode = this.getParent(); - var right = true; + var hDirection = 'right'; var parentMenu = this.getParentMenu(); if(parentMenu && parentMenu instanceof Menu) { - right = !parentMenu.align.left.valid; + hDirection = parentMenu.align.status.horizontal.direction; + } + var hAlign = 'right'; + if(parentMenu && parentMenu instanceof Menu) { + hAlign = parentMenu.align.status.horizontal.align; } - this.align.offsetHorizontal = this.options.offsetHorizontal; - this.align.offsetVertical = this.options.offsetVertical; + this.align.offset = this.options.alignOffset; this.align .setNode(this.node) .setParentNode(parentNode) - .setHorizontal(right, false) - .setVertical(false, true); + .setHorizontal(hDirection, hAlign) + .setVertical('bottom', 'top'); - // this.node.setAttribute('data-kit-menu-align-horizontal', horMode); + + if(recursive) { + this.calcStyleChildMenu(true, MenuList); + } + }; + + Menu.prototype.calcStyleChildMenu = function(recursive = false, MenuList = null){ + var i, MenuListActive = []; + for(i in MenuList){ + if(!MenuList.hasOwnProperty(i) || !(MenuList[i] instanceof Menu)) { + continue; + } + + if(MenuList[i].bActive && this !== MenuList[i]) { + MenuListActive.push(MenuList[i]); + } + } + + for(i in MenuListActive){ + if(MenuListActive[i].getParentMenu() === this) { + MenuListActive[i].calcStyle(); + + if(recursive) { + MenuListActive[i].calcStyleChildMenu(true, MenuListActive); + } + } + } }; /** * @return {Menu} | null */ Menu.prototype.getParentMenu = function() { + if(this.getParent() && this.getParent().kitMenuItem) { + return this.getParent().kitMenuItem.getMenu(); + } + return undefined; if( this.getParent() && (this.getParent() instanceof Element) && - this.getParent().hasOwnProperty('kitMenuItem') && (this.getParent().kitMenuItem instanceof MenuItemClass) && - this.getParent().kitMenuItem.getMenu() && (this.getParent().kitMenuItem.getMenu() instanceof Menu) + this.getParent().hasOwnProperty('kitMenuItem') && (this.getParent().kitMenuItem instanceof MenuItemClass) ) { return this.getParent().kitMenuItem.getMenu(); } - return null; + return undefined; }; Menu.prototype.getParentMenuNode = function() { var parentMenu = this.getParentMenu(), @@ -194,6 +262,12 @@ kit.PluginManager.register('menu',function(module, exports, require) { return parentMenuNode; }; + /** + * + * @param options {kitMenuItemOptions} + * @param returnItem + * @return {Menu} + */ Menu.prototype.addItem = function (options = {}, returnItem = false) { var listIndex; if(options instanceof MenuItemClass) { @@ -262,7 +336,7 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.options.parent = parentNode; if(this.bInit) { - this.reInit(); + this.reInit(true); } }; Menu.prototype.setEventType = function(type = 'hover') { @@ -273,6 +347,12 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.reInit(); } }; + Menu.prototype.addDocumentEventListener = function() { + document.addEventListener('click', this.documentListenerHandler, false); + }; + Menu.prototype.removeDocumentEventListener = function() { + document.removeEventListener('click', this.documentListenerHandler, false); + }; Menu.prototype.removeParentEventListener = function() { // console.log('Menu: removeParentEventListener'); if(this.options.parent instanceof Element) { @@ -293,11 +373,21 @@ kit.PluginManager.register('menu',function(module, exports, require) { } } }; - Menu.prototype.initNodeHandlers = function() { - if(this.node) { - this.node.addEventListener('mouseenter', this.nodeActionHandler, false); - this.node.addEventListener('mouseleave', this.nodeActionHandler, false); + Menu.prototype.addNodeEventListener = function() { + if(!this.node) { + return; } + + this.node.addEventListener('mouseenter', this.nodeActionHandler, false); + this.node.addEventListener('mouseleave', this.nodeActionHandler, false); + }; + Menu.prototype.removeNodeEventListener = function() { + if(!this.node) { + return; + } + + this.node.removeEventListener('mouseenter', this.nodeActionHandler, false); + this.node.removeEventListener('mouseleave', this.nodeActionHandler, false); }; Menu.prototype.toggleParent = function() { this.node.classList.toggle('active'); @@ -324,7 +414,7 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.options.parent.append(this.getNode()); this.addParentEventListener(); - this.initNodeHandlers(); + this.addNodeEventListener(); //document.addEventListener('click', this.documentListenerHandler, false); @@ -332,15 +422,17 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.bInit = true; }; - Menu.prototype.reInit = function () { - //console.log('Menu: reInit ' + this.id); + Menu.prototype.reInit = function (recursiveCalcStyle = false) { + // console.warn('Menu: reInit ' + this.id); if(this.bInit === false) { return; } + this.removeNodeEventListener(); this.removeParentEventListener(); + //this.removeDocumentEventListener(); - document.removeEventListener('click', this.documentListenerHandler, false); + this.removeAnimation(); this.node.remove(); @@ -349,17 +441,18 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.options.parent.prepend(this.getNode()); if(this.bActive) { + this.calcStyle(recursiveCalcStyle); this.showNode(); } else { this.hideNode(); } + this.addNodeEventListener(); this.addParentEventListener(); - this.initNodeHandlers(); - - //document.addEventListener('click', this.documentListenerHandler, false); - + //this.addDocumentEventListener(); }; + + Menu.prototype.toggle = function() { if(this.toggleParent()) { this.showNode(); @@ -412,10 +505,16 @@ kit.PluginManager.register('menu',function(module, exports, require) { // console.log('documentListener'); // console.log(event); - if (this.needHideByParent(event.target)) { - this.toggle(); + if(this.options.eventType === 'click') { + if (this.needHideByParent(event.target)) { + this.toggle(); + } } }; + /** + * @param options {kitMenuClassDefaultOptions} + * @return {Menu} + */ Menu.prototype.setOptions = function (options = {}) { this.options = Object.assign({}, this.options, options); this.setParent(this.options.parent); @@ -431,16 +530,22 @@ kit.PluginManager.register('menu',function(module, exports, require) { this.bInit = false; this.bActive = false; this.child = null; + + /** + * @class kitMenuItemOptions + */ this.options = { id: '', - icon: libModule.icon.options, - arrow: libModule.icon.arrowMenu, + icon: libModule.svg.options, + arrow: libModule.svg.arrowMenu, label: 'menu', href: 'javascript:void(0);', class: 'kit-menu-item', sort: 500, visible: true, + /** @type {kitMenuItemHandler} */ hover: this.defaultHoverHandler, + /** @type {kitMenuItemHandler} */ click: this.defaultClickHandler, dblclick: this.defaultDblClickHandler, }; @@ -725,6 +830,15 @@ kit.PluginManager.register('menu',function(module, exports, require) { return Menu; })(); var getInstance = function(options = {}, items = []) { + if(options instanceof Menu) { + return options; + } + if(typeof options === 'string') { + options = document.querySelector(options); + } + if((options instanceof HTMLElement) && options.kit && options.kit.menu) { + return options.kit.menu; + } return new MenuClass(options, items); }; var getActiveMenuIdList = function(){ @@ -755,14 +869,14 @@ kit.PluginManager.register('menu',function(module, exports, require) { MenuList[id].calcStyle(); }); }; - var autoload = function(doc = document){ + var autoload = function(doc = document, selector = '.kit-menu'){ if(!(doc instanceof Node)) { return false; } - var menuList = doc.querySelectorAll('.' + defaultMenuOptions.class); + var menuList = doc.querySelectorAll(selector); menuList.forEach( function(menuNode, currentIndex, listObj) { - if(!menuNode.hasOwnProperty(defaultMenuOptions.nodeProperty)) { + if(!menuNode.kit || !menuNode.kit.hasOwnProperty(defaultMenuOptions.nodeProperty)) { } } @@ -777,11 +891,19 @@ kit.PluginManager.register('menu',function(module, exports, require) { }; window.addEventListener('resize', globalHandlers.resize); - this.Class = MenuClass; - this.getInstance = getInstance; - this.reInitAllMenu = reInitAllMenu; - this.reCalcAllMenu = reCalcAllMenu; - this.autoload = autoload; - return this; + /** + * @memberof kitCore + * @instance + */ + var menu = { + Class: MenuClass, + getInstance: getInstance, + reInitAllMenu: reInitAllMenu, + reCalcAllMenu: reCalcAllMenu, + autoload: autoload, + MenuList: MenuList, + }; + + return module.exports = menu; }); \ No newline at end of file diff --git a/assets/tippy/tippy.js b/assets/tippy/tippy.js new file mode 100644 index 0000000..359babc --- /dev/null +++ b/assets/tippy/tippy.js @@ -0,0 +1,2463 @@ +/**! + * tippy.js v6.3.1 + * (c) 2017-2021 atomiks + * MIT License + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) : + typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) : + (global = global || self, global.tippy = factory(global.Popper)); +}(this, (function (core) { 'use strict'; + + var css = ".tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:\"\";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}"; + + function injectCSS(css) { + var style = document.createElement('style'); + style.textContent = css; + style.setAttribute('data-tippy-stylesheet', ''); + var head = document.head; + var firstStyleOrLinkTag = document.querySelector('head>style,head>link'); + + if (firstStyleOrLinkTag) { + head.insertBefore(style, firstStyleOrLinkTag); + } else { + head.appendChild(style); + } + } + + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; + var ua = isBrowser ? navigator.userAgent : ''; + var isIE = /MSIE |Trident\//.test(ua); + + var ROUND_ARROW = ''; + var BOX_CLASS = "tippy-box"; + var CONTENT_CLASS = "tippy-content"; + var BACKDROP_CLASS = "tippy-backdrop"; + var ARROW_CLASS = "tippy-arrow"; + var SVG_ARROW_CLASS = "tippy-svg-arrow"; + var TOUCH_OPTIONS = { + passive: true, + capture: true + }; + + function hasOwnProperty(obj, key) { + return {}.hasOwnProperty.call(obj, key); + } + function getValueAtIndexOrReturn(value, index, defaultValue) { + if (Array.isArray(value)) { + var v = value[index]; + return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v; + } + + return value; + } + function isType(value, type) { + var str = {}.toString.call(value); + return str.indexOf('[object') === 0 && str.indexOf(type + "]") > -1; + } + function invokeWithArgsOrReturn(value, args) { + return typeof value === 'function' ? value.apply(void 0, args) : value; + } + function debounce(fn, ms) { + // Avoid wrapping in `setTimeout` if ms is 0 anyway + if (ms === 0) { + return fn; + } + + var timeout; + return function (arg) { + clearTimeout(timeout); + timeout = setTimeout(function () { + fn(arg); + }, ms); + }; + } + function removeProperties(obj, keys) { + var clone = Object.assign({}, obj); + keys.forEach(function (key) { + delete clone[key]; + }); + return clone; + } + function splitBySpaces(value) { + return value.split(/\s+/).filter(Boolean); + } + function normalizeToArray(value) { + return [].concat(value); + } + function pushIfUnique(arr, value) { + if (arr.indexOf(value) === -1) { + arr.push(value); + } + } + function unique(arr) { + return arr.filter(function (item, index) { + return arr.indexOf(item) === index; + }); + } + function getBasePlacement(placement) { + return placement.split('-')[0]; + } + function arrayFrom(value) { + return [].slice.call(value); + } + function removeUndefinedProps(obj) { + return Object.keys(obj).reduce(function (acc, key) { + if (obj[key] !== undefined) { + acc[key] = obj[key]; + } + + return acc; + }, {}); + } + + function div() { + return document.createElement('div'); + } + function isElement(value) { + return ['Element', 'Fragment'].some(function (type) { + return isType(value, type); + }); + } + function isNodeList(value) { + return isType(value, 'NodeList'); + } + function isMouseEvent(value) { + return isType(value, 'MouseEvent'); + } + function isReferenceElement(value) { + return !!(value && value._tippy && value._tippy.reference === value); + } + function getArrayOfElements(value) { + if (isElement(value)) { + return [value]; + } + + if (isNodeList(value)) { + return arrayFrom(value); + } + + if (Array.isArray(value)) { + return value; + } + + return arrayFrom(document.querySelectorAll(value)); + } + function setTransitionDuration(els, value) { + els.forEach(function (el) { + if (el) { + el.style.transitionDuration = value + "ms"; + } + }); + } + function setVisibilityState(els, state) { + els.forEach(function (el) { + if (el) { + el.setAttribute('data-state', state); + } + }); + } + function getOwnerDocument(elementOrElements) { + var _element$ownerDocumen; + + var _normalizeToArray = normalizeToArray(elementOrElements), + element = _normalizeToArray[0]; // Elements created via a