From 67ba5205e22a66bdd457ff3698d26bc3ff2fad0e Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 20 Dec 2018 10:08:22 +0100 Subject: [PATCH] js: Upgrade Sortable.js to latest version (1.8.0-rc1) --- configuration.php | 1 + public/js/vendor/Sortable.js | 1940 ++++++++++++++++++++ public/js/vendor/jquery.fn.sortable.js | 1712 +---------------- public/js/vendor/jquery.fn.sortable.min.js | 3 - 4 files changed, 1983 insertions(+), 1673 deletions(-) create mode 100644 public/js/vendor/Sortable.js delete mode 100644 public/js/vendor/jquery.fn.sortable.min.js diff --git a/configuration.php b/configuration.php index 358287d..f09ee04 100644 --- a/configuration.php +++ b/configuration.php @@ -58,5 +58,6 @@ $this->provideRestriction( $this->translate('Restrict access to configurations with the given prefix') ); +$this->provideJsFile('vendor/Sortable.js'); $this->provideJsFile('behavior/sortable.js'); $this->provideJsFile('vendor/jquery.fn.sortable.js'); \ No newline at end of file diff --git a/public/js/vendor/Sortable.js b/public/js/vendor/Sortable.js new file mode 100644 index 0000000..33e639a --- /dev/null +++ b/public/js/vendor/Sortable.js @@ -0,0 +1,1940 @@ +/**! + * Sortable + * @author RubaXa + * @author owenm + * @license MIT + */ + +(function sortableModule(factory) { + "use strict"; + + if (typeof define === "function" && define.amd) { + define(factory); + } + else if (typeof module != "undefined" && typeof module.exports != "undefined") { + module.exports = factory(); + } + else { + /* jshint sub:true */ + window["Sortable"] = factory(); + } +})(function sortableFactory() { + "use strict"; + + if (typeof window === "undefined" || !window.document) { + return function sortableError() { + throw new Error("Sortable.js requires a window with a document"); + }; + } + + var dragEl, + parentEl, + ghostEl, + cloneEl, + rootEl, + nextEl, + lastDownEl, + + scrollEl, + scrollParentEl, + scrollCustomFn, + + oldIndex, + newIndex, + + activeGroup, + putSortable, + + autoScrolls = [], + scrolling = false, + + pointerElemChangedInterval, + lastPointerElemX, + lastPointerElemY, + + tapEvt, + touchEvt, + + moved, + + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + + forRepaintDummy, + realDragElRect, // dragEl rect after current animation + + /** @const */ + R_SPACE = /\s+/g, + + expando = 'Sortable' + (new Date).getTime(), + + win = window, + document = win.document, + parseInt = win.parseInt, + setTimeout = win.setTimeout, + + $ = win.jQuery || win.Zepto, + Polymer = win.Polymer, + + captureMode = { + capture: false, + passive: false + }, + + supportDraggable = ('draggable' in document.createElement('div')), + supportCssPointerEvents = (function (el) { + // false when IE11 + if (!!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie)/i)) { + return false; + } + el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + })(), + + _silent = false, + _alignedSilent = false, + + abs = Math.abs, + min = Math.min, + + savedInputChecked = [], + touchDragOverListeners = [], + + alwaysFalse = function () { return false; }, + + _detectDirection = function(el, options) { + var elCSS = _css(el), + elWidth = parseInt(elCSS.width), + child1 = _getChild(el, 0, options), + child2 = _getChild(el, 1, options), + firstChildCSS = child1 && _css(child1), + secondChildCSS = child2 && _css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + child1.getBoundingClientRect().width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + child2.getBoundingClientRect().width + ; + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' + ? 'vertical' : 'horizontal'; + } + return (child1 && + ( + firstChildCSS.display === 'block' || + firstChildCSS.display === 'grid' || + firstChildWidth >= elWidth && + elCSS.float === 'none' || + child2 && + elCSS.float === 'none' && + firstChildWidth + secondChildWidth > elWidth + ) ? + 'vertical' : 'horizontal' + ); + }, + + _isInRowColumn = function(x, y, el, axis, options) { + var targetRect = realDragElRect || dragEl.getBoundingClientRect(), + targetS1Opp = axis === 'vertical' ? targetRect.left : targetRect.top, + targetS2Opp = axis === 'vertical' ? targetRect.right : targetRect.bottom, + mouseOnOppAxis = axis === 'vertical' ? x : y + ; + + return targetS1Opp < mouseOnOppAxis && mouseOnOppAxis < targetS2Opp; + }, + + _getParentAutoScrollElement = function(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return win; + + var elem = el; + var gotSelf = false; + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = _css(elem); + if ( + elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || + elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll') + ) { + if (!elem || !elem.getBoundingClientRect || elem === document.body) return win; + + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + } while (elem = elem.parentNode); + + return win; + }, + + _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl, /**Boolean*/isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (options.scroll) { + var _this = rootEl ? rootEl[expando] : window, + rect, + css, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + + x = evt.clientX, + y = evt.clientY, + + winWidth = window.innerWidth, + winHeight = window.innerHeight, + + vx, + vy, + + scrollThisInstance = false + ; + + // Detect scrollEl + if (scrollParentEl !== rootEl) { + _clearAutoScrolls(); + + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = _getParentAutoScrollElement(rootEl, true); + scrollParentEl = scrollEl; + } + } + + + var layersOut = 0; + var currentParent = scrollEl; + do { + var el; + + if (currentParent && currentParent !== win) { + el = currentParent; + css = _css(el); + rect = currentParent.getBoundingClientRect(); + vx = el.clientWidth < el.scrollWidth && (css.overflowX == 'auto' || css.overflowX == 'scroll') && + ((abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens)); + + vy = el.clientHeight < el.scrollHeight && (css.overflowY == 'auto' || css.overflowY == 'scroll') && + ((abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens)); + } else if (currentParent === win) { + el = win; + vx = (winWidth - x <= sens) - (x <= sens); + vy = (winHeight - y <= sens) - (y <= sens); + } + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + + clearInterval(autoScrolls[layersOut].pid); + + if (el && (vx != 0 || vy != 0)) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + autoScrolls[layersOut].pid = setInterval((function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._emulateDragOver(true); + } + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if ('function' === typeof(scrollCustomFn)) { + if (scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + if (autoScrolls[this.layer].el === win) { + win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); + } else { + autoScrolls[this.layer].el.scrollTop += scrollOffsetY; + autoScrolls[this.layer].el.scrollLeft += scrollOffsetX; + } + }).bind({layer: layersOut}), 24); + } + } + layersOut++; + } while (options.bubbleScroll && currentParent !== win && (currentParent = _getParentAutoScrollElement(currentParent, false))); + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not + } + }, 30), + + _clearAutoScrolls = function () { + autoScrolls.forEach(function(autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; + }, + + _prepareGroup = function (options) { + function toFn(value, pull) { + return function(to, from, dragEl, evt) { + var ret; + + if (value == null && pull) { + ret = true; // default pull value: true (backwards compatibility) + } else if (value == null || value === false) { + ret = false; + } else if (pull && value === 'clone') { + ret = value; + } else if (typeof value === 'function') { + ret = value(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + + ret = (value === true || + (typeof value === 'string' && value === otherGroup) || + (value.join && value.indexOf(otherGroup) > -1)); + } + return ret || (to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name); + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || typeof originalGroup != 'object') { + originalGroup = {name: originalGroup}; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + + options.group = group; + }, + + _checkAlignment = function(evt) { + if (!dragEl) return; + dragEl.parentNode[expando] && dragEl.parentNode[expando]._computeIsAligned(evt); + } + ; + + + /** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); + } + + this.el = el; // root element + this.options = options = _extend({}, options); + + + // Export instance + el[expando] = this; + + // Default options + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true, + draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', + + swapThreshold: 1, // percentage; 0 <= x <= 1 + invertSwap: false, // invert always + invertedSwapThreshold: null, // will be set to same as swapThreshold if default + + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + setData: function (dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + touchStartThreshold: parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: {x: 0, y: 0}, + supportPointer: Sortable.supportPointer !== false && ( + ('PointerEvent' in window) || + window.navigator && ('msPointerEnabled' in window.navigator) // microsoft + ) + }; + + + // Set default options + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + if (!('direction' in options)) { + options.direction = function() { + return _detectDirection(el, options); + }; + } + + _prepareGroup(options); + + options.invertedSwapThreshold == null && (options.invertedSwapThreshold = options.swapThreshold); + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + // Setup drag mode + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + // Bind events + _on(el, 'mousedown', this._onTapStart); + _on(el, 'touchstart', this._onTapStart); + options.supportPointer && _on(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + _on(el, 'dragover', this); + _on(el, 'dragenter', this); + } + + touchDragOverListeners.push(this._onDragOver); + + // Restore sorting + options.store && options.store.get && this.sort(options.store.get(this) || []); + } + + Sortable.prototype = /** @lends Sortable.prototype */ { + constructor: Sortable, + + // is mouse aligned with dragEl? + _isAligned: true, + + _computeIsAligned: function(evt, isDragEl) { + if (_alignedSilent) return; + if (!dragEl || dragEl.parentNode !== this.el) return; + if (isDragEl !== true && isDragEl !== false) { + isDragEl = !!_closest(evt.target, null, dragEl, true); + } + this._isAligned = !scrolling && (isDragEl || this._isAligned && _isInRowColumn(evt.clientX, evt.clientY, this.el, this._getDirection(evt, null), this.options)); + _alignedSilent = true; + setTimeout(function() { + _alignedSilent = false; + }, 30); + }, + + _getDirection: function(evt, target) { + return (typeof this.options.direction === 'function') ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + + _onTapStart: function (/** Event|TouchEvent */evt) { + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0], + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && ((evt.path && evt.path[0]) || (evt.composedPath && evt.composedPath()[0])) || target, + filter = options.filter, + startIndex; + + _saveInputCheckedState(el); + + + // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button or enabled + } + + // cancel dnd if original target is content editable + if (originalTarget.isContentEditable) { + return; + } + + target = _closest(target, options.draggable, el, true); + + if (!target) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } + + // Get the index of the dragged element within its parent + startIndex = _index(target, options.draggable); + + // Check filter + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent(_this, originalTarget, 'filter', target, el, el, startIndex); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = _closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent(_this, criteria, 'filter', target, el, el, startIndex); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !_closest(originalTarget, options.handle, el, false)) { + return; + } + + // Prepare `dragstart` + this._prepareDragStart(evt, touch, target, startIndex); + }, + + + _handleAutoScroll: function(evt, fallback) { + if (!dragEl || !this.options.scroll) return; + var x = evt.clientX, + y = evt.clientY, + + elem = document.elementFromPoint(x, y), + _this = this + ; + + // firefox does not have native autoscroll + if (fallback || (window.navigator && window.navigator.userAgent.toLowerCase().indexOf('firefox') > -1)) { + _autoScroll(evt, _this.options, elem, true); + + // Listener for pointer element change + var ogElemScroller = _getParentAutoScrollElement(elem, true); + if ( + scrolling && + ( + !pointerElemChangedInterval || + x !== lastPointerElemX || + y !== lastPointerElemY + ) + ) { + + pointerElemChangedInterval && clearInterval(pointerElemChangedInterval); + // Detect for pointer elem change, emulating native DnD behaviour + pointerElemChangedInterval = setInterval(function() { + if (!dragEl) return; + // could also check if scroll direction on newElem changes due to parent autoscrolling + var newElem = _getParentAutoScrollElement(document.elementFromPoint(x, y), true); + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + _clearAutoScrolls(); + _autoScroll(evt, _this.options, ogElemScroller, true); + } + }, 10); + lastPointerElemX = x; + lastPointerElemY = y; + } + + } else { + // if DnD is enabled (not on firefox), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!_this.options.bubbleScroll || _getParentAutoScrollElement(elem, true) === window) { + _clearAutoScrolls(); + return; + } + _autoScroll(evt, _this.options, _getParentAutoScrollElement(elem, false)); + } + }, + + _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && (target.parentNode === el)) { + tapEvt = evt; + + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + oldIndex = startIndex; + + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + + dragEl.style['will-change'] = 'all'; + + dragStartFn = function () { + // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + _this._disableDelayedDrag(); + + // Make the element draggable + dragEl.draggable = _this.nativeDraggable; + + // Bind the events: dragstart/dragend + _this._triggerDragStart(evt, touch); + + // Drag start event + _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, rootEl, oldIndex); + + // Chosen item + _toggleClass(dragEl, options.chosenClass, true); + }; + + // Disable "draggable" + options.ignore.split(',').forEach(function (criteria) { + _find(dragEl, criteria.trim(), _disableDraggable); + }); + + _on(ownerDocument, 'mouseup', _this._onDrop); + _on(ownerDocument, 'touchend', _this._onDrop); + _on(ownerDocument, 'touchcancel', _this._onDrop); + options.supportPointer && _on(ownerDocument, 'pointercancel', _this._onDrop); + + if (options.delay) { + // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + _on(ownerDocument, 'touchend', _this._disableDelayedDrag); + _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + _on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + _on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && _on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + + _this._dragStartTimer = setTimeout(dragStartFn.bind(_this), options.delay); + } else { + dragStartFn(); + } + + + } + }, + + _delayedDragTouchMoveHandler: function (/** TouchEvent|PointerEvent **/e) { + var touch = e.touches ? e.touches[0] : e; + if (min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) + >= this.options.touchStartThreshold + ) { + this._disableDelayedDrag(); + } + }, + + _disableDelayedDrag: function () { + var ownerDocument = this.el.ownerDocument; + + clearTimeout(this._dragStartTimer); + _off(ownerDocument, 'mouseup', this._disableDelayedDrag); + _off(ownerDocument, 'touchend', this._disableDelayedDrag); + _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + _off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + _off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + _off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + + _triggerDragStart: function (/** Event */evt, /** Touch */touch) { + touch = touch || (evt.pointerType == 'touch' ? evt : null); + + + if (touch) { + // Touch device support + tapEvt = { + target: dragEl, + clientX: touch.clientX, + clientY: touch.clientY + }; + + this._onDragStart(tapEvt, 'touch'); + } + else if (!this.nativeDraggable) { + this._onDragStart(tapEvt, true); + } + else { + _on(dragEl, 'dragend', this); + _on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) { + } + }, + + _dragStarted: function () { + if (rootEl && dragEl) { + if (this.nativeDraggable) { + _on(document, 'dragover', this._handleAutoScroll); + _on(document, 'dragover', _checkAlignment); + } + var options = this.options; + + // Apply effect + _toggleClass(dragEl, options.dragClass, false); + _toggleClass(dragEl, options.ghostClass, true); + + _css(dragEl, 'transform', ''); + + Sortable.active = this; + + this._isAligned = true; + + // Drag start event + _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, rootEl, oldIndex); + } else { + this._nulling(); + } + }, + + _emulateDragOver: function (bypassLastTouchCheck) { + if (touchEvt) { + if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY && !bypassLastTouchCheck) { + return; + } + + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', 'none'); + } + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + var isDragEl = !!_closest(target, null, dragEl, true); + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + parent = target; + } + + if (parent) { + do { + if (parent[expando]) { + var i = touchDragOverListeners.length; + while (i--) { + touchDragOverListeners[i]({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + } + + if (!this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + dragEl.parentNode[expando]._computeIsAligned(touchEvt, isDragEl); + + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', ''); + } + } + }, + + + _onTouchMove: function (/**TouchEvent*/evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x, + dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y, + translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; + + // prevent duplicate event firing + if (this.options.supportPointer && evt.type === 'touchmove') return; + + // only set the status to dragging, when we are actually dragging + if (!Sortable.active) { + if (fallbackTolerance && + min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance + ) { + return; + } + + this._dragStarted(); + } + + // as well as creating the ghost element on the document body + this._appendGhost(); + + this._handleAutoScroll(touch, true); + + + moved = true; + touchEvt = touch; + + _css(ghostEl, 'webkitTransform', translate3d); + _css(ghostEl, 'mozTransform', translate3d); + _css(ghostEl, 'msTransform', translate3d); + _css(ghostEl, 'transform', translate3d); + + evt.cancelable && evt.preventDefault(); + } + }, + + _appendGhost: function () { + if (!ghostEl) { + var rect = dragEl.getBoundingClientRect(), + css = _css(dragEl), + options = this.options; + + ghostEl = dragEl.cloneNode(true); + + _toggleClass(ghostEl, options.ghostClass, false); + _toggleClass(ghostEl, options.fallbackClass, true); + _toggleClass(ghostEl, options.dragClass, true); + + _css(ghostEl, 'box-sizing', 'border-box'); + _css(ghostEl, 'margin', 0); + _css(ghostEl, 'top', rect.top); + _css(ghostEl, 'left', rect.left); + _css(ghostEl, 'width', rect.width); + _css(ghostEl, 'height', rect.height); + _css(ghostEl, 'opacity', '0.8'); + _css(ghostEl, 'position', 'fixed'); + _css(ghostEl, 'zIndex', '100000'); + _css(ghostEl, 'pointerEvents', 'none'); + + options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); + } + }, + + _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { + var _this = this; + var dataTransfer = evt.dataTransfer; + var options = _this.options; + + _this._offUpEvents(); + if (activeGroup.checkPull(_this, _this, dragEl, evt)) { + cloneEl = _clone(dragEl); + + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + _toggleClass(cloneEl, _this.options.chosenClass, false); + + // #1143: IFrame support workaround + _this._cloneId = _nextTick(function () { + rootEl.insertBefore(cloneEl, dragEl); + _dispatchEvent(_this, rootEl, 'clone', dragEl); + }); + } + + _toggleClass(dragEl, options.dragClass, true); + + if (useFallback) { + if (useFallback === 'touch') { + // Fixed #973: + _on(document, 'touchmove', _preventScroll); + + // Bind touch events + _on(document, 'touchmove', _this._onTouchMove); + _on(document, 'touchend', _this._onDrop); + _on(document, 'touchcancel', _this._onDrop); + + if (options.supportPointer) { + _on(document, 'pointermove', _this._onTouchMove); + _on(document, 'pointerup', _this._onDrop); + } + } else { + // Old brwoser + _on(document, 'mousemove', _this._onTouchMove); + _on(document, 'mouseup', _this._onDrop); + } + + _this._loopId = setInterval(_this._emulateDragOver, 50); + _toggleClass(dragEl, options.dragClass, false); + } + else { + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + _on(document, 'drop', _this); + + // #1276 fix: + _css(dragEl, 'transform', 'translateZ(0)'); + + _this._dragStartId = _nextTick(_this._dragStarted); + } + _on(document, 'selectstart', _this); + }, + + _onDragOver: function (/**Event*/evt) { + var el = this.el, + target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = (activeGroup === group), + isMovingBetweenSortable = false, + canSort = options.sort + ; + + + if (evt.rootEl !== void 0 && evt.rootEl !== this.el) return; // touch fallback + + // no bubbling and not fallback + if (!options.dragoverBubble && !evt.rootEl) { + this._handleAutoScroll(evt); + dragEl.parentNode[expando]._computeIsAligned(evt); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + !options.dragoverBubble && evt.stopPropagation(); + } + + + moved = true; + + target = _closest(evt.target, options.draggable, el, true); + + + if (dragEl.animated && target === dragEl || target.animated || _silent) { + return; + } + + + if (target !== lastTarget) { + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + lastTarget = null; + } + + + if (activeSortable && !options.disabled && + (isOwner + ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : ( + putSortable === this || + ( + (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && + group.checkPut(this, activeSortable, dragEl, evt) + ) + ) + ) + ) { + var direction; + var axis = this._getDirection(evt, target); + + + dragRect = dragEl.getBoundingClientRect(); + + if (putSortable !== this && this !== Sortable.active) { + putSortable = this; + isMovingBetweenSortable = true; + } else if (this === Sortable.active) { + isMovingBetweenSortable = false; + putSortable = null; + } + + if (revert) { + this._hideClone(); + parentEl = rootEl; // actualization + + if (cloneEl || nextEl) { + rootEl.insertBefore(dragEl, cloneEl || nextEl); + } + else if (!canSort) { + rootEl.appendChild(dragEl); + } + + return; + } + + if ((el.children.length === 0) || (el.children[0] === ghostEl) || + (el === evt.target) && _ghostIsLast(evt, axis, el) + ) { + //assign target only if condition is true + if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) { + target = _lastChild(el); + } + + if (target) { + if (target.animated) { + return; + } + + targetRect = target.getBoundingClientRect(); + } + + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(this); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + if (!dragEl.contains(el)) { + el.appendChild(dragEl); + parentEl = el; // actualization + this._isAligned = true; // must be for _ghostIsLast to pass + realDragElRect = null; + } + + this._animate(dragRect, dragEl); + target && this._animate(targetRect, target); + } + } + else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0) && target !== el) { + + isCircumstantialInvert = isCircumstantialInvert || options.invertSwap || dragEl.parentNode !== el || !this._isAligned; + direction = _getSwapDirection(evt, target, axis, + options.swapThreshold, options.invertedSwapThreshold, + isCircumstantialInvert, + lastTarget === target); + if (direction === 0) return; + realDragElRect = null; + + + this._isAligned = true; + + if (!lastTarget || lastTarget !== target && (!target || !target.animated)) { + pastFirstInvertThresh = false; + lastTarget = target; + } + + + lastDirection = direction; + + targetRect = target.getBoundingClientRect(); + + var nextSibling = target.nextElementSibling, + after = false + ; + + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = (moveVector === 1); + } + + _silent = true; + setTimeout(_unsilent, 30); + + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(this); + } + + if (!dragEl.contains(el)) { + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } + } + + parentEl = dragEl.parentNode; // actualization + + this._animate(dragRect, dragEl); + this._animate(targetRect, target); + } + } + } + }, + + _animate: function (prevRect, target) { + var ms = this.options.animation; + + if (ms) { + var currentRect = target.getBoundingClientRect(); + + if (target === dragEl) { + realDragElRect = currentRect; + } + + if (prevRect.nodeType === 1) { + prevRect = prevRect.getBoundingClientRect(); + } + + // Check if actually moving position + if ((prevRect.left + prevRect.width / 2) === (currentRect.left + currentRect.width / 2) + && (prevRect.top + prevRect.height / 2) === (currentRect.top + currentRect.height / 2) + ) return; + + _css(target, 'transition', 'none'); + _css(target, 'transform', 'translate3d(' + + (prevRect.left - currentRect.left) + 'px,' + + (prevRect.top - currentRect.top) + 'px,0)' + ); + + forRepaintDummy = target.offsetWidth; // repaint + + _css(target, 'transition', 'all ' + ms + 'ms'); + _css(target, 'transform', 'translate3d(0,0,0)'); + + clearTimeout(target.animated); + target.animated = setTimeout(function () { + _css(target, 'transition', ''); + _css(target, 'transform', ''); + target.animated = false; + }, ms); + } + }, + + _offUpEvents: function () { + var ownerDocument = this.el.ownerDocument; + + _off(document, 'touchmove', _preventScroll); + _off(document, 'touchmove', this._onTouchMove); + _off(document, 'pointermove', this._onTouchMove); + _off(ownerDocument, 'mouseup', this._onDrop); + _off(ownerDocument, 'touchend', this._onDrop); + _off(ownerDocument, 'pointerup', this._onDrop); + _off(ownerDocument, 'touchcancel', this._onDrop); + _off(ownerDocument, 'pointercancel', this._onDrop); + _off(document, 'selectstart', this); + }, + + _onDrop: function (/**Event*/evt) { + var el = this.el, + options = this.options; + scrolling = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + + clearInterval(this._loopId); + + clearInterval(pointerElemChangedInterval); + _clearAutoScrolls(); + _cancelThrottle(); + + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this._cloneId); + _cancelNextTick(this._dragStartId); + + // Unbind events + _off(document, 'mousemove', this._onTouchMove); + + + if (this.nativeDraggable) { + _off(document, 'drop', this); + _off(el, 'dragstart', this._onDragStart); + _off(document, 'dragover', this._handleAutoScroll); + _off(document, 'dragover', _checkAlignment); + } + + this._offUpEvents(); + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) { + // Remove clone + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + _off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + dragEl.style['will-change'] = ''; + + // Remove class's + _toggleClass(dragEl, this.options.ghostClass, false); + _toggleClass(dragEl, this.options.chosenClass, false); + + // Drag stop event + _dispatchEvent(this, rootEl, 'unchoose', dragEl, parentEl, rootEl, oldIndex, null, evt); + + if (rootEl !== parentEl) { + newIndex = _index(dragEl, options.draggable); + + if (newIndex >= 0) { + // Add event + _dispatchEvent(null, parentEl, 'add', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + + // Remove event + _dispatchEvent(this, rootEl, 'remove', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + + // drag from one list and drop into another + _dispatchEvent(null, parentEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + } + + putSortable && putSortable.save(); + } + else { + if (dragEl.nextSibling !== nextEl) { + // Get the index of the dragged element within its parent + newIndex = _index(dragEl, options.draggable); + + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent(this, rootEl, 'update', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + } + + _dispatchEvent(this, rootEl, 'end', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + + // Save sorting + this.save(); + } + } + + } + this._nulling(); + }, + + _nulling: function() { + rootEl = + dragEl = + parentEl = + ghostEl = + nextEl = + cloneEl = + lastDownEl = + + scrollEl = + scrollParentEl = + autoScrolls.length = + + pointerElemChangedInterval = + lastPointerElemX = + lastPointerElemY = + + tapEvt = + touchEvt = + + moved = + newIndex = + oldIndex = + + lastTarget = + lastDirection = + + forRepaintDummy = + realDragElRect = + + putSortable = + activeGroup = + Sortable.active = null; + + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = 0; + }, + + handleEvent: function (/**Event*/evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + _globalDragOver(evt); + } + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function () { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + if (_closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function (order) { + var items = {}, rootEl = this.el; + + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (_closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + + /** + * Save the current sorting + */ + save: function () { + var store = this.options.store; + store && store.set && store.set(this); + }, + + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function (el, selector) { + return _closest(el, selector || this.options.draggable, this.el, false); + }, + + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function (name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + options[name] = value; + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + + /** + * Destroy + */ + destroy: function () { + var el = this.el; + + el[expando] = null; + + _off(el, 'mousedown', this._onTapStart); + _off(el, 'touchstart', this._onTapStart); + _off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + _off(el, 'dragover', this); + _off(el, 'dragenter', this); + } + // Remove draggable attributes + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); + + this._onDrop(); + + this.el = el = null; + }, + + _hideClone: function() { + if (!cloneEl.cloneHidden) { + _css(cloneEl, 'display', 'none'); + cloneEl.cloneHidden = true; + } + }, + + _showClone: function(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + return; + } + + if (cloneEl.cloneHidden) { + // show clone at dragEl or original position + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this._animate(dragEl, cloneEl); + } + _css(cloneEl, 'display', ''); + cloneEl.cloneHidden = false; + } + } + }; + + function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector) || (includeCTX && el === ctx)) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = _getParentOrHost(el)); + } + + return null; + } + + + function _getParentOrHost(el) { + return (el.host && el !== document && el.host.nodeType) + ? el.host + : el.parentNode; + } + + + function _globalDragOver(/**Event*/evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + evt.cancelable && evt.preventDefault(); + } + + + function _on(el, event, fn) { + el.addEventListener(event, fn, captureMode); + } + + + function _off(el, event, fn) { + el.removeEventListener(event, fn, captureMode); + } + + + function _toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } + else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } + } + + + function _css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } + else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } + else { + if (!(prop in style)) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } + } + + + function _find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; + } + + + + function _dispatchEvent(sortable, rootEl, name, targetEl, toEl, fromEl, startIndex, newIndex, originalEvt) { + sortable = (sortable || rootEl[expando]); + + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + // Support for new CustomEvent feature + if (window.CustomEvent) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + + evt.oldIndex = startIndex; + evt.newIndex = newIndex; + + evt.originalEvent = originalEvt; + + rootEl.dispatchEvent(evt); + + if (options[onName]) { + options[onName].call(sortable, evt); + } + } + + + function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; + // Support for new CustomEvent feature + if (window.CustomEvent) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + evt.willInsertAfter = willInsertAfter; + + evt.originalEvent = originalEvt; + + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvt); + } + + return retVal; + } + + function _disableDraggable(el) { + el.draggable = false; + } + + function _unsilent() { + _silent = false; + } + + function _getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children + ; + while (i < children.length) { + if ( + children[i].style.display !== 'none' && + children[i] !== ghostEl && + children[i] !== dragEl && + _closest(children[i], options.draggable, el, false) + ) { + if (currentChild === childNum) { + return children[i]; + } + currentChild++; + } + + i++; + } + return null; + } + + function _lastChild(el) { + var last = el.lastElementChild; + + if (last === ghostEl) { + last = el.children[el.childElementCount - 2]; + } + + return last || null; + } + + function _ghostIsLast(evt, axis, el) { + var elRect = _lastChild(el).getBoundingClientRect(), + mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, + mouseOnOppAxis = axis === 'vertical' ? evt.clientX : evt.clientY, + targetS2 = axis === 'vertical' ? elRect.bottom : elRect.right, + targetS1Opp = axis === 'vertical' ? elRect.left : elRect.top, + targetS2Opp = axis === 'vertical' ? elRect.right : elRect.bottom + ; + return ( + mouseOnOppAxis > targetS1Opp && + mouseOnOppAxis < targetS2Opp && + mouseOnAxis > targetS2 + ); + } + + function _getSwapDirection(evt, target, axis, swapThreshold, invertedSwapThreshold, invertSwap, inside) { + var targetRect = target.getBoundingClientRect(), + mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, + targetLength = axis === 'vertical' ? targetRect.height : targetRect.width, + targetS1 = axis === 'vertical' ? targetRect.top : targetRect.left, + targetS2 = axis === 'vertical' ? targetRect.bottom : targetRect.right, + dragRect = dragEl.getBoundingClientRect(), + dragLength = axis === 'vertical' ? dragRect.height : dragRect.width, + invert = false + ; + var dragStyle = _css(dragEl); + dragLength += parseInt(dragStyle.marginLeft) + parseInt(dragStyle.marginRight); + + if (!invertSwap) { + // Never invert or create dragEl shadow when width causes mouse to move past the end of regular swapThreshold + if (inside && dragLength < targetLength * swapThreshold) { // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && + (lastDirection === 1 ? + ( + mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 + ) : + ( + mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2 + ) + ) + ) + { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + var dragS1 = axis === 'vertical' ? dragRect.top : dragRect.left, + dragS2 = axis === 'vertical' ? dragRect.bottom : dragRect.right + ; + // dragEl shadow + if ( + lastDirection === 1 ? + ( + mouseOnAxis < targetS1 + dragLength // over dragEl shadow + ) : + ( + mouseOnAxis > targetS2 - dragLength + ) + ) + { + return lastDirection * -1; + } + } else { + invert = true; + } + } else { + // Regular + if ( + mouseOnAxis > targetS1 + (targetLength * (1 - swapThreshold) / 2) && + mouseOnAxis < targetS2 - (targetLength * (1 - swapThreshold) / 2) + ) { + return ((mouseOnAxis > targetS1 + targetLength / 2) ? -1 : 1); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if ( + mouseOnAxis < targetS1 + (targetLength * invertedSwapThreshold / 2) || + mouseOnAxis > targetS2 - (targetLength * invertedSwapThreshold / 2) + ) + { + return ((mouseOnAxis > targetS1 + targetLength / 2) ? 1 : -1); + } + } + + return 0; + } + + + /** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); + } + + /** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + function _index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + + while (el && (el = el.previousElementSibling)) { + if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) { + index++; + } + } + + return index; + } + + function _matches(/**HTMLElement*/el, /**String*/selector) { + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } + } catch(_) { + return false; + } + } + + return false; + } + + var _throttleTimeout; + function _throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this + ; + + _throttleTimeout = setTimeout(function () { + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = void 0; + }, ms); + } + }; + } + + function _cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; + } + + function _extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; + } + + function _clone(el) { + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } + else if ($) { + return $(el).clone(true)[0]; + } + else { + return el.cloneNode(true); + } + } + + function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } + } + + function _nextTick(fn) { + return setTimeout(fn, 0); + } + + function _cancelNextTick(id) { + return clearTimeout(id); + } + + function _preventScroll(evt) { + if (Sortable.active && evt.cancelable) { + evt.preventDefault(); + } + } + + + // Export utils + Sortable.utils = { + on: _on, + off: _off, + css: _css, + find: _find, + is: function (el, selector) { + return !!_closest(el, selector, el, false); + }, + extend: _extend, + throttle: _throttle, + closest: _closest, + toggleClass: _toggleClass, + clone: _clone, + index: _index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: _getChild + }; + + + /** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + Sortable.create = function (el, options) { + return new Sortable(el, options); + }; + + + // Export + Sortable.version = '1.8.0-rc1'; + return Sortable; +}); \ No newline at end of file diff --git a/public/js/vendor/jquery.fn.sortable.js b/public/js/vendor/jquery.fn.sortable.js index d2b308c..cd5189a 100644 --- a/public/js/vendor/jquery.fn.sortable.js +++ b/public/js/vendor/jquery.fn.sortable.js @@ -1,1674 +1,51 @@ -/** - * jQuery plugin for Sortable - * @author RubaXa - * @license MIT - */ (function (factory) { "use strict"; - - if (typeof define === "function" && define.amd) { - define(["jquery"], factory); - } - else { - /* jshint sub:true */ - factory(jQuery); - } -})(function ($) { - "use strict"; - - - var dragEl, - parentEl, - ghostEl, - cloneEl, - rootEl, - nextEl, - lastDownEl, - - scrollEl, - scrollParentEl, - scrollCustomFn, - - lastEl, - lastCSS, - lastParentCSS, - - oldIndex, - newIndex, - - activeGroup, - putSortable, - - autoScrolls = [], - - pointerElemChangedInterval, - lastPointerElemX, - lastPointerElemY, - - tapEvt, - touchEvt, - - moved, - - forRepaintDummy, - - /** @const */ - R_SPACE = /\s+/g, - R_FLOAT = /left|right|inline/, - - expando = 'Sortable' + (new Date).getTime(), - - win = window, - document = win.document, - parseInt = win.parseInt, - setTimeout = win.setTimeout, - - $ = win.jQuery || win.Zepto, - Polymer = win.Polymer, - - captureMode = false, - passiveMode = false, - - supportDraggable = ('draggable' in document.createElement('div')), - supportCssPointerEvents = (function (el) { - // false when IE11 - if (!!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie)/i)) { - return false; - } - el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - })(), - - _silent = false, - - abs = Math.abs, - min = Math.min, - - savedInputChecked = [], - touchDragOverListeners = [], - - alwaysFalse = function () { return false; }, - - _getParentAutoScrollElement = function(rootEl, includeSelf) { - // will skip to window in _autoScroll - if (!rootEl || !rootEl.getBoundingClientRect) return; - - var elem = rootEl; - var gotSelf = false; - do { - if ( - (elem.clientWidth < elem.scrollWidth) || - (elem.clientHeight < elem.scrollHeight) - ) { - if (!elem || !elem.getBoundingClientRect || elem === document.body) return; - - if (gotSelf || includeSelf) return elem; - gotSelf = true; - } - - } while (elem = elem.parentNode); - }, - - _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) { - // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (options.scroll) { - var _this = rootEl ? rootEl[expando] : window, - rect, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - - x = evt.clientX, - y = evt.clientY, - - winWidth = window.innerWidth, - winHeight = window.innerHeight, - - vx, - vy, - - scrollOffsetX, - scrollOffsetY - ; - - // Detect scrollEl - if (scrollParentEl !== rootEl) { - _clearAutoScrolls(); - - scrollEl = options.scroll; - scrollCustomFn = options.scrollFn; - - if (scrollEl === true) { - scrollEl = _getParentAutoScrollElement(rootEl, true); - scrollParentEl = scrollEl; - } - } - - - var layersOut = 0; - var currentParent = scrollEl; - do { - var el; - - if (currentParent) { - el = currentParent; - rect = currentParent.getBoundingClientRect(); - vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens); - vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens); - } - - - if (!(vx || vy)) { - vx = (winWidth - x <= sens) - (x <= sens); - vy = (winHeight - y <= sens) - (y <= sens); - - /* jshint expr:true */ - (vx || vy) && (el = win); - } - - if (!autoScrolls[layersOut]) { - for (var i = 0; i <= layersOut; i++) { - if (!autoScrolls[i]) { - autoScrolls[i] = {}; - } - } - } - - if (autoScrolls[layersOut].vx !== vx || autoScrolls[layersOut].vy !== vy || autoScrolls[layersOut].el !== el) { - autoScrolls[layersOut].el = el; - autoScrolls[layersOut].vx = vx; - autoScrolls[layersOut].vy = vy; - - clearInterval(autoScrolls[layersOut].pid); - - if (el) { - autoScrolls[layersOut].pid = setInterval((function () { - scrollOffsetY = autoScrolls[this.layersOut].vy ? autoScrolls[this.layersOut].vy * speed : 0; - scrollOffsetX = autoScrolls[this.layersOut].vx ? autoScrolls[this.layersOut].vx * speed : 0; - - if ('function' === typeof(scrollCustomFn)) { - if (scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layersOut].el) !== 'continue') { - return; - } - } - - if (autoScrolls[this.layersOut].el === win) { - win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); - } else { - autoScrolls[this.layersOut].el.scrollTop += scrollOffsetY; - autoScrolls[this.layersOut].el.scrollLeft += scrollOffsetX; - } - }).bind({layersOut: layersOut}), 24); - } - } - layersOut++; - } while (options.bubbleScroll && (currentParent = _getParentAutoScrollElement(currentParent, false))); - } - }, 30), - - _clearAutoScrolls = function () { - autoScrolls.forEach(function(autoScroll) { - clearInterval(autoScroll.pid); - }); - autoScrolls = []; - }, - - _prepareGroup = function (options) { - function toFn(value, pull) { - return function(to, from, dragEl, evt) { - var ret; - - if (value == null || value === false) { - ret = false; - } else if (pull && value === 'clone') { - ret = value; - } else if (typeof value === 'function') { - ret = value(to, from, dragEl, evt); - } else { - var otherGroup = (pull ? to : from).options.group.name; - - ret = (value === true || - (typeof value === 'string' && value === otherGroup) || - (value.join && value.indexOf(otherGroup) > -1)); - } - - return ret || to.options.group.name === from.options.group.name; - } - } - - var group = {}; - var originalGroup = options.group; - - if (!originalGroup || typeof originalGroup != 'object') { - originalGroup = {name: originalGroup}; - } - - group.name = originalGroup.name; - group.checkPull = toFn(originalGroup.pull, true); - group.checkPut = toFn(originalGroup.put); - group.revertClone = originalGroup.revertClone; - - options.group = group; - } + var sortable, + jq, + _this = this ; - // Detect support a passive mode - try { - window.addEventListener('test', null, Object.defineProperty({}, 'passive', { - get: function () { - // `false`, because everything starts to work incorrectly and instead of d'n'd, - // begins the page has scrolled. - passiveMode = false; - captureMode = { - capture: false, - passive: passiveMode - }; - } - })); - } catch (err) {} - - /** - * @class Sortable - * @param {HTMLElement} el - * @param {Object} [options] - */ - function Sortable(el, options) { - if (!(el && el.nodeType && el.nodeType === 1)) { - throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); - } - - this.el = el; // root element - this.options = options = _extend({}, options); - - - // Export instance - el[expando] = this; - - // Default options - var defaults = { - group: null, - sort: true, - disabled: false, - store: null, - handle: null, - scroll: true, - scrollSensitivity: 30, - scrollSpeed: 10, - bubbleScroll: true, - draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', - ghostClass: 'sortable-ghost', - chosenClass: 'sortable-chosen', - dragClass: 'sortable-drag', - ignore: 'a, img', - filter: null, - preventOnFilter: true, - animation: 0, - setData: function (dataTransfer, dragEl) { - dataTransfer.setData('Text', dragEl.textContent); - }, - dropBubble: false, - dragoverBubble: false, - dataIdAttr: 'data-id', - delay: 0, - touchStartThreshold: parseInt(window.devicePixelRatio, 10) || 1, - forceFallback: false, - fallbackClass: 'sortable-fallback', - fallbackOnBody: false, - fallbackTolerance: 0, - fallbackOffset: {x: 0, y: 0}, - supportPointer: Sortable.supportPointer !== false - }; - - - // Set default options - for (var name in defaults) { - !(name in options) && (options[name] = defaults[name]); - } - - _prepareGroup(options); - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - - // Setup drag mode - this.nativeDraggable = options.forceFallback ? false : supportDraggable; - - // Bind events - _on(el, 'mousedown', this._onTapStart); - _on(el, 'touchstart', this._onTapStart); - options.supportPointer && _on(el, 'pointerdown', this._onTapStart); - - if (this.nativeDraggable) { - _on(el, 'dragover', this); - _on(el, 'dragenter', this); - } - - touchDragOverListeners.push(this._onDragOver); - - // Restore sorting - options.store && this.sort(options.store.get(this)); - } - - - Sortable.prototype = /** @lends Sortable.prototype */ { - constructor: Sortable, - - _onTapStart: function (/** Event|TouchEvent */evt) { - var _this = this, - el = this.el, - options = this.options, - preventOnFilter = options.preventOnFilter, - type = evt.type, - touch = evt.touches && evt.touches[0], - target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && ((evt.path && evt.path[0]) || (evt.composedPath && evt.composedPath()[0])) || target, - filter = options.filter, - startIndex; - - _saveInputCheckedState(el); - - - // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. - if (dragEl) { - return; - } - - if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { - return; // only left button or enabled - } - - // cancel dnd if original target is content editable - if (originalTarget.isContentEditable) { - return; - } - - target = _closest(target, options.draggable, el); - - if (!target) { - return; - } - - if (lastDownEl === target) { - // Ignoring duplicate `down` - return; - } - - // Get the index of the dragged element within its parent - startIndex = _index(target, options.draggable); - - // Check filter - if (typeof filter === 'function') { - if (filter.call(this, evt, target, this)) { - _dispatchEvent(_this, originalTarget, 'filter', target, el, el, startIndex); - preventOnFilter && evt.preventDefault(); - return; // cancel dnd - } - } - else if (filter) { - filter = filter.split(',').some(function (criteria) { - criteria = _closest(originalTarget, criteria.trim(), el); - - if (criteria) { - _dispatchEvent(_this, criteria, 'filter', target, el, el, startIndex); - return true; - } - }); - - if (filter) { - preventOnFilter && evt.preventDefault(); - return; // cancel dnd - } - } - - if (options.handle && !_closest(originalTarget, options.handle, el)) { - return; - } - - // Prepare `dragstart` - this._prepareDragStart(evt, touch, target, startIndex); - }, - - - _handleAutoScroll: function(evt) { - if (!dragEl || !this.options.scroll || (this.options.supportPointer && evt.type == 'touchmove')) return; - var - x = (evt.touches ? evt.touches[0] : evt).clientX, - y = (evt.touches ? evt.touches[0] : evt).clientY, - - elem = document.elementFromPoint(x, y), - _this = this - ; - - - // touch does not have native autoscroll, even with DnD enabled - if (!_this.nativeDraggable || evt.touches || (evt.pointerType && evt.pointerType == 'touch')) { - - _autoScroll(evt.touches ? evt.touches[0] : evt, _this.options, elem); - - // Listener for pointer element change - var ogElemScroller = _getParentAutoScrollElement(elem, true); - if (!pointerElemChangedInterval || - x != lastPointerElemX || - y != lastPointerElemY) { - - pointerElemChangedInterval && clearInterval(pointerElemChangedInterval); - // Detect for pointer elem change, emulating native DnD behaviour - pointerElemChangedInterval = setInterval(function() { - if (!dragEl) return; - var newElem = _getParentAutoScrollElement(document.elementFromPoint(x, y), true); - if (newElem != ogElemScroller) { - ogElemScroller = newElem; - _clearAutoScrolls(); - _autoScroll(evt.touches ? evt.touches[0] : evt, _this.options, ogElemScroller); - } - }, 10); - lastPointerElemX = x; - lastPointerElemY = y; - } - - } else { - // if DnD is enabled, first autoscroll will already scroll, so get parent autoscroll of first autoscroll - if (!_this.options.bubbleScroll) return; - _autoScroll(evt, _this.options, _getParentAutoScrollElement(elem, false)); - } - }, - - _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) { - var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - - if (target && !dragEl && (target.parentNode === el)) { - tapEvt = evt; - - rootEl = el; - dragEl = target; - parentEl = dragEl.parentNode; - nextEl = dragEl.nextSibling; - lastDownEl = target; - activeGroup = options.group; - oldIndex = startIndex; - - this._lastX = (touch || evt).clientX; - this._lastY = (touch || evt).clientY; - - dragEl.style['will-change'] = 'all'; - - dragStartFn = function () { - // Delayed drag has been triggered - // we can re-enable the events: touchmove/mousemove - _this._disableDelayedDrag(); - - // Make the element draggable - dragEl.draggable = _this.nativeDraggable; - - // Bind the events: dragstart/dragend - _this._triggerDragStart(evt, touch); - - // Drag start event - _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, rootEl, oldIndex); - - // Chosen item - _toggleClass(dragEl, options.chosenClass, true); - }; - - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - _find(dragEl, criteria.trim(), _disableDraggable); - }); - - _on(ownerDocument, 'mouseup', _this._onDrop); - _on(ownerDocument, 'touchend', _this._onDrop); - _on(ownerDocument, 'touchcancel', _this._onDrop); - _on(ownerDocument, 'selectstart', _this); - options.supportPointer && _on(ownerDocument, 'pointercancel', _this._onDrop); - - if (options.delay) { - // If the user moves the pointer or let go the click or touch - // before the delay has been reached: - // disable the delayed drag - _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - _on(ownerDocument, 'touchend', _this._disableDelayedDrag); - _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - _on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); - _on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); - options.supportPointer && _on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); - - _this._dragStartTimer = setTimeout(dragStartFn.bind(_this), options.delay); - } else { - dragStartFn(); - } - - - } - }, - - _delayedDragTouchMoveHandler: function (/** TouchEvent|PointerEvent **/e) { - var touch = e.touches ? e.touches[0] : e; - if (min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) - >= this.options.touchStartThreshold - ) { - this._disableDelayedDrag(); - } - }, - - _disableDelayedDrag: function () { - var ownerDocument = this.el.ownerDocument; - - clearTimeout(this._dragStartTimer); - _off(ownerDocument, 'mouseup', this._disableDelayedDrag); - _off(ownerDocument, 'touchend', this._disableDelayedDrag); - _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - _off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); - _off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); - _off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); - }, - - _triggerDragStart: function (/** Event */evt, /** Touch */touch) { - touch = touch || (evt.pointerType == 'touch' ? evt : null); - - - if (touch) { - // Touch device support - tapEvt = { - target: dragEl, - clientX: touch.clientX, - clientY: touch.clientY - }; - - this._onDragStart(tapEvt, 'touch'); - } - else if (!this.nativeDraggable) { - this._onDragStart(tapEvt, true); - } - else { - _on(dragEl, 'dragend', this); - _on(rootEl, 'dragstart', this._onDragStart); - } - - try { - if (document.selection) { - // Timeout neccessary for IE9 - _nextTick(function () { - document.selection.empty(); - }); - } else { - window.getSelection().removeAllRanges(); - } - } catch (err) { - } - }, - - _dragStarted: function () { - if (rootEl && dragEl) { - _on(document, 'drag', this._handleAutoScroll); - var options = this.options; - - // Apply effect - _toggleClass(dragEl, options.ghostClass, true); - _toggleClass(dragEl, options.dragClass, false); - - Sortable.active = this; - - // Drag start event - _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, rootEl, oldIndex); - } else { - this._nulling(); - } - }, - - _emulateDragOver: function () { - if (touchEvt) { - if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { - return; - } - - this._lastX = touchEvt.clientX; - this._lastY = touchEvt.clientY; - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', 'none'); - } - - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - var parent = target; - - while (target && target.shadowRoot) { - target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - parent = target; - } - - if (parent) { - do { - if (parent[expando]) { - var i = touchDragOverListeners.length; - while (i--) { - touchDragOverListeners[i]({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - } - - if (!this.options.dragoverBubble) { - break; - } - } - - target = parent; // store last element - } - /* jshint boss:true */ - while (parent = parent.parentNode); - } - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', ''); - } - } - }, - - - _onTouchMove: function (/**TouchEvent*/evt) { - if (tapEvt) { - var options = this.options, - fallbackTolerance = options.fallbackTolerance, - fallbackOffset = options.fallbackOffset, - touch = evt.touches ? evt.touches[0] : evt, - dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x, - dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y, - translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; - - // only set the status to dragging, when we are actually dragging - if (!Sortable.active) { - if (fallbackTolerance && - min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance - ) { - return; - } - - this._dragStarted(); - } - - // as well as creating the ghost element on the document body - this._appendGhost(); - - moved = true; - touchEvt = touch; - - _css(ghostEl, 'webkitTransform', translate3d); - _css(ghostEl, 'mozTransform', translate3d); - _css(ghostEl, 'msTransform', translate3d); - _css(ghostEl, 'transform', translate3d); - - evt.preventDefault(); - } - }, - - _appendGhost: function () { - if (!ghostEl) { - var rect = dragEl.getBoundingClientRect(), - css = _css(dragEl), - options = this.options, - ghostRect; - - ghostEl = dragEl.cloneNode(true); - - _toggleClass(ghostEl, options.ghostClass, false); - _toggleClass(ghostEl, options.fallbackClass, true); - _toggleClass(ghostEl, options.dragClass, true); - - _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); - _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); - _css(ghostEl, 'width', rect.width); - _css(ghostEl, 'height', rect.height); - _css(ghostEl, 'opacity', '0.8'); - _css(ghostEl, 'position', 'fixed'); - _css(ghostEl, 'zIndex', '100000'); - _css(ghostEl, 'pointerEvents', 'none'); - - options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); - - // Fixing dimensions. - ghostRect = ghostEl.getBoundingClientRect(); - _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); - _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); - } - }, - - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var _this = this; - var dataTransfer = evt.dataTransfer; - var options = _this.options; - - _this._offUpEvents(); - - if (activeGroup.checkPull(_this, _this, dragEl, evt)) { - cloneEl = _clone(dragEl); - - cloneEl.draggable = false; - cloneEl.style['will-change'] = ''; - - this._hideClone(); - - _toggleClass(cloneEl, _this.options.chosenClass, false); - - // #1143: IFrame support workaround - _this._cloneId = _nextTick(function () { - rootEl.insertBefore(cloneEl, dragEl); - _dispatchEvent(_this, rootEl, 'clone', dragEl); - }); - } - - _toggleClass(dragEl, options.dragClass, true); - - if (useFallback) { - if (useFallback === 'touch') { - // Bind touch events - _on(document, 'touchmove', _this._onTouchMove); - // onTouchMove before handleAutoScroll in this case, because onTouchMove sets touchEvt - _on(document, 'touchmove', _this._handleAutoScroll); - _on(document, 'touchend', _this._onDrop); - _on(document, 'touchcancel', _this._onDrop); - - if (options.supportPointer) { - _on(document, 'pointermove', _this._handleAutoScroll); - _on(document, 'pointermove', _this._onTouchMove); - _on(document, 'pointerup', _this._onDrop); - } - } else { - // Old brwoser - _on(document, 'mousemove', _this._handleAutoScroll); - _on(document, 'mousemove', _this._onTouchMove); - _on(document, 'mouseup', _this._onDrop); - } - - _this._loopId = setInterval(_this._emulateDragOver, 50); - } - else { - if (dataTransfer) { - dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(_this, dataTransfer, dragEl); - } - - _on(document, 'drop', _this); - - // #1143: Бывает элемент с IFrame внутри блокирует `drop`, - // поэтому если вызвался `mouseover`, значит надо отменять весь d'n'd. - // Breaking Chrome 62+ - // _on(document, 'mouseover', _this); - - _this._dragStartId = _nextTick(_this._dragStarted); - } - }, - - _onDragOver: function (/**Event*/evt) { - var el = this.el, - target, - dragRect, - targetRect, - revert, - options = this.options, - group = options.group, - activeSortable = Sortable.active, - isOwner = (activeGroup === group), - isMovingBetweenSortable = false, - canSort = options.sort; - - if (evt.preventDefault !== void 0) { - evt.preventDefault(); - !options.dragoverBubble && evt.stopPropagation(); - } - - if (dragEl.animated) { - return; - } - - moved = true; - - target = evt.target == el ? evt.target : _closest(evt.target, options.draggable, el); - - if (target === el) return; - - if (activeSortable && !options.disabled && - (isOwner - ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list - : ( - putSortable === this || - ( - (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && - group.checkPut(this, activeSortable, dragEl, evt) - ) - ) - ) && - (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback - ) { - if (_silent) { - return; - } - - dragRect = dragEl.getBoundingClientRect(); - - if (putSortable !== this) { - putSortable = this; - isMovingBetweenSortable = true; - } - - if (revert) { - this._hideClone(); - parentEl = rootEl; // actualization - - if (cloneEl || nextEl) { - rootEl.insertBefore(dragEl, cloneEl || nextEl); - } - else if (!canSort) { - rootEl.appendChild(dragEl); - } - - return; - } - - - if ((el.children.length === 0) || (el.children[0] === ghostEl) || - (el === evt.target) && (_ghostIsLast(el, evt)) - ) { - //assign target only if condition is true - if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) { - target = el.lastElementChild; - } - - if (target) { - if (target.animated) { - return; - } - - targetRect = target.getBoundingClientRect(); - } - - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(this); - } - - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) { - if (!dragEl.contains(el)) { - el.appendChild(dragEl); - parentEl = el; // actualization - } - - this._animate(dragRect, dragEl); - target && this._animate(targetRect, target); - } - } - else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { - if (lastEl !== target) { - lastEl = target; - lastCSS = _css(target); - lastParentCSS = _css(target.parentNode); - } - - targetRect = target.getBoundingClientRect(); - - var width = targetRect.right - targetRect.left, - height = targetRect.bottom - targetRect.top, - floating = R_FLOAT.test(lastCSS.cssFloat + lastCSS.display) - || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), - isWide = (target.offsetWidth > dragEl.offsetWidth), - isLong = (target.offsetHeight > dragEl.offsetHeight), - halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, - nextSibling = target.nextElementSibling, - after = false - ; - - if (floating) { - var elTop = dragEl.offsetTop, - tgTop = target.offsetTop; - - if (elTop === tgTop) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; - } - else if (target.previousElementSibling === dragEl || dragEl.previousElementSibling === target) { - after = (evt.clientY - targetRect.top) / height > 0.5; - } else { - after = tgTop > elTop; - } - } else if (!isMovingBetweenSortable) { - after = (nextSibling !== dragEl) && !isLong || halfway && isLong; - } - - var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); - - if (moveVector !== false) { - if (moveVector === 1 || moveVector === -1) { - after = (moveVector === 1); - } - - _silent = true; - setTimeout(_unsilent, 30); - - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(this); - } - - if (!dragEl.contains(el)) { - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } - } - - parentEl = dragEl.parentNode; // actualization - - this._animate(dragRect, dragEl); - this._animate(targetRect, target); - } - } - } - }, - - _animate: function (prevRect, target) { - var ms = this.options.animation; - - if (ms) { - var currentRect = target.getBoundingClientRect(); - - if (prevRect.nodeType === 1) { - prevRect = prevRect.getBoundingClientRect(); - } - - _css(target, 'transition', 'none'); - _css(target, 'transform', 'translate3d(' - + (prevRect.left - currentRect.left) + 'px,' - + (prevRect.top - currentRect.top) + 'px,0)' - ); - - forRepaintDummy = target.offsetWidth; // repaint - - _css(target, 'transition', 'all ' + ms + 'ms'); - _css(target, 'transform', 'translate3d(0,0,0)'); - - clearTimeout(target.animated); - target.animated = setTimeout(function () { - _css(target, 'transition', ''); - _css(target, 'transform', ''); - target.animated = false; - }, ms); - } - }, - - _offUpEvents: function () { - var ownerDocument = this.el.ownerDocument; - - _off(document, 'touchmove', this._handleAutoScroll); - _off(document, 'pointermove', this._handleAutoScroll); - _off(document, 'mousemove', this._handleAutoScroll); - _off(document, 'touchmove', this._onTouchMove); - _off(document, 'pointermove', this._onTouchMove); - _off(ownerDocument, 'mouseup', this._onDrop); - _off(ownerDocument, 'touchend', this._onDrop); - _off(ownerDocument, 'pointerup', this._onDrop); - _off(ownerDocument, 'touchcancel', this._onDrop); - _off(ownerDocument, 'pointercancel', this._onDrop); - _off(ownerDocument, 'selectstart', this); - }, - - _onDrop: function (/**Event*/evt) { - var el = this.el, - options = this.options; - - clearInterval(this._loopId); - - clearInterval(pointerElemChangedInterval); - _clearAutoScrolls(); - _cancelThrottle(); - - clearTimeout(this._dragStartTimer); - - _cancelNextTick(this._cloneId); - _cancelNextTick(this._dragStartId); - - // Unbind events - _off(document, 'mouseover', this); - _off(document, 'mousemove', this._onTouchMove); - - - if (this.nativeDraggable) { - _off(document, 'drop', this); - _off(el, 'dragstart', this._onDragStart); - _off(document, 'drag', this._handleAutoScroll); - } - - this._offUpEvents(); - - if (evt) { - if (moved) { - evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); - } - - ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - - if (rootEl === parentEl || this.lastPutMode !== 'clone') { - // Remove clone - cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); - } - - if (dragEl) { - if (this.nativeDraggable) { - _off(dragEl, 'dragend', this); - } - - _disableDraggable(dragEl); - dragEl.style['will-change'] = ''; - - // Remove class's - _toggleClass(dragEl, this.options.ghostClass, false); - _toggleClass(dragEl, this.options.chosenClass, false); - - // Drag stop event - _dispatchEvent(this, rootEl, 'unchoose', dragEl, parentEl, rootEl, oldIndex, null, evt); - - if (rootEl !== parentEl) { - newIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // Add event - _dispatchEvent(null, parentEl, 'add', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - - // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - - // drag from one list and drop into another - _dispatchEvent(null, parentEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - } - } - else { - if (dragEl.nextSibling !== nextEl) { - // Get the index of the dragged element within its parent - newIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - } - } - } - - if (Sortable.active) { - /* jshint eqnull:true */ - if (newIndex == null || newIndex === -1) { - newIndex = oldIndex; - } - - _dispatchEvent(this, rootEl, 'end', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); - - // Save sorting - this.save(); - } - } - - } - - this._nulling(); - }, - - _nulling: function() { - rootEl = - dragEl = - parentEl = - ghostEl = - nextEl = - cloneEl = - lastDownEl = - - scrollEl = - scrollParentEl = - - tapEvt = - touchEvt = - - moved = - newIndex = - - lastEl = - lastCSS = - - putSortable = - activeGroup = - Sortable.active = null; - - savedInputChecked.forEach(function (el) { - el.checked = true; + if (typeof define === "function" && define.amd) { + try { + define(["sortablejs", "jquery"], function(Sortable, $) { + sortable = Sortable; + jq = $; + checkErrors(); + factory(Sortable, $); }); - savedInputChecked.length = 0; - }, - - handleEvent: function (/**Event*/evt) { - switch (evt.type) { - case 'drop': - case 'dragend': - this._onDrop(evt); - break; - - case 'dragover': - case 'dragenter': - if (dragEl) { - this._onDragOver(evt); - _globalDragOver(evt); - } - break; - - case 'mouseover': - this._onDrop(evt); - break; - - case 'selectstart': - evt.preventDefault(); - break; - } - }, - - - /** - * Serializes the item into an array of string. - * @returns {String[]} - */ - toArray: function () { - var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - - for (; i < n; i++) { - el = children[i]; - if (_closest(el, options.draggable, this.el)) { - order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); - } - } - - return order; - }, - - - /** - * Sorts the elements according to the array. - * @param {String[]} order order of the items - */ - sort: function (order) { - var items = {}, rootEl = this.el; - - this.toArray().forEach(function (id, i) { - var el = rootEl.children[i]; - - if (_closest(el, this.options.draggable, rootEl)) { - items[id] = el; - } - }, this); - - order.forEach(function (id) { - if (items[id]) { - rootEl.removeChild(items[id]); - rootEl.appendChild(items[id]); - } - }); - }, - - - /** - * Save the current sorting - */ - save: function () { - var store = this.options.store; - store && store.set(this); - }, - - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * @param {HTMLElement} el - * @param {String} [selector] default: `options.draggable` - * @returns {HTMLElement|null} - */ - closest: function (el, selector) { - return _closest(el, selector || this.options.draggable, this.el); - }, - - - /** - * Set/get option - * @param {string} name - * @param {*} [value] - * @returns {*} - */ - option: function (name, value) { - var options = this.options; - - if (value === void 0) { - return options[name]; - } else { - options[name] = value; - - if (name === 'group') { - _prepareGroup(options); - } - } - }, - - - /** - * Destroy - */ - destroy: function () { - var el = this.el; - - el[expando] = null; - - _off(el, 'mousedown', this._onTapStart); - _off(el, 'touchstart', this._onTapStart); - _off(el, 'pointerdown', this._onTapStart); - - if (this.nativeDraggable) { - _off(el, 'dragover', this); - _off(el, 'dragenter', this); - } - - // Remove draggable attributes - Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { - el.removeAttribute('draggable'); - }); - - touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); - - this._onDrop(); - - this.el = el = null; - }, - - _hideClone: function() { - if (!cloneEl.cloneHidden) { - _css(cloneEl, 'display', 'none'); - cloneEl.cloneHidden = true; - } - }, - - _showClone: function(putSortable) { - if (putSortable.lastPutMode !== 'clone') return; - - if (cloneEl.cloneHidden) { - // show clone at dragEl or original position - rootEl.insertBefore(cloneEl, rootEl.contains(dragEl) && !this.options.group.revertClone ? dragEl : nextEl); - - if (this.options.group.revertClone) { - this._animate(dragEl, cloneEl); - } - _css(cloneEl, 'display', ''); - cloneEl.cloneHidden = false; - } + } catch(err) { + checkErrors(); } - }; + return; + } else if (typeof exports === 'object') { + try { + sortable = require('sortablejs'); + jq = require('jquery'); + } catch(err) { } + } - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { - if (el) { - ctx = ctx || document; + if (typeof jQuery === 'function' || typeof $ === 'function') { + jq = jQuery || $; + } - do { - if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector)) { - return el; - } - /* jshint boss:true */ - } while (el = _getParentOrHost(el)); + if (typeof Sortable !== 'undefined') { + sortable = Sortable; + } + + function checkErrors() { + if (!jq) { + throw new Error('jQuery is required for jquery-sortablejs'); } - return null; - } - - - function _getParentOrHost(el) { - return (el.host && el !== document && el.host.nodeType) - ? el.host - : el.parentNode; - } - - - function _globalDragOver(/**Event*/evt) { - if (evt.dataTransfer) { - evt.dataTransfer.dropEffect = 'move'; - } - evt.preventDefault(); - } - - - function _on(el, event, fn) { - el.addEventListener(event, fn, captureMode); - } - - - function _off(el, event, fn) { - el.removeEventListener(event, fn, captureMode); - } - - - function _toggleClass(el, name, state) { - if (el) { - if (el.classList) { - el.classList[state ? 'add' : 'remove'](name); - } - else { - var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); - el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); - } + if (!sortable) { + throw new Error('SortableJS is required for jquery-sortablejs (https://github.com/SortableJS/Sortable)'); } } + checkErrors(); + factory(sortable, jq); +})(function (Sortable, $) { + "use strict"; - - function _css(el, prop, val) { - var style = el && el.style; - - if (style) { - if (val === void 0) { - if (document.defaultView && document.defaultView.getComputedStyle) { - val = document.defaultView.getComputedStyle(el, ''); - } - else if (el.currentStyle) { - val = el.currentStyle; - } - - return prop === void 0 ? val : val[prop]; - } - else { - if (!(prop in style)) { - prop = '-webkit-' + prop; - } - - style[prop] = val + (typeof val === 'string' ? '' : 'px'); - } - } - } - - - function _find(ctx, tagName, iterator) { - if (ctx) { - var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; - - if (iterator) { - for (; i < n; i++) { - iterator(list[i], i); - } - } - - return list; - } - - return []; - } - - - - function _dispatchEvent(sortable, rootEl, name, targetEl, toEl, fromEl, startIndex, newIndex, originalEvt) { - sortable = (sortable || rootEl[expando]); - - var evt = document.createEvent('Event'), - options = sortable.options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - - evt.initEvent(name, true, true); - - evt.to = toEl || rootEl; - evt.from = fromEl || rootEl; - evt.item = targetEl || rootEl; - evt.clone = cloneEl; - - evt.oldIndex = startIndex; - evt.newIndex = newIndex; - - evt.originalEvent = originalEvt; - - rootEl.dispatchEvent(evt); - - if (options[onName]) { - options[onName].call(sortable, evt); - } - } - - - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) { - var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; - - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); - - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || toEl.getBoundingClientRect(); - evt.willInsertAfter = willInsertAfter; - - evt.originalEvent = originalEvt; - - fromEl.dispatchEvent(evt); - - if (onMoveFn) { - retVal = onMoveFn.call(sortable, evt, originalEvt); - } - - return retVal; - } - - - function _disableDraggable(el) { - el.draggable = false; - } - - - function _unsilent() { - _silent = false; - } - - - /** @returns {HTMLElement|false} */ - function _ghostIsLast(el, evt) { - var lastEl = el.lastElementChild, - rect = lastEl.getBoundingClientRect(); - - // 5 — min delta - // abs — нельзя добавлять, а то глюки при наведении сверху - return (evt.clientY - (rect.top + rect.height) > 5) || - (evt.clientX - (rect.left + rect.width) > 5); - } - - - /** - * Generate id - * @param {HTMLElement} el - * @returns {String} - * @private - */ - function _generateId(el) { - var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - - while (i--) { - sum += str.charCodeAt(i); - } - - return sum.toString(36); - } - - /** - * Returns the index of an element within its parent for a selected set of - * elements - * @param {HTMLElement} el - * @param {selector} selector - * @return {number} - */ - function _index(el, selector) { - var index = 0; - - if (!el || !el.parentNode) { - return -1; - } - - while (el && (el = el.previousElementSibling)) { - if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) { - index++; - } - } - - return index; - } - - function _matches(/**HTMLElement*/el, /**String*/selector) { - if (el) { - try { - if (el.matches) { - return el.matches(selector); - } else if (el.msMatchesSelector) { - return el.msMatchesSelector(selector); - } - } catch(_) { - return false; - } - } - - return false; - } - - var _throttleTimeout; - function _throttle(callback, ms) { - return function () { - if (!_throttleTimeout) { - var args = arguments, - _this = this - ; - - _throttleTimeout = setTimeout(function () { - if (args.length === 1) { - callback.call(_this, args[0]); - } else { - callback.apply(_this, args); - } - - _throttleTimeout = void 0; - }, ms); - } - }; - } - - function _cancelThrottle() { - clearTimeout(_throttleTimeout); - _throttleTimeout = void 0; - } - - function _extend(dst, src) { - if (dst && src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - } - - return dst; - } - - function _clone(el) { - if (Polymer && Polymer.dom) { - return Polymer.dom(el).cloneNode(true); - } - else if ($) { - return $(el).clone(true)[0]; - } - else { - return el.cloneNode(true); - } - } - - function _saveInputCheckedState(root) { - savedInputChecked.length = 0; - - var inputs = root.getElementsByTagName('input'); - var idx = inputs.length; - - while (idx--) { - var el = inputs[idx]; - el.checked && savedInputChecked.push(el); - } - } - - function _nextTick(fn) { - return setTimeout(fn, 0); - } - - function _cancelNextTick(id) { - return clearTimeout(id); - } - - // Fixed #973: - _on(document, 'touchmove', function (evt) { - if (Sortable.active) { - evt.preventDefault(); - } - }); - - // Export utils - Sortable.utils = { - on: _on, - off: _off, - css: _css, - find: _find, - is: function (el, selector) { - return !!_closest(el, selector, el); - }, - extend: _extend, - throttle: _throttle, - closest: _closest, - toggleClass: _toggleClass, - clone: _clone, - index: _index, - nextTick: _nextTick, - cancelNextTick: _cancelNextTick - }; - - - /** - * Create sortable instance - * @param {HTMLElement} el - * @param {Object} [options] - */ - Sortable.create = function (el, options) { - return new Sortable(el, options); - }; - - - - - - /** - * jQuery plugin for Sortable - * @param {Object|String} options - * @param {..*} [args] - * @returns {jQuery|*} - */ $.fn.sortable = function (options) { var retVal, args = arguments; @@ -1680,20 +57,15 @@ if (!sortable && (options instanceof Object || !options)) { sortable = new Sortable(this, options); $el.data('sortable', sortable); - } - - if (sortable) { - if (options === 'widget') { - retVal = sortable; - } - else if (options === 'destroy') { + } else if (sortable) { + if (options === 'destroy') { sortable.destroy(); $el.removeData('sortable'); - } - else if (typeof sortable[options] === 'function') { + } else if (options === 'widget') { + retVal = sortable; + } else if (typeof sortable[options] === 'function') { retVal = sortable[options].apply(sortable, [].slice.call(args, 1)); - } - else if (options in sortable.options) { + } else if (options in sortable.options) { retVal = sortable.option.apply(sortable, args); } } @@ -1701,4 +73,4 @@ return (retVal === void 0) ? this : retVal; }; -}); +}); \ No newline at end of file diff --git a/public/js/vendor/jquery.fn.sortable.min.js b/public/js/vendor/jquery.fn.sortable.min.js deleted file mode 100644 index b0eeaa5..0000000 --- a/public/js/vendor/jquery.fn.sortable.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Sortable 1.7.0 - MIT | git://github.com/rubaxa/Sortable.git */ - -!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(r){"use strict";var C,E,x,O,P,N,d,b,y,D,k,A,B,c,o,M,Y,a,l,s,h,T,X,t,i,S=[],u=/\s+/g,I=/left|right|inline/,R="Sortable"+(new Date).getTime(),w=window,p=w.document,f=w.parseInt,H=w.setTimeout,e=(r=w.jQuery||w.Zepto,w.Polymer),g=!1,n=!1,v="draggable"in p.createElement("div"),m=!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie)/i)&&((t=p.createElement("x")).style.cssText="pointer-events:auto","auto"===t.style.pointerEvents),F=!1,L=Math.abs,_=Math.min,j=[],W=[],U=function(t,e){if(t&&t.getBoundingClientRect){var n=t,o=!1;do{if(n.clientWidth*",ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,touchStartThreshold:f(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==G.supportPointer};for(var o in n)!(o in e)&&(e[o]=n[o]);for(var i in z(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&v,Z(t,"mousedown",this._onTapStart),Z(t,"touchstart",this._onTapStart),e.supportPointer&&Z(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(Z(t,"dragover",this),Z(t,"dragenter",this)),W.push(this._onDragOver),e.store&&this.sort(e.store.get(this))}function Q(t,e,n){if(t){n=n||p;do{if(">*"===e&&t.parentNode===n||lt(t,e))return t}while(t=(o=t).host&&o!==p&&o.host.nodeType?o.host:o.parentNode)}var o;return null}function Z(t,e,n){t.addEventListener(e,n,g)}function J(t,e,n){t.removeEventListener(e,n,g)}function K(t,e,n){if(t)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(u," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(u," ")}}function $(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return p.defaultView&&p.defaultView.getComputedStyle?n=p.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function tt(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i*"!==e&&!lt(t,e)||n++;return n}function lt(t,e){if(t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e)}catch(t){return!1}return!1}function st(n,o){return function(){if(!i){var t=arguments,e=this;i=H(function(){1===t.length?n.call(e,t[0]):n.apply(e,t),i=void 0},o)}}}function ct(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}function ht(t){return e&&e.dom?e.dom(t).cloneNode(!0):r?r(t).clone(!0)[0]:t.cloneNode(!0)}function dt(t){return H(t,0)}function ut(t){return clearTimeout(t)}G.prototype={constructor:G,_onTapStart:function(t){var e,n=this,o=this.el,i=this.options,r=i.preventOnFilter,a=t.type,l=t.touches&&t.touches[0],s=(l||t).target,c=t.target.shadowRoot&&(t.path&&t.path[0]||t.composedPath&&t.composedPath()[0])||s,h=i.filter;if(function(t){j.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&j.push(o)}}(o),!C&&!(/mousedown|pointerdown/.test(a)&&0!==t.button||i.disabled)&&!c.isContentEditable&&(s=Q(s,i.draggable,o))&&d!==s){if(e=at(s,i.draggable),"function"==typeof h){if(h.call(this,t,s,this))return et(n,c,"filter",s,o,o,e),void(r&&t.preventDefault())}else if(h&&(h=h.split(",").some(function(t){if(t=Q(c,t.trim(),o))return et(n,t,"filter",s,o,o,e),!0})))return void(r&&t.preventDefault());i.handle&&!Q(c,i.handle,o)||this._prepareDragStart(t,l,s,e)}},_handleAutoScroll:function(e){if(C&&this.options.scroll&&(!this.options.supportPointer||"touchmove"!=e.type)){var n=(e.touches?e.touches[0]:e).clientX,o=(e.touches?e.touches[0]:e).clientY,t=p.elementFromPoint(n,o),i=this;if(!i.nativeDraggable||e.touches||e.pointerType&&"touch"==e.pointerType){V(e.touches?e.touches[0]:e,i.options,t);var r=U(t,!0);a&&n==l&&o==s||(a&&clearInterval(a),a=setInterval(function(){if(C){var t=U(p.elementFromPoint(n,o),!0);t!=r&&(r=t,q(),V(e.touches?e.touches[0]:e,i.options,r))}},10),l=n,s=o)}else{if(!i.options.bubbleScroll)return;V(e,i.options,U(t,!1))}}},_prepareDragStart:function(t,e,n,o){var i,r=this,a=r.el,l=r.options,s=a.ownerDocument;n&&!C&&n.parentNode===a&&(h=t,P=a,E=(C=n).parentNode,N=C.nextSibling,d=n,M=l.group,c=o,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,C.style["will-change"]="all",i=function(){r._disableDelayedDrag(),C.draggable=r.nativeDraggable,r._triggerDragStart(t,e),et(r,P,"choose",C,P,P,c),K(C,l.chosenClass,!0)},l.ignore.split(",").forEach(function(t){tt(C,t.trim(),ot)}),Z(s,"mouseup",r._onDrop),Z(s,"touchend",r._onDrop),Z(s,"touchcancel",r._onDrop),Z(s,"selectstart",r),l.supportPointer&&Z(s,"pointercancel",r._onDrop),l.delay?(Z(s,"mouseup",r._disableDelayedDrag),Z(s,"touchend",r._disableDelayedDrag),Z(s,"touchcancel",r._disableDelayedDrag),Z(s,"mousemove",r._delayedDragTouchMoveHandler),Z(s,"touchmove",r._delayedDragTouchMoveHandler),l.supportPointer&&Z(s,"pointermove",r._delayedDragTouchMoveHandler),r._dragStartTimer=H(i.bind(r),l.delay)):i())},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;_(L(e.clientX-this._lastX),L(e.clientY-this._lastY))>=this.options.touchStartThreshold&&this._disableDelayedDrag()},_disableDelayedDrag:function(){var t=this.el.ownerDocument;clearTimeout(this._dragStartTimer),J(t,"mouseup",this._disableDelayedDrag),J(t,"touchend",this._disableDelayedDrag),J(t,"touchcancel",this._disableDelayedDrag),J(t,"mousemove",this._delayedDragTouchMoveHandler),J(t,"touchmove",this._delayedDragTouchMoveHandler),J(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){(e=e||("touch"==t.pointerType?t:null))?(h={target:C,clientX:e.clientX,clientY:e.clientY},this._onDragStart(h,"touch")):this.nativeDraggable?(Z(C,"dragend",this),Z(P,"dragstart",this._onDragStart)):this._onDragStart(h,!0);try{p.selection?dt(function(){p.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(){if(P&&C){Z(p,"drag",this._handleAutoScroll);var t=this.options;K(C,t.ghostClass,!0),K(C,t.dragClass,!1),et(G.active=this,P,"start",C,P,P,c)}else this._nulling()},_emulateDragOver:function(){if(T){if(this._lastX===T.clientX&&this._lastY===T.clientY)return;this._lastX=T.clientX,this._lastY=T.clientY,m||$(x,"display","none");for(var t=p.elementFromPoint(T.clientX,T.clientY),e=t;t&&t.shadowRoot;)e=t=t.shadowRoot.elementFromPoint(T.clientX,T.clientY);if(e)do{if(e[R]){for(var n=W.length;n--;)W[n]({clientX:T.clientX,clientY:T.clientY,target:t,rootEl:e});if(!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);m||$(x,"display","")}},_onTouchMove:function(t){if(h){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=i.clientX-h.clientX+o.x,a=i.clientY-h.clientY+o.y,l=t.touches?"translate3d("+r+"px,"+a+"px,0)":"translate("+r+"px,"+a+"px)";if(!G.active){if(n&&_(L(i.clientX-this._lastX),L(i.clientY-this._lastY))C.offsetWidth,_=e.offsetHeight>C.offsetHeight,b=.5<(v?(t.clientX-o.left)/f:(t.clientY-o.top)/g),y=e.nextElementSibling,D=!1;if(v){var T=C.offsetTop,S=e.offsetTop;D=T===S?e.previousElementSibling===C&&!m||b&&m:e.previousElementSibling===C||C.previousElementSibling===e?.5<(t.clientY-o.top)/g:T