PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
booking / vendors / sortablejs / modular / sortable.complete.esm.js

sortable.complete.esm.js in Booking Calendar 11.8, at vendors/sortablejs/modular/sortable.complete.esm.js

3,381 lines 117.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**!
2 * Sortable 1.15.6
3 * @author RubaXa <trash@rubaxa.org>
4 * @author owenm <owen23355@gmail.com>
5 * @license MIT
6 */
7 function ownKeys(object, enumerableOnly) {
8 var keys = Object.keys(object);
9 if (Object.getOwnPropertySymbols) {
10 var symbols = Object.getOwnPropertySymbols(object);
11 if (enumerableOnly) {
12 symbols = symbols.filter(function (sym) {
13 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
14 });
15 }
16 keys.push.apply(keys, symbols);
17 }
18 return keys;
19 }
20 function _objectSpread2(target) {
21 for (var i = 1; i < arguments.length; i++) {
22 var source = arguments[i] != null ? arguments[i] : {};
23 if (i % 2) {
24 ownKeys(Object(source), true).forEach(function (key) {
25 _defineProperty(target, key, source[key]);
26 });
27 } else if (Object.getOwnPropertyDescriptors) {
28 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
29 } else {
30 ownKeys(Object(source)).forEach(function (key) {
31 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
32 });
33 }
34 }
35 return target;
36 }
37 function _typeof(obj) {
38 "@babel/helpers - typeof";
39
40 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
41 _typeof = function (obj) {
42 return typeof obj;
43 };
44 } else {
45 _typeof = function (obj) {
46 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
47 };
48 }
49 return _typeof(obj);
50 }
51 function _defineProperty(obj, key, value) {
52 if (key in obj) {
53 Object.defineProperty(obj, key, {
54 value: value,
55 enumerable: true,
56 configurable: true,
57 writable: true
58 });
59 } else {
60 obj[key] = value;
61 }
62 return obj;
63 }
64 function _extends() {
65 _extends = Object.assign || function (target) {
66 for (var i = 1; i < arguments.length; i++) {
67 var source = arguments[i];
68 for (var key in source) {
69 if (Object.prototype.hasOwnProperty.call(source, key)) {
70 target[key] = source[key];
71 }
72 }
73 }
74 return target;
75 };
76 return _extends.apply(this, arguments);
77 }
78 function _objectWithoutPropertiesLoose(source, excluded) {
79 if (source == null) return {};
80 var target = {};
81 var sourceKeys = Object.keys(source);
82 var key, i;
83 for (i = 0; i < sourceKeys.length; i++) {
84 key = sourceKeys[i];
85 if (excluded.indexOf(key) >= 0) continue;
86 target[key] = source[key];
87 }
88 return target;
89 }
90 function _objectWithoutProperties(source, excluded) {
91 if (source == null) return {};
92 var target = _objectWithoutPropertiesLoose(source, excluded);
93 var key, i;
94 if (Object.getOwnPropertySymbols) {
95 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
96 for (i = 0; i < sourceSymbolKeys.length; i++) {
97 key = sourceSymbolKeys[i];
98 if (excluded.indexOf(key) >= 0) continue;
99 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
100 target[key] = source[key];
101 }
102 }
103 return target;
104 }
105 function _toConsumableArray(arr) {
106 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
107 }
108 function _arrayWithoutHoles(arr) {
109 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
110 }
111 function _iterableToArray(iter) {
112 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
113 }
114 function _unsupportedIterableToArray(o, minLen) {
115 if (!o) return;
116 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
117 var n = Object.prototype.toString.call(o).slice(8, -1);
118 if (n === "Object" && o.constructor) n = o.constructor.name;
119 if (n === "Map" || n === "Set") return Array.from(o);
120 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
121 }
122 function _arrayLikeToArray(arr, len) {
123 if (len == null || len > arr.length) len = arr.length;
124 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
125 return arr2;
126 }
127 function _nonIterableSpread() {
128 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
129 }
130
131 var version = "1.15.6";
132
133 function userAgent(pattern) {
134 if (typeof window !== 'undefined' && window.navigator) {
135 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
136 }
137 }
138 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
139 var Edge = userAgent(/Edge/i);
140 var FireFox = userAgent(/firefox/i);
141 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
142 var IOS = userAgent(/iP(ad|od|hone)/i);
143 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
144
145 var captureMode = {
146 capture: false,
147 passive: false
148 };
149 function on(el, event, fn) {
150 el.addEventListener(event, fn, !IE11OrLess && captureMode);
151 }
152 function off(el, event, fn) {
153 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
154 }
155 function matches( /**HTMLElement*/el, /**String*/selector) {
156 if (!selector) return;
157 selector[0] === '>' && (selector = selector.substring(1));
158 if (el) {
159 try {
160 if (el.matches) {
161 return el.matches(selector);
162 } else if (el.msMatchesSelector) {
163 return el.msMatchesSelector(selector);
164 } else if (el.webkitMatchesSelector) {
165 return el.webkitMatchesSelector(selector);
166 }
167 } catch (_) {
168 return false;
169 }
170 }
171 return false;
172 }
173 function getParentOrHost(el) {
174 return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode;
175 }
176 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
177 if (el) {
178 ctx = ctx || document;
179 do {
180 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
181 return el;
182 }
183 if (el === ctx) break;
184 /* jshint boss:true */
185 } while (el = getParentOrHost(el));
186 }
187 return null;
188 }
189 var R_SPACE = /\s+/g;
190 function toggleClass(el, name, state) {
191 if (el && name) {
192 if (el.classList) {
193 el.classList[state ? 'add' : 'remove'](name);
194 } else {
195 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
196 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
197 }
198 }
199 }
200 function css(el, prop, val) {
201 var style = el && el.style;
202 if (style) {
203 if (val === void 0) {
204 if (document.defaultView && document.defaultView.getComputedStyle) {
205 val = document.defaultView.getComputedStyle(el, '');
206 } else if (el.currentStyle) {
207 val = el.currentStyle;
208 }
209 return prop === void 0 ? val : val[prop];
210 } else {
211 if (!(prop in style) && prop.indexOf('webkit') === -1) {
212 prop = '-webkit-' + prop;
213 }
214 style[prop] = val + (typeof val === 'string' ? '' : 'px');
215 }
216 }
217 }
218 function matrix(el, selfOnly) {
219 var appliedTransforms = '';
220 if (typeof el === 'string') {
221 appliedTransforms = el;
222 } else {
223 do {
224 var transform = css(el, 'transform');
225 if (transform && transform !== 'none') {
226 appliedTransforms = transform + ' ' + appliedTransforms;
227 }
228 /* jshint boss:true */
229 } while (!selfOnly && (el = el.parentNode));
230 }
231 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
232 /*jshint -W056 */
233 return matrixFn && new matrixFn(appliedTransforms);
234 }
235 function find(ctx, tagName, iterator) {
236 if (ctx) {
237 var list = ctx.getElementsByTagName(tagName),
238 i = 0,
239 n = list.length;
240 if (iterator) {
241 for (; i < n; i++) {
242 iterator(list[i], i);
243 }
244 }
245 return list;
246 }
247 return [];
248 }
249 function getWindowScrollingElement() {
250 var scrollingElement = document.scrollingElement;
251 if (scrollingElement) {
252 return scrollingElement;
253 } else {
254 return document.documentElement;
255 }
256 }
257
258 /**
259 * Returns the "bounding client rect" of given element
260 * @param {HTMLElement} el The element whose boundingClientRect is wanted
261 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
262 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
263 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
264 * @param {[HTMLElement]} container The parent the element will be placed in
265 * @return {Object} The boundingClientRect of el, with specified adjustments
266 */
267 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
268 if (!el.getBoundingClientRect && el !== window) return;
269 var elRect, top, left, bottom, right, height, width;
270 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
271 elRect = el.getBoundingClientRect();
272 top = elRect.top;
273 left = elRect.left;
274 bottom = elRect.bottom;
275 right = elRect.right;
276 height = elRect.height;
277 width = elRect.width;
278 } else {
279 top = 0;
280 left = 0;
281 bottom = window.innerHeight;
282 right = window.innerWidth;
283 height = window.innerHeight;
284 width = window.innerWidth;
285 }
286 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
287 // Adjust for translate()
288 container = container || el.parentNode;
289
290 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
291 // Not needed on <= IE11
292 if (!IE11OrLess) {
293 do {
294 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
295 var containerRect = container.getBoundingClientRect();
296
297 // Set relative to edges of padding box of container
298 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
299 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
300 bottom = top + elRect.height;
301 right = left + elRect.width;
302 break;
303 }
304 /* jshint boss:true */
305 } while (container = container.parentNode);
306 }
307 }
308 if (undoScale && el !== window) {
309 // Adjust for scale()
310 var elMatrix = matrix(container || el),
311 scaleX = elMatrix && elMatrix.a,
312 scaleY = elMatrix && elMatrix.d;
313 if (elMatrix) {
314 top /= scaleY;
315 left /= scaleX;
316 width /= scaleX;
317 height /= scaleY;
318 bottom = top + height;
319 right = left + width;
320 }
321 }
322 return {
323 top: top,
324 left: left,
325 bottom: bottom,
326 right: right,
327 width: width,
328 height: height
329 };
330 }
331
332 /**
333 * Checks if a side of an element is scrolled past a side of its parents
334 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
335 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
336 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
337 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
338 */
339 function isScrolledPast(el, elSide, parentSide) {
340 var parent = getParentAutoScrollElement(el, true),
341 elSideVal = getRect(el)[elSide];
342
343 /* jshint boss:true */
344 while (parent) {
345 var parentSideVal = getRect(parent)[parentSide],
346 visible = void 0;
347 if (parentSide === 'top' || parentSide === 'left') {
348 visible = elSideVal >= parentSideVal;
349 } else {
350 visible = elSideVal <= parentSideVal;
351 }
352 if (!visible) return parent;
353 if (parent === getWindowScrollingElement()) break;
354 parent = getParentAutoScrollElement(parent, false);
355 }
356 return false;
357 }
358
359 /**
360 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
361 * and non-draggable elements
362 * @param {HTMLElement} el The parent element
363 * @param {Number} childNum The index of the child
364 * @param {Object} options Parent Sortable's options
365 * @return {HTMLElement} The child at index childNum, or null if not found
366 */
367 function getChild(el, childNum, options, includeDragEl) {
368 var currentChild = 0,
369 i = 0,
370 children = el.children;
371 while (i < children.length) {
372 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
373 if (currentChild === childNum) {
374 return children[i];
375 }
376 currentChild++;
377 }
378 i++;
379 }
380 return null;
381 }
382
383 /**
384 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
385 * @param {HTMLElement} el Parent element
386 * @param {selector} selector Any other elements that should be ignored
387 * @return {HTMLElement} The last child, ignoring ghostEl
388 */
389 function lastChild(el, selector) {
390 var last = el.lastElementChild;
391 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
392 last = last.previousElementSibling;
393 }
394 return last || null;
395 }
396
397 /**
398 * Returns the index of an element within its parent for a selected set of
399 * elements
400 * @param {HTMLElement} el
401 * @param {selector} selector
402 * @return {number}
403 */
404 function index(el, selector) {
405 var index = 0;
406 if (!el || !el.parentNode) {
407 return -1;
408 }
409
410 /* jshint boss:true */
411 while (el = el.previousElementSibling) {
412 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
413 index++;
414 }
415 }
416 return index;
417 }
418
419 /**
420 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
421 * The value is returned in real pixels.
422 * @param {HTMLElement} el
423 * @return {Array} Offsets in the format of [left, top]
424 */
425 function getRelativeScrollOffset(el) {
426 var offsetLeft = 0,
427 offsetTop = 0,
428 winScroller = getWindowScrollingElement();
429 if (el) {
430 do {
431 var elMatrix = matrix(el),
432 scaleX = elMatrix.a,
433 scaleY = elMatrix.d;
434 offsetLeft += el.scrollLeft * scaleX;
435 offsetTop += el.scrollTop * scaleY;
436 } while (el !== winScroller && (el = el.parentNode));
437 }
438 return [offsetLeft, offsetTop];
439 }
440
441 /**
442 * Returns the index of the object within the given array
443 * @param {Array} arr Array that may or may not hold the object
444 * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
445 * @return {Number} The index of the object in the array, or -1
446 */
447 function indexOfObject(arr, obj) {
448 for (var i in arr) {
449 if (!arr.hasOwnProperty(i)) continue;
450 for (var key in obj) {
451 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
452 }
453 }
454 return -1;
455 }
456 function getParentAutoScrollElement(el, includeSelf) {
457 // skip to window
458 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
459 var elem = el;
460 var gotSelf = false;
461 do {
462 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
463 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
464 var elemCSS = css(elem);
465 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
466 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
467 if (gotSelf || includeSelf) return elem;
468 gotSelf = true;
469 }
470 }
471 /* jshint boss:true */
472 } while (elem = elem.parentNode);
473 return getWindowScrollingElement();
474 }
475 function extend(dst, src) {
476 if (dst && src) {
477 for (var key in src) {
478 if (src.hasOwnProperty(key)) {
479 dst[key] = src[key];
480 }
481 }
482 }
483 return dst;
484 }
485 function isRectEqual(rect1, rect2) {
486 return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
487 }
488 var _throttleTimeout;
489 function throttle(callback, ms) {
490 return function () {
491 if (!_throttleTimeout) {
492 var args = arguments,
493 _this = this;
494 if (args.length === 1) {
495 callback.call(_this, args[0]);
496 } else {
497 callback.apply(_this, args);
498 }
499 _throttleTimeout = setTimeout(function () {
500 _throttleTimeout = void 0;
501 }, ms);
502 }
503 };
504 }
505 function cancelThrottle() {
506 clearTimeout(_throttleTimeout);
507 _throttleTimeout = void 0;
508 }
509 function scrollBy(el, x, y) {
510 el.scrollLeft += x;
511 el.scrollTop += y;
512 }
513 function clone(el) {
514 var Polymer = window.Polymer;
515 var $ = window.jQuery || window.Zepto;
516 if (Polymer && Polymer.dom) {
517 return Polymer.dom(el).cloneNode(true);
518 } else if ($) {
519 return $(el).clone(true)[0];
520 } else {
521 return el.cloneNode(true);
522 }
523 }
524 function setRect(el, rect) {
525 css(el, 'position', 'absolute');
526 css(el, 'top', rect.top);
527 css(el, 'left', rect.left);
528 css(el, 'width', rect.width);
529 css(el, 'height', rect.height);
530 }
531 function unsetRect(el) {
532 css(el, 'position', '');
533 css(el, 'top', '');
534 css(el, 'left', '');
535 css(el, 'width', '');
536 css(el, 'height', '');
537 }
538 function getChildContainingRectFromElement(container, options, ghostEl) {
539 var rect = {};
540 Array.from(container.children).forEach(function (child) {
541 var _rect$left, _rect$top, _rect$right, _rect$bottom;
542 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
543 var childRect = getRect(child);
544 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
545 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
546 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
547 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
548 });
549 rect.width = rect.right - rect.left;
550 rect.height = rect.bottom - rect.top;
551 rect.x = rect.left;
552 rect.y = rect.top;
553 return rect;
554 }
555 var expando = 'Sortable' + new Date().getTime();
556
557 function AnimationStateManager() {
558 var animationStates = [],
559 animationCallbackId;
560 return {
561 captureAnimationState: function captureAnimationState() {
562 animationStates = [];
563 if (!this.options.animation) return;
564 var children = [].slice.call(this.el.children);
565 children.forEach(function (child) {
566 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
567 animationStates.push({
568 target: child,
569 rect: getRect(child)
570 });
571 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
572
573 // If animating: compensate for current animation
574 if (child.thisAnimationDuration) {
575 var childMatrix = matrix(child, true);
576 if (childMatrix) {
577 fromRect.top -= childMatrix.f;
578 fromRect.left -= childMatrix.e;
579 }
580 }
581 child.fromRect = fromRect;
582 });
583 },
584 addAnimationState: function addAnimationState(state) {
585 animationStates.push(state);
586 },
587 removeAnimationState: function removeAnimationState(target) {
588 animationStates.splice(indexOfObject(animationStates, {
589 target: target
590 }), 1);
591 },
592 animateAll: function animateAll(callback) {
593 var _this = this;
594 if (!this.options.animation) {
595 clearTimeout(animationCallbackId);
596 if (typeof callback === 'function') callback();
597 return;
598 }
599 var animating = false,
600 animationTime = 0;
601 animationStates.forEach(function (state) {
602 var time = 0,
603 target = state.target,
604 fromRect = target.fromRect,
605 toRect = getRect(target),
606 prevFromRect = target.prevFromRect,
607 prevToRect = target.prevToRect,
608 animatingRect = state.rect,
609 targetMatrix = matrix(target, true);
610 if (targetMatrix) {
611 // Compensate for current animation
612 toRect.top -= targetMatrix.f;
613 toRect.left -= targetMatrix.e;
614 }
615 target.toRect = toRect;
616 if (target.thisAnimationDuration) {
617 // Could also check if animatingRect is between fromRect and toRect
618 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
619 // Make sure animatingRect is on line between toRect & fromRect
620 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
621 // If returning to same place as started from animation and on same axis
622 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
623 }
624 }
625
626 // if fromRect != toRect: animate
627 if (!isRectEqual(toRect, fromRect)) {
628 target.prevFromRect = fromRect;
629 target.prevToRect = toRect;
630 if (!time) {
631 time = _this.options.animation;
632 }
633 _this.animate(target, animatingRect, toRect, time);
634 }
635 if (time) {
636 animating = true;
637 animationTime = Math.max(animationTime, time);
638 clearTimeout(target.animationResetTimer);
639 target.animationResetTimer = setTimeout(function () {
640 target.animationTime = 0;
641 target.prevFromRect = null;
642 target.fromRect = null;
643 target.prevToRect = null;
644 target.thisAnimationDuration = null;
645 }, time);
646 target.thisAnimationDuration = time;
647 }
648 });
649 clearTimeout(animationCallbackId);
650 if (!animating) {
651 if (typeof callback === 'function') callback();
652 } else {
653 animationCallbackId = setTimeout(function () {
654 if (typeof callback === 'function') callback();
655 }, animationTime);
656 }
657 animationStates = [];
658 },
659 animate: function animate(target, currentRect, toRect, duration) {
660 if (duration) {
661 css(target, 'transition', '');
662 css(target, 'transform', '');
663 var elMatrix = matrix(this.el),
664 scaleX = elMatrix && elMatrix.a,
665 scaleY = elMatrix && elMatrix.d,
666 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
667 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
668 target.animatingX = !!translateX;
669 target.animatingY = !!translateY;
670 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
671 this.forRepaintDummy = repaint(target); // repaint
672
673 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
674 css(target, 'transform', 'translate3d(0,0,0)');
675 typeof target.animated === 'number' && clearTimeout(target.animated);
676 target.animated = setTimeout(function () {
677 css(target, 'transition', '');
678 css(target, 'transform', '');
679 target.animated = false;
680 target.animatingX = false;
681 target.animatingY = false;
682 }, duration);
683 }
684 }
685 };
686 }
687 function repaint(target) {
688 return target.offsetWidth;
689 }
690 function calculateRealTime(animatingRect, fromRect, toRect, options) {
691 return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
692 }
693
694 var plugins = [];
695 var defaults = {
696 initializeByDefault: true
697 };
698 var PluginManager = {
699 mount: function mount(plugin) {
700 // Set default static properties
701 for (var option in defaults) {
702 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
703 plugin[option] = defaults[option];
704 }
705 }
706 plugins.forEach(function (p) {
707 if (p.pluginName === plugin.pluginName) {
708 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
709 }
710 });
711 plugins.push(plugin);
712 },
713 pluginEvent: function pluginEvent(eventName, sortable, evt) {
714 var _this = this;
715 this.eventCanceled = false;
716 evt.cancel = function () {
717 _this.eventCanceled = true;
718 };
719 var eventNameGlobal = eventName + 'Global';
720 plugins.forEach(function (plugin) {
721 if (!sortable[plugin.pluginName]) return;
722 // Fire global events if it exists in this sortable
723 if (sortable[plugin.pluginName][eventNameGlobal]) {
724 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
725 sortable: sortable
726 }, evt));
727 }
728
729 // Only fire plugin event if plugin is enabled in this sortable,
730 // and plugin has event defined
731 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
732 sortable[plugin.pluginName][eventName](_objectSpread2({
733 sortable: sortable
734 }, evt));
735 }
736 });
737 },
738 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
739 plugins.forEach(function (plugin) {
740 var pluginName = plugin.pluginName;
741 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
742 var initialized = new plugin(sortable, el, sortable.options);
743 initialized.sortable = sortable;
744 initialized.options = sortable.options;
745 sortable[pluginName] = initialized;
746
747 // Add default options from plugin
748 _extends(defaults, initialized.defaults);
749 });
750 for (var option in sortable.options) {
751 if (!sortable.options.hasOwnProperty(option)) continue;
752 var modified = this.modifyOption(sortable, option, sortable.options[option]);
753 if (typeof modified !== 'undefined') {
754 sortable.options[option] = modified;
755 }
756 }
757 },
758 getEventProperties: function getEventProperties(name, sortable) {
759 var eventProperties = {};
760 plugins.forEach(function (plugin) {
761 if (typeof plugin.eventProperties !== 'function') return;
762 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
763 });
764 return eventProperties;
765 },
766 modifyOption: function modifyOption(sortable, name, value) {
767 var modifiedValue;
768 plugins.forEach(function (plugin) {
769 // Plugin must exist on the Sortable
770 if (!sortable[plugin.pluginName]) return;
771
772 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
773 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
774 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
775 }
776 });
777 return modifiedValue;
778 }
779 };
780
781 function dispatchEvent(_ref) {
782 var sortable = _ref.sortable,
783 rootEl = _ref.rootEl,
784 name = _ref.name,
785 targetEl = _ref.targetEl,
786 cloneEl = _ref.cloneEl,
787 toEl = _ref.toEl,
788 fromEl = _ref.fromEl,
789 oldIndex = _ref.oldIndex,
790 newIndex = _ref.newIndex,
791 oldDraggableIndex = _ref.oldDraggableIndex,
792 newDraggableIndex = _ref.newDraggableIndex,
793 originalEvent = _ref.originalEvent,
794 putSortable = _ref.putSortable,
795 extraEventProperties = _ref.extraEventProperties;
796 sortable = sortable || rootEl && rootEl[expando];
797 if (!sortable) return;
798 var evt,
799 options = sortable.options,
800 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
801 // Support for new CustomEvent feature
802 if (window.CustomEvent && !IE11OrLess && !Edge) {
803 evt = new CustomEvent(name, {
804 bubbles: true,
805 cancelable: true
806 });
807 } else {
808 evt = document.createEvent('Event');
809 evt.initEvent(name, true, true);
810 }
811 evt.to = toEl || rootEl;
812 evt.from = fromEl || rootEl;
813 evt.item = targetEl || rootEl;
814 evt.clone = cloneEl;
815 evt.oldIndex = oldIndex;
816 evt.newIndex = newIndex;
817 evt.oldDraggableIndex = oldDraggableIndex;
818 evt.newDraggableIndex = newDraggableIndex;
819 evt.originalEvent = originalEvent;
820 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
821 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
822 for (var option in allEventProperties) {
823 evt[option] = allEventProperties[option];
824 }
825 if (rootEl) {
826 rootEl.dispatchEvent(evt);
827 }
828 if (options[onName]) {
829 options[onName].call(sortable, evt);
830 }
831 }
832
833 var _excluded = ["evt"];
834 var pluginEvent = function pluginEvent(eventName, sortable) {
835 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
836 originalEvent = _ref.evt,
837 data = _objectWithoutProperties(_ref, _excluded);
838 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
839 dragEl: dragEl,
840 parentEl: parentEl,
841 ghostEl: ghostEl,
842 rootEl: rootEl,
843 nextEl: nextEl,
844 lastDownEl: lastDownEl,
845 cloneEl: cloneEl,
846 cloneHidden: cloneHidden,
847 dragStarted: moved,
848 putSortable: putSortable,
849 activeSortable: Sortable.active,
850 originalEvent: originalEvent,
851 oldIndex: oldIndex,
852 oldDraggableIndex: oldDraggableIndex,
853 newIndex: newIndex,
854 newDraggableIndex: newDraggableIndex,
855 hideGhostForTarget: _hideGhostForTarget,
856 unhideGhostForTarget: _unhideGhostForTarget,
857 cloneNowHidden: function cloneNowHidden() {
858 cloneHidden = true;
859 },
860 cloneNowShown: function cloneNowShown() {
861 cloneHidden = false;
862 },
863 dispatchSortableEvent: function dispatchSortableEvent(name) {
864 _dispatchEvent({
865 sortable: sortable,
866 name: name,
867 originalEvent: originalEvent
868 });
869 }
870 }, data));
871 };
872 function _dispatchEvent(info) {
873 dispatchEvent(_objectSpread2({
874 putSortable: putSortable,
875 cloneEl: cloneEl,
876 targetEl: dragEl,
877 rootEl: rootEl,
878 oldIndex: oldIndex,
879 oldDraggableIndex: oldDraggableIndex,
880 newIndex: newIndex,
881 newDraggableIndex: newDraggableIndex
882 }, info));
883 }
884 var dragEl,
885 parentEl,
886 ghostEl,
887 rootEl,
888 nextEl,
889 lastDownEl,
890 cloneEl,
891 cloneHidden,
892 oldIndex,
893 newIndex,
894 oldDraggableIndex,
895 newDraggableIndex,
896 activeGroup,
897 putSortable,
898 awaitingDragStarted = false,
899 ignoreNextClick = false,
900 sortables = [],
901 tapEvt,
902 touchEvt,
903 lastDx,
904 lastDy,
905 tapDistanceLeft,
906 tapDistanceTop,
907 moved,
908 lastTarget,
909 lastDirection,
910 pastFirstInvertThresh = false,
911 isCircumstantialInvert = false,
912 targetMoveDistance,
913 // For positioning ghost absolutely
914 ghostRelativeParent,
915 ghostRelativeParentInitialScroll = [],
916 // (left, top)
917
918 _silent = false,
919 savedInputChecked = [];
920
921 /** @const */
922 var documentExists = typeof document !== 'undefined',
923 PositionGhostAbsolutely = IOS,
924 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
925 // This will not pass for IE9, because IE9 DnD only works on anchors
926 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
927 supportCssPointerEvents = function () {
928 if (!documentExists) return;
929 // false when <= IE11
930 if (IE11OrLess) {
931 return false;
932 }
933 var el = document.createElement('x');
934 el.style.cssText = 'pointer-events:auto';
935 return el.style.pointerEvents === 'auto';
936 }(),
937 _detectDirection = function _detectDirection(el, options) {
938 var elCSS = css(el),
939 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
940 child1 = getChild(el, 0, options),
941 child2 = getChild(el, 1, options),
942 firstChildCSS = child1 && css(child1),
943 secondChildCSS = child2 && css(child2),
944 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
945 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
946 if (elCSS.display === 'flex') {
947 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
948 }
949 if (elCSS.display === 'grid') {
950 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
951 }
952 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
953 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
954 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
955 }
956 return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
957 },
958 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
959 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
960 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
961 dragElOppLength = vertical ? dragRect.width : dragRect.height,
962 targetS1Opp = vertical ? targetRect.left : targetRect.top,
963 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
964 targetOppLength = vertical ? targetRect.width : targetRect.height;
965 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
966 },
967 /**
968 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
969 * @param {Number} x X position
970 * @param {Number} y Y position
971 * @return {HTMLElement} Element of the first found nearest Sortable
972 */
973 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
974 var ret;
975 sortables.some(function (sortable) {
976 var threshold = sortable[expando].options.emptyInsertThreshold;
977 if (!threshold || lastChild(sortable)) return;
978 var rect = getRect(sortable),
979 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
980 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
981 if (insideHorizontally && insideVertically) {
982 return ret = sortable;
983 }
984 });
985 return ret;
986 },
987 _prepareGroup = function _prepareGroup(options) {
988 function toFn(value, pull) {
989 return function (to, from, dragEl, evt) {
990 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
991 if (value == null && (pull || sameGroup)) {
992 // Default pull value
993 // Default pull and put value if same group
994 return true;
995 } else if (value == null || value === false) {
996 return false;
997 } else if (pull && value === 'clone') {
998 return value;
999 } else if (typeof value === 'function') {
1000 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
1001 } else {
1002 var otherGroup = (pull ? to : from).options.group.name;
1003 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
1004 }
1005 };
1006 }
1007 var group = {};
1008 var originalGroup = options.group;
1009 if (!originalGroup || _typeof(originalGroup) != 'object') {
1010 originalGroup = {
1011 name: originalGroup
1012 };
1013 }
1014 group.name = originalGroup.name;
1015 group.checkPull = toFn(originalGroup.pull, true);
1016 group.checkPut = toFn(originalGroup.put);
1017 group.revertClone = originalGroup.revertClone;
1018 options.group = group;
1019 },
1020 _hideGhostForTarget = function _hideGhostForTarget() {
1021 if (!supportCssPointerEvents && ghostEl) {
1022 css(ghostEl, 'display', 'none');
1023 }
1024 },
1025 _unhideGhostForTarget = function _unhideGhostForTarget() {
1026 if (!supportCssPointerEvents && ghostEl) {
1027 css(ghostEl, 'display', '');
1028 }
1029 };
1030
1031 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
1032 if (documentExists && !ChromeForAndroid) {
1033 document.addEventListener('click', function (evt) {
1034 if (ignoreNextClick) {
1035 evt.preventDefault();
1036 evt.stopPropagation && evt.stopPropagation();
1037 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
1038 ignoreNextClick = false;
1039 return false;
1040 }
1041 }, true);
1042 }
1043 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
1044 if (dragEl) {
1045 evt = evt.touches ? evt.touches[0] : evt;
1046 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
1047 if (nearest) {
1048 // Create imitation event
1049 var event = {};
1050 for (var i in evt) {
1051 if (evt.hasOwnProperty(i)) {
1052 event[i] = evt[i];
1053 }
1054 }
1055 event.target = event.rootEl = nearest;
1056 event.preventDefault = void 0;
1057 event.stopPropagation = void 0;
1058 nearest[expando]._onDragOver(event);
1059 }
1060 }
1061 };
1062 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
1063 if (dragEl) {
1064 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
1065 }
1066 };
1067
1068 /**
1069 * @class Sortable
1070 * @param {HTMLElement} el
1071 * @param {Object} [options]
1072 */
1073 function Sortable(el, options) {
1074 if (!(el && el.nodeType && el.nodeType === 1)) {
1075 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
1076 }
1077 this.el = el; // root element
1078 this.options = options = _extends({}, options);
1079
1080 // Export instance
1081 el[expando] = this;
1082 var defaults = {
1083 group: null,
1084 sort: true,
1085 disabled: false,
1086 store: null,
1087 handle: null,
1088 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
1089 swapThreshold: 1,
1090 // percentage; 0 <= x <= 1
1091 invertSwap: false,
1092 // invert always
1093 invertedSwapThreshold: null,
1094 // will be set to same as swapThreshold if default
1095 removeCloneOnHide: true,
1096 direction: function direction() {
1097 return _detectDirection(el, this.options);
1098 },
1099 ghostClass: 'sortable-ghost',
1100 chosenClass: 'sortable-chosen',
1101 dragClass: 'sortable-drag',
1102 ignore: 'a, img',
1103 filter: null,
1104 preventOnFilter: true,
1105 animation: 0,
1106 easing: null,
1107 setData: function setData(dataTransfer, dragEl) {
1108 dataTransfer.setData('Text', dragEl.textContent);
1109 },
1110 dropBubble: false,
1111 dragoverBubble: false,
1112 dataIdAttr: 'data-id',
1113 delay: 0,
1114 delayOnTouchOnly: false,
1115 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
1116 forceFallback: false,
1117 fallbackClass: 'sortable-fallback',
1118 fallbackOnBody: false,
1119 fallbackTolerance: 0,
1120 fallbackOffset: {
1121 x: 0,
1122 y: 0
1123 },
1124 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
1125 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
1126 emptyInsertThreshold: 5
1127 };
1128 PluginManager.initializePlugins(this, el, defaults);
1129
1130 // Set default options
1131 for (var name in defaults) {
1132 !(name in options) && (options[name] = defaults[name]);
1133 }
1134 _prepareGroup(options);
1135
1136 // Bind all private methods
1137 for (var fn in this) {
1138 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
1139 this[fn] = this[fn].bind(this);
1140 }
1141 }
1142
1143 // Setup drag mode
1144 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
1145 if (this.nativeDraggable) {
1146 // Touch start threshold cannot be greater than the native dragstart threshold
1147 this.options.touchStartThreshold = 1;
1148 }
1149
1150 // Bind events
1151 if (options.supportPointer) {
1152 on(el, 'pointerdown', this._onTapStart);
1153 } else {
1154 on(el, 'mousedown', this._onTapStart);
1155 on(el, 'touchstart', this._onTapStart);
1156 }
1157 if (this.nativeDraggable) {
1158 on(el, 'dragover', this);
1159 on(el, 'dragenter', this);
1160 }
1161 sortables.push(this.el);
1162
1163 // Restore sorting
1164 options.store && options.store.get && this.sort(options.store.get(this) || []);
1165
1166 // Add animation state manager
1167 _extends(this, AnimationStateManager());
1168 }
1169 Sortable.prototype = /** @lends Sortable.prototype */{
1170 constructor: Sortable,
1171 _isOutsideThisEl: function _isOutsideThisEl(target) {
1172 if (!this.el.contains(target) && target !== this.el) {
1173 lastTarget = null;
1174 }
1175 },
1176 _getDirection: function _getDirection(evt, target) {
1177 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
1178 },
1179 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
1180 if (!evt.cancelable) return;
1181 var _this = this,
1182 el = this.el,
1183 options = this.options,
1184 preventOnFilter = options.preventOnFilter,
1185 type = evt.type,
1186 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
1187 target = (touch || evt).target,
1188 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
1189 filter = options.filter;
1190 _saveInputCheckedState(el);
1191
1192 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
1193 if (dragEl) {
1194 return;
1195 }
1196 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
1197 return; // only left button and enabled
1198 }
1199
1200 // cancel dnd if original target is content editable
1201 if (originalTarget.isContentEditable) {
1202 return;
1203 }
1204
1205 // Safari ignores further event handling after mousedown
1206 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
1207 return;
1208 }
1209 target = closest(target, options.draggable, el, false);
1210 if (target && target.animated) {
1211 return;
1212 }
1213 if (lastDownEl === target) {
1214 // Ignoring duplicate `down`
1215 return;
1216 }
1217
1218 // Get the index of the dragged element within its parent
1219 oldIndex = index(target);
1220 oldDraggableIndex = index(target, options.draggable);
1221
1222 // Check filter
1223 if (typeof filter === 'function') {
1224 if (filter.call(this, evt, target, this)) {
1225 _dispatchEvent({
1226 sortable: _this,
1227 rootEl: originalTarget,
1228 name: 'filter',
1229 targetEl: target,
1230 toEl: el,
1231 fromEl: el
1232 });
1233 pluginEvent('filter', _this, {
1234 evt: evt
1235 });
1236 preventOnFilter && evt.preventDefault();
1237 return; // cancel dnd
1238 }
1239 } else if (filter) {
1240 filter = filter.split(',').some(function (criteria) {
1241 criteria = closest(originalTarget, criteria.trim(), el, false);
1242 if (criteria) {
1243 _dispatchEvent({
1244 sortable: _this,
1245 rootEl: criteria,
1246 name: 'filter',
1247 targetEl: target,
1248 fromEl: el,
1249 toEl: el
1250 });
1251 pluginEvent('filter', _this, {
1252 evt: evt
1253 });
1254 return true;
1255 }
1256 });
1257 if (filter) {
1258 preventOnFilter && evt.preventDefault();
1259 return; // cancel dnd
1260 }
1261 }
1262 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
1263 return;
1264 }
1265
1266 // Prepare `dragstart`
1267 this._prepareDragStart(evt, touch, target);
1268 },
1269 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
1270 var _this = this,
1271 el = _this.el,
1272 options = _this.options,
1273 ownerDocument = el.ownerDocument,
1274 dragStartFn;
1275 if (target && !dragEl && target.parentNode === el) {
1276 var dragRect = getRect(target);
1277 rootEl = el;
1278 dragEl = target;
1279 parentEl = dragEl.parentNode;
1280 nextEl = dragEl.nextSibling;
1281 lastDownEl = target;
1282 activeGroup = options.group;
1283 Sortable.dragged = dragEl;
1284 tapEvt = {
1285 target: dragEl,
1286 clientX: (touch || evt).clientX,
1287 clientY: (touch || evt).clientY
1288 };
1289 tapDistanceLeft = tapEvt.clientX - dragRect.left;
1290 tapDistanceTop = tapEvt.clientY - dragRect.top;
1291 this._lastX = (touch || evt).clientX;
1292 this._lastY = (touch || evt).clientY;
1293 dragEl.style['will-change'] = 'all';
1294 dragStartFn = function dragStartFn() {
1295 pluginEvent('delayEnded', _this, {
1296 evt: evt
1297 });
1298 if (Sortable.eventCanceled) {
1299 _this._onDrop();
1300 return;
1301 }
1302 // Delayed drag has been triggered
1303 // we can re-enable the events: touchmove/mousemove
1304 _this._disableDelayedDragEvents();
1305 if (!FireFox && _this.nativeDraggable) {
1306 dragEl.draggable = true;
1307 }
1308
1309 // Bind the events: dragstart/dragend
1310 _this._triggerDragStart(evt, touch);
1311
1312 // Drag start event
1313 _dispatchEvent({
1314 sortable: _this,
1315 name: 'choose',
1316 originalEvent: evt
1317 });
1318
1319 // Chosen item
1320 toggleClass(dragEl, options.chosenClass, true);
1321 };
1322
1323 // Disable "draggable"
1324 options.ignore.split(',').forEach(function (criteria) {
1325 find(dragEl, criteria.trim(), _disableDraggable);
1326 });
1327 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
1328 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
1329 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
1330 if (options.supportPointer) {
1331 on(ownerDocument, 'pointerup', _this._onDrop);
1332 // Native D&D triggers pointercancel
1333 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
1334 } else {
1335 on(ownerDocument, 'mouseup', _this._onDrop);
1336 on(ownerDocument, 'touchend', _this._onDrop);
1337 on(ownerDocument, 'touchcancel', _this._onDrop);
1338 }
1339
1340 // Make dragEl draggable (must be before delay for FireFox)
1341 if (FireFox && this.nativeDraggable) {
1342 this.options.touchStartThreshold = 4;
1343 dragEl.draggable = true;
1344 }
1345 pluginEvent('delayStart', this, {
1346 evt: evt
1347 });
1348
1349 // Delay is impossible for native DnD in Edge or IE
1350 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
1351 if (Sortable.eventCanceled) {
1352 this._onDrop();
1353 return;
1354 }
1355 // If the user moves the pointer or let go the click or touch
1356 // before the delay has been reached:
1357 // disable the delayed drag
1358 if (options.supportPointer) {
1359 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
1360 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
1361 } else {
1362 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
1363 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
1364 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
1365 }
1366 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
1367 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
1368 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
1369 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
1370 } else {
1371 dragStartFn();
1372 }
1373 }
1374 },
1375 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
1376 var touch = e.touches ? e.touches[0] : e;
1377 if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
1378 this._disableDelayedDrag();
1379 }
1380 },
1381 _disableDelayedDrag: function _disableDelayedDrag() {
1382 dragEl && _disableDraggable(dragEl);
1383 clearTimeout(this._dragStartTimer);
1384 this._disableDelayedDragEvents();
1385 },
1386 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
1387 var ownerDocument = this.el.ownerDocument;
1388 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
1389 off(ownerDocument, 'touchend', this._disableDelayedDrag);
1390 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
1391 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
1392 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
1393 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
1394 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
1395 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
1396 },
1397 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
1398 touch = touch || evt.pointerType == 'touch' && evt;
1399 if (!this.nativeDraggable || touch) {
1400 if (this.options.supportPointer) {
1401 on(document, 'pointermove', this._onTouchMove);
1402 } else if (touch) {
1403 on(document, 'touchmove', this._onTouchMove);
1404 } else {
1405 on(document, 'mousemove', this._onTouchMove);
1406 }
1407 } else {
1408 on(dragEl, 'dragend', this);
1409 on(rootEl, 'dragstart', this._onDragStart);
1410 }
1411 try {
1412 if (document.selection) {
1413 _nextTick(function () {
1414 document.selection.empty();
1415 });
1416 } else {
1417 window.getSelection().removeAllRanges();
1418 }
1419 } catch (err) {}
1420 },
1421 _dragStarted: function _dragStarted(fallback, evt) {
1422 awaitingDragStarted = false;
1423 if (rootEl && dragEl) {
1424 pluginEvent('dragStarted', this, {
1425 evt: evt
1426 });
1427 if (this.nativeDraggable) {
1428 on(document, 'dragover', _checkOutsideTargetEl);
1429 }
1430 var options = this.options;
1431
1432 // Apply effect
1433 !fallback && toggleClass(dragEl, options.dragClass, false);
1434 toggleClass(dragEl, options.ghostClass, true);
1435 Sortable.active = this;
1436 fallback && this._appendGhost();
1437
1438 // Drag start event
1439 _dispatchEvent({
1440 sortable: this,
1441 name: 'start',
1442 originalEvent: evt
1443 });
1444 } else {
1445 this._nulling();
1446 }
1447 },
1448 _emulateDragOver: function _emulateDragOver() {
1449 if (touchEvt) {
1450 this._lastX = touchEvt.clientX;
1451 this._lastY = touchEvt.clientY;
1452 _hideGhostForTarget();
1453 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
1454 var parent = target;
1455 while (target && target.shadowRoot) {
1456 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
1457 if (target === parent) break;
1458 parent = target;
1459 }
1460 dragEl.parentNode[expando]._isOutsideThisEl(target);
1461 if (parent) {
1462 do {
1463 if (parent[expando]) {
1464 var inserted = void 0;
1465 inserted = parent[expando]._onDragOver({
1466 clientX: touchEvt.clientX,
1467 clientY: touchEvt.clientY,
1468 target: target,
1469 rootEl: parent
1470 });
1471 if (inserted && !this.options.dragoverBubble) {
1472 break;
1473 }
1474 }
1475 target = parent; // store last element
1476 }
1477 /* jshint boss:true */ while (parent = getParentOrHost(parent));
1478 }
1479 _unhideGhostForTarget();
1480 }
1481 },
1482 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
1483 if (tapEvt) {
1484 var options = this.options,
1485 fallbackTolerance = options.fallbackTolerance,
1486 fallbackOffset = options.fallbackOffset,
1487 touch = evt.touches ? evt.touches[0] : evt,
1488 ghostMatrix = ghostEl && matrix(ghostEl, true),
1489 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
1490 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
1491 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
1492 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
1493 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
1494
1495 // only set the status to dragging, when we are actually dragging
1496 if (!Sortable.active && !awaitingDragStarted) {
1497 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
1498 return;
1499 }
1500 this._onDragStart(evt, true);
1501 }
1502 if (ghostEl) {
1503 if (ghostMatrix) {
1504 ghostMatrix.e += dx - (lastDx || 0);
1505 ghostMatrix.f += dy - (lastDy || 0);
1506 } else {
1507 ghostMatrix = {
1508 a: 1,
1509 b: 0,
1510 c: 0,
1511 d: 1,
1512 e: dx,
1513 f: dy
1514 };
1515 }
1516 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
1517 css(ghostEl, 'webkitTransform', cssMatrix);
1518 css(ghostEl, 'mozTransform', cssMatrix);
1519 css(ghostEl, 'msTransform', cssMatrix);
1520 css(ghostEl, 'transform', cssMatrix);
1521 lastDx = dx;
1522 lastDy = dy;
1523 touchEvt = touch;
1524 }
1525 evt.cancelable && evt.preventDefault();
1526 }
1527 },
1528 _appendGhost: function _appendGhost() {
1529 // Bug if using scale(): https://stackoverflow.com/questions/2637058
1530 // Not being adjusted for
1531 if (!ghostEl) {
1532 var container = this.options.fallbackOnBody ? document.body : rootEl,
1533 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
1534 options = this.options;
1535
1536 // Position absolutely
1537 if (PositionGhostAbsolutely) {
1538 // Get relatively positioned parent
1539 ghostRelativeParent = container;
1540 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
1541 ghostRelativeParent = ghostRelativeParent.parentNode;
1542 }
1543 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
1544 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
1545 rect.top += ghostRelativeParent.scrollTop;
1546 rect.left += ghostRelativeParent.scrollLeft;
1547 } else {
1548 ghostRelativeParent = getWindowScrollingElement();
1549 }
1550 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
1551 }
1552 ghostEl = dragEl.cloneNode(true);
1553 toggleClass(ghostEl, options.ghostClass, false);
1554 toggleClass(ghostEl, options.fallbackClass, true);
1555 toggleClass(ghostEl, options.dragClass, true);
1556 css(ghostEl, 'transition', '');
1557 css(ghostEl, 'transform', '');
1558 css(ghostEl, 'box-sizing', 'border-box');
1559 css(ghostEl, 'margin', 0);
1560 css(ghostEl, 'top', rect.top);
1561 css(ghostEl, 'left', rect.left);
1562 css(ghostEl, 'width', rect.width);
1563 css(ghostEl, 'height', rect.height);
1564 css(ghostEl, 'opacity', '0.8');
1565 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
1566 css(ghostEl, 'zIndex', '100000');
1567 css(ghostEl, 'pointerEvents', 'none');
1568 Sortable.ghost = ghostEl;
1569 container.appendChild(ghostEl);
1570
1571 // Set transform-origin
1572 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
1573 }
1574 },
1575 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
1576 var _this = this;
1577 var dataTransfer = evt.dataTransfer;
1578 var options = _this.options;
1579 pluginEvent('dragStart', this, {
1580 evt: evt
1581 });
1582 if (Sortable.eventCanceled) {
1583 this._onDrop();
1584 return;
1585 }
1586 pluginEvent('setupClone', this);
1587 if (!Sortable.eventCanceled) {
1588 cloneEl = clone(dragEl);
1589 cloneEl.removeAttribute("id");
1590 cloneEl.draggable = false;
1591 cloneEl.style['will-change'] = '';
1592 this._hideClone();
1593 toggleClass(cloneEl, this.options.chosenClass, false);
1594 Sortable.clone = cloneEl;
1595 }
1596
1597 // #1143: IFrame support workaround
1598 _this.cloneId = _nextTick(function () {
1599 pluginEvent('clone', _this);
1600 if (Sortable.eventCanceled) return;
1601 if (!_this.options.removeCloneOnHide) {
1602 rootEl.insertBefore(cloneEl, dragEl);
1603 }
1604 _this._hideClone();
1605 _dispatchEvent({
1606 sortable: _this,
1607 name: 'clone'
1608 });
1609 });
1610 !fallback && toggleClass(dragEl, options.dragClass, true);
1611
1612 // Set proper drop events
1613 if (fallback) {
1614 ignoreNextClick = true;
1615 _this._loopId = setInterval(_this._emulateDragOver, 50);
1616 } else {
1617 // Undo what was set in _prepareDragStart before drag started
1618 off(document, 'mouseup', _this._onDrop);
1619 off(document, 'touchend', _this._onDrop);
1620 off(document, 'touchcancel', _this._onDrop);
1621 if (dataTransfer) {
1622 dataTransfer.effectAllowed = 'move';
1623 options.setData && options.setData.call(_this, dataTransfer, dragEl);
1624 }
1625 on(document, 'drop', _this);
1626
1627 // #1276 fix:
1628 css(dragEl, 'transform', 'translateZ(0)');
1629 }
1630 awaitingDragStarted = true;
1631 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
1632 on(document, 'selectstart', _this);
1633 moved = true;
1634 window.getSelection().removeAllRanges();
1635 if (Safari) {
1636 css(document.body, 'user-select', 'none');
1637 }
1638 },
1639 // Returns true - if no further action is needed (either inserted or another condition)
1640 _onDragOver: function _onDragOver( /**Event*/evt) {
1641 var el = this.el,
1642 target = evt.target,
1643 dragRect,
1644 targetRect,
1645 revert,
1646 options = this.options,
1647 group = options.group,
1648 activeSortable = Sortable.active,
1649 isOwner = activeGroup === group,
1650 canSort = options.sort,
1651 fromSortable = putSortable || activeSortable,
1652 vertical,
1653 _this = this,
1654 completedFired = false;
1655 if (_silent) return;
1656 function dragOverEvent(name, extra) {
1657 pluginEvent(name, _this, _objectSpread2({
1658 evt: evt,
1659 isOwner: isOwner,
1660 axis: vertical ? 'vertical' : 'horizontal',
1661 revert: revert,
1662 dragRect: dragRect,
1663 targetRect: targetRect,
1664 canSort: canSort,
1665 fromSortable: fromSortable,
1666 target: target,
1667 completed: completed,
1668 onMove: function onMove(target, after) {
1669 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
1670 },
1671 changed: changed
1672 }, extra));
1673 }
1674
1675 // Capture animation state
1676 function capture() {
1677 dragOverEvent('dragOverAnimationCapture');
1678 _this.captureAnimationState();
1679 if (_this !== fromSortable) {
1680 fromSortable.captureAnimationState();
1681 }
1682 }
1683
1684 // Return invocation when dragEl is inserted (or completed)
1685 function completed(insertion) {
1686 dragOverEvent('dragOverCompleted', {
1687 insertion: insertion
1688 });
1689 if (insertion) {
1690 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
1691 if (isOwner) {
1692 activeSortable._hideClone();
1693 } else {
1694 activeSortable._showClone(_this);
1695 }
1696 if (_this !== fromSortable) {
1697 // Set ghost class to new sortable's ghost class
1698 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
1699 toggleClass(dragEl, options.ghostClass, true);
1700 }
1701 if (putSortable !== _this && _this !== Sortable.active) {
1702 putSortable = _this;
1703 } else if (_this === Sortable.active && putSortable) {
1704 putSortable = null;
1705 }
1706
1707 // Animation
1708 if (fromSortable === _this) {
1709 _this._ignoreWhileAnimating = target;
1710 }
1711 _this.animateAll(function () {
1712 dragOverEvent('dragOverAnimationComplete');
1713 _this._ignoreWhileAnimating = null;
1714 });
1715 if (_this !== fromSortable) {
1716 fromSortable.animateAll();
1717 fromSortable._ignoreWhileAnimating = null;
1718 }
1719 }
1720
1721 // Null lastTarget if it is not inside a previously swapped element
1722 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
1723 lastTarget = null;
1724 }
1725
1726 // no bubbling and not fallback
1727 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
1728 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
1729
1730 // Do not detect for empty insert if already inserted
1731 !insertion && nearestEmptyInsertDetectEvent(evt);
1732 }
1733 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
1734 return completedFired = true;
1735 }
1736
1737 // Call when dragEl has been inserted
1738 function changed() {
1739 newIndex = index(dragEl);
1740 newDraggableIndex = index(dragEl, options.draggable);
1741 _dispatchEvent({
1742 sortable: _this,
1743 name: 'change',
1744 toEl: el,
1745 newIndex: newIndex,
1746 newDraggableIndex: newDraggableIndex,
1747 originalEvent: evt
1748 });
1749 }
1750 if (evt.preventDefault !== void 0) {
1751 evt.cancelable && evt.preventDefault();
1752 }
1753 target = closest(target, options.draggable, el, true);
1754 dragOverEvent('dragOver');
1755 if (Sortable.eventCanceled) return completedFired;
1756 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
1757 return completed(false);
1758 }
1759 ignoreNextClick = false;
1760 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
1761 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
1762 vertical = this._getDirection(evt, target) === 'vertical';
1763 dragRect = getRect(dragEl);
1764 dragOverEvent('dragOverValid');
1765 if (Sortable.eventCanceled) return completedFired;
1766 if (revert) {
1767 parentEl = rootEl; // actualization
1768 capture();
1769 this._hideClone();
1770 dragOverEvent('revert');
1771 if (!Sortable.eventCanceled) {
1772 if (nextEl) {
1773 rootEl.insertBefore(dragEl, nextEl);
1774 } else {
1775 rootEl.appendChild(dragEl);
1776 }
1777 }
1778 return completed(true);
1779 }
1780 var elLastChild = lastChild(el, options.draggable);
1781 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
1782 // Insert to end of list
1783
1784 // If already at end of list: Do not insert
1785 if (elLastChild === dragEl) {
1786 return completed(false);
1787 }
1788
1789 // if there is a last element, it is the target
1790 if (elLastChild && el === evt.target) {
1791 target = elLastChild;
1792 }
1793 if (target) {
1794 targetRect = getRect(target);
1795 }
1796 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
1797 capture();
1798 if (elLastChild && elLastChild.nextSibling) {
1799 // the last draggable element is not the last node
1800 el.insertBefore(dragEl, elLastChild.nextSibling);
1801 } else {
1802 el.appendChild(dragEl);
1803 }
1804 parentEl = el; // actualization
1805
1806 changed();
1807 return completed(true);
1808 }
1809 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
1810 // Insert to start of list
1811 var firstChild = getChild(el, 0, options, true);
1812 if (firstChild === dragEl) {
1813 return completed(false);
1814 }
1815 target = firstChild;
1816 targetRect = getRect(target);
1817 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
1818 capture();
1819 el.insertBefore(dragEl, firstChild);
1820 parentEl = el; // actualization
1821
1822 changed();
1823 return completed(true);
1824 }
1825 } else if (target.parentNode === el) {
1826 targetRect = getRect(target);
1827 var direction = 0,
1828 targetBeforeFirstSwap,
1829 differentLevel = dragEl.parentNode !== el,
1830 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
1831 side1 = vertical ? 'top' : 'left',
1832 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
1833 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
1834 if (lastTarget !== target) {
1835 targetBeforeFirstSwap = targetRect[side1];
1836 pastFirstInvertThresh = false;
1837 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
1838 }
1839 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
1840 var sibling;
1841 if (direction !== 0) {
1842 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
1843 var dragIndex = index(dragEl);
1844 do {
1845 dragIndex -= direction;
1846 sibling = parentEl.children[dragIndex];
1847 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
1848 }
1849 // If dragEl is already beside target: Do not insert
1850 if (direction === 0 || sibling === target) {
1851 return completed(false);
1852 }
1853 lastTarget = target;
1854 lastDirection = direction;
1855 var nextSibling = target.nextElementSibling,
1856 after = false;
1857 after = direction === 1;
1858 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
1859 if (moveVector !== false) {
1860 if (moveVector === 1 || moveVector === -1) {
1861 after = moveVector === 1;
1862 }
1863 _silent = true;
1864 setTimeout(_unsilent, 30);
1865 capture();
1866 if (after && !nextSibling) {
1867 el.appendChild(dragEl);
1868 } else {
1869 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
1870 }
1871
1872 // Undo chrome's scroll adjustment (has no effect on other browsers)
1873 if (scrolledPastTop) {
1874 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
1875 }
1876 parentEl = dragEl.parentNode; // actualization
1877
1878 // must be done before animation
1879 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
1880 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
1881 }
1882 changed();
1883 return completed(true);
1884 }
1885 }
1886 if (el.contains(dragEl)) {
1887 return completed(false);
1888 }
1889 }
1890 return false;
1891 },
1892 _ignoreWhileAnimating: null,
1893 _offMoveEvents: function _offMoveEvents() {
1894 off(document, 'mousemove', this._onTouchMove);
1895 off(document, 'touchmove', this._onTouchMove);
1896 off(document, 'pointermove', this._onTouchMove);
1897 off(document, 'dragover', nearestEmptyInsertDetectEvent);
1898 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
1899 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
1900 },
1901 _offUpEvents: function _offUpEvents() {
1902 var ownerDocument = this.el.ownerDocument;
1903 off(ownerDocument, 'mouseup', this._onDrop);
1904 off(ownerDocument, 'touchend', this._onDrop);
1905 off(ownerDocument, 'pointerup', this._onDrop);
1906 off(ownerDocument, 'pointercancel', this._onDrop);
1907 off(ownerDocument, 'touchcancel', this._onDrop);
1908 off(document, 'selectstart', this);
1909 },
1910 _onDrop: function _onDrop( /**Event*/evt) {
1911 var el = this.el,
1912 options = this.options;
1913
1914 // Get the index of the dragged element within its parent
1915 newIndex = index(dragEl);
1916 newDraggableIndex = index(dragEl, options.draggable);
1917 pluginEvent('drop', this, {
1918 evt: evt
1919 });
1920 parentEl = dragEl && dragEl.parentNode;
1921
1922 // Get again after plugin event
1923 newIndex = index(dragEl);
1924 newDraggableIndex = index(dragEl, options.draggable);
1925 if (Sortable.eventCanceled) {
1926 this._nulling();
1927 return;
1928 }
1929 awaitingDragStarted = false;
1930 isCircumstantialInvert = false;
1931 pastFirstInvertThresh = false;
1932 clearInterval(this._loopId);
1933 clearTimeout(this._dragStartTimer);
1934 _cancelNextTick(this.cloneId);
1935 _cancelNextTick(this._dragStartId);
1936
1937 // Unbind events
1938 if (this.nativeDraggable) {
1939 off(document, 'drop', this);
1940 off(el, 'dragstart', this._onDragStart);
1941 }
1942 this._offMoveEvents();
1943 this._offUpEvents();
1944 if (Safari) {
1945 css(document.body, 'user-select', '');
1946 }
1947 css(dragEl, 'transform', '');
1948 if (evt) {
1949 if (moved) {
1950 evt.cancelable && evt.preventDefault();
1951 !options.dropBubble && evt.stopPropagation();
1952 }
1953 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
1954 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
1955 // Remove clone(s)
1956 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
1957 }
1958 if (dragEl) {
1959 if (this.nativeDraggable) {
1960 off(dragEl, 'dragend', this);
1961 }
1962 _disableDraggable(dragEl);
1963 dragEl.style['will-change'] = '';
1964
1965 // Remove classes
1966 // ghostClass is added in dragStarted
1967 if (moved && !awaitingDragStarted) {
1968 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
1969 }
1970 toggleClass(dragEl, this.options.chosenClass, false);
1971
1972 // Drag stop event
1973 _dispatchEvent({
1974 sortable: this,
1975 name: 'unchoose',
1976 toEl: parentEl,
1977 newIndex: null,
1978 newDraggableIndex: null,
1979 originalEvent: evt
1980 });
1981 if (rootEl !== parentEl) {
1982 if (newIndex >= 0) {
1983 // Add event
1984 _dispatchEvent({
1985 rootEl: parentEl,
1986 name: 'add',
1987 toEl: parentEl,
1988 fromEl: rootEl,
1989 originalEvent: evt
1990 });
1991
1992 // Remove event
1993 _dispatchEvent({
1994 sortable: this,
1995 name: 'remove',
1996 toEl: parentEl,
1997 originalEvent: evt
1998 });
1999
2000 // drag from one list and drop into another
2001 _dispatchEvent({
2002 rootEl: parentEl,
2003 name: 'sort',
2004 toEl: parentEl,
2005 fromEl: rootEl,
2006 originalEvent: evt
2007 });
2008 _dispatchEvent({
2009 sortable: this,
2010 name: 'sort',
2011 toEl: parentEl,
2012 originalEvent: evt
2013 });
2014 }
2015 putSortable && putSortable.save();
2016 } else {
2017 if (newIndex !== oldIndex) {
2018 if (newIndex >= 0) {
2019 // drag & drop within the same list
2020 _dispatchEvent({
2021 sortable: this,
2022 name: 'update',
2023 toEl: parentEl,
2024 originalEvent: evt
2025 });
2026 _dispatchEvent({
2027 sortable: this,
2028 name: 'sort',
2029 toEl: parentEl,
2030 originalEvent: evt
2031 });
2032 }
2033 }
2034 }
2035 if (Sortable.active) {
2036 /* jshint eqnull:true */
2037 if (newIndex == null || newIndex === -1) {
2038 newIndex = oldIndex;
2039 newDraggableIndex = oldDraggableIndex;
2040 }
2041 _dispatchEvent({
2042 sortable: this,
2043 name: 'end',
2044 toEl: parentEl,
2045 originalEvent: evt
2046 });
2047
2048 // Save sorting
2049 this.save();
2050 }
2051 }
2052 }
2053 this._nulling();
2054 },
2055 _nulling: function _nulling() {
2056 pluginEvent('nulling', this);
2057 rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
2058 savedInputChecked.forEach(function (el) {
2059 el.checked = true;
2060 });
2061 savedInputChecked.length = lastDx = lastDy = 0;
2062 },
2063 handleEvent: function handleEvent( /**Event*/evt) {
2064 switch (evt.type) {
2065 case 'drop':
2066 case 'dragend':
2067 this._onDrop(evt);
2068 break;
2069 case 'dragenter':
2070 case 'dragover':
2071 if (dragEl) {
2072 this._onDragOver(evt);
2073 _globalDragOver(evt);
2074 }
2075 break;
2076 case 'selectstart':
2077 evt.preventDefault();
2078 break;
2079 }
2080 },
2081 /**
2082 * Serializes the item into an array of string.
2083 * @returns {String[]}
2084 */
2085 toArray: function toArray() {
2086 var order = [],
2087 el,
2088 children = this.el.children,
2089 i = 0,
2090 n = children.length,
2091 options = this.options;
2092 for (; i < n; i++) {
2093 el = children[i];
2094 if (closest(el, options.draggable, this.el, false)) {
2095 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
2096 }
2097 }
2098 return order;
2099 },
2100 /**
2101 * Sorts the elements according to the array.
2102 * @param {String[]} order order of the items
2103 */
2104 sort: function sort(order, useAnimation) {
2105 var items = {},
2106 rootEl = this.el;
2107 this.toArray().forEach(function (id, i) {
2108 var el = rootEl.children[i];
2109 if (closest(el, this.options.draggable, rootEl, false)) {
2110 items[id] = el;
2111 }
2112 }, this);
2113 useAnimation && this.captureAnimationState();
2114 order.forEach(function (id) {
2115 if (items[id]) {
2116 rootEl.removeChild(items[id]);
2117 rootEl.appendChild(items[id]);
2118 }
2119 });
2120 useAnimation && this.animateAll();
2121 },
2122 /**
2123 * Save the current sorting
2124 */
2125 save: function save() {
2126 var store = this.options.store;
2127 store && store.set && store.set(this);
2128 },
2129 /**
2130 * 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.
2131 * @param {HTMLElement} el
2132 * @param {String} [selector] default: `options.draggable`
2133 * @returns {HTMLElement|null}
2134 */
2135 closest: function closest$1(el, selector) {
2136 return closest(el, selector || this.options.draggable, this.el, false);
2137 },
2138 /**
2139 * Set/get option
2140 * @param {string} name
2141 * @param {*} [value]
2142 * @returns {*}
2143 */
2144 option: function option(name, value) {
2145 var options = this.options;
2146 if (value === void 0) {
2147 return options[name];
2148 } else {
2149 var modifiedValue = PluginManager.modifyOption(this, name, value);
2150 if (typeof modifiedValue !== 'undefined') {
2151 options[name] = modifiedValue;
2152 } else {
2153 options[name] = value;
2154 }
2155 if (name === 'group') {
2156 _prepareGroup(options);
2157 }
2158 }
2159 },
2160 /**
2161 * Destroy
2162 */
2163 destroy: function destroy() {
2164 pluginEvent('destroy', this);
2165 var el = this.el;
2166 el[expando] = null;
2167 off(el, 'mousedown', this._onTapStart);
2168 off(el, 'touchstart', this._onTapStart);
2169 off(el, 'pointerdown', this._onTapStart);
2170 if (this.nativeDraggable) {
2171 off(el, 'dragover', this);
2172 off(el, 'dragenter', this);
2173 }
2174 // Remove draggable attributes
2175 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
2176 el.removeAttribute('draggable');
2177 });
2178 this._onDrop();
2179 this._disableDelayedDragEvents();
2180 sortables.splice(sortables.indexOf(this.el), 1);
2181 this.el = el = null;
2182 },
2183 _hideClone: function _hideClone() {
2184 if (!cloneHidden) {
2185 pluginEvent('hideClone', this);
2186 if (Sortable.eventCanceled) return;
2187 css(cloneEl, 'display', 'none');
2188 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
2189 cloneEl.parentNode.removeChild(cloneEl);
2190 }
2191 cloneHidden = true;
2192 }
2193 },
2194 _showClone: function _showClone(putSortable) {
2195 if (putSortable.lastPutMode !== 'clone') {
2196 this._hideClone();
2197 return;
2198 }
2199 if (cloneHidden) {
2200 pluginEvent('showClone', this);
2201 if (Sortable.eventCanceled) return;
2202
2203 // show clone at dragEl or original position
2204 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
2205 rootEl.insertBefore(cloneEl, dragEl);
2206 } else if (nextEl) {
2207 rootEl.insertBefore(cloneEl, nextEl);
2208 } else {
2209 rootEl.appendChild(cloneEl);
2210 }
2211 if (this.options.group.revertClone) {
2212 this.animate(dragEl, cloneEl);
2213 }
2214 css(cloneEl, 'display', '');
2215 cloneHidden = false;
2216 }
2217 }
2218 };
2219 function _globalDragOver( /**Event*/evt) {
2220 if (evt.dataTransfer) {
2221 evt.dataTransfer.dropEffect = 'move';
2222 }
2223 evt.cancelable && evt.preventDefault();
2224 }
2225 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
2226 var evt,
2227 sortable = fromEl[expando],
2228 onMoveFn = sortable.options.onMove,
2229 retVal;
2230 // Support for new CustomEvent feature
2231 if (window.CustomEvent && !IE11OrLess && !Edge) {
2232 evt = new CustomEvent('move', {
2233 bubbles: true,
2234 cancelable: true
2235 });
2236 } else {
2237 evt = document.createEvent('Event');
2238 evt.initEvent('move', true, true);
2239 }
2240 evt.to = toEl;
2241 evt.from = fromEl;
2242 evt.dragged = dragEl;
2243 evt.draggedRect = dragRect;
2244 evt.related = targetEl || toEl;
2245 evt.relatedRect = targetRect || getRect(toEl);
2246 evt.willInsertAfter = willInsertAfter;
2247 evt.originalEvent = originalEvent;
2248 fromEl.dispatchEvent(evt);
2249 if (onMoveFn) {
2250 retVal = onMoveFn.call(sortable, evt, originalEvent);
2251 }
2252 return retVal;
2253 }
2254 function _disableDraggable(el) {
2255 el.draggable = false;
2256 }
2257 function _unsilent() {
2258 _silent = false;
2259 }
2260 function _ghostIsFirst(evt, vertical, sortable) {
2261 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
2262 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
2263 var spacer = 10;
2264 return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left;
2265 }
2266 function _ghostIsLast(evt, vertical, sortable) {
2267 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
2268 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
2269 var spacer = 10;
2270 return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top;
2271 }
2272 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
2273 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
2274 targetLength = vertical ? targetRect.height : targetRect.width,
2275 targetS1 = vertical ? targetRect.top : targetRect.left,
2276 targetS2 = vertical ? targetRect.bottom : targetRect.right,
2277 invert = false;
2278 if (!invertSwap) {
2279 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
2280 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
2281 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
2282 // check if past first invert threshold on side opposite of lastDirection
2283 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
2284 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
2285 pastFirstInvertThresh = true;
2286 }
2287 if (!pastFirstInvertThresh) {
2288 // dragEl shadow (target move distance shadow)
2289 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
2290 : mouseOnAxis > targetS2 - targetMoveDistance) {
2291 return -lastDirection;
2292 }
2293 } else {
2294 invert = true;
2295 }
2296 } else {
2297 // Regular
2298 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
2299 return _getInsertDirection(target);
2300 }
2301 }
2302 }
2303 invert = invert || invertSwap;
2304 if (invert) {
2305 // Invert of regular
2306 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
2307 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
2308 }
2309 }
2310 return 0;
2311 }
2312
2313 /**
2314 * Gets the direction dragEl must be swapped relative to target in order to make it
2315 * seem that dragEl has been "inserted" into that element's position
2316 * @param {HTMLElement} target The target whose position dragEl is being inserted at
2317 * @return {Number} Direction dragEl must be swapped
2318 */
2319 function _getInsertDirection(target) {
2320 if (index(dragEl) < index(target)) {
2321 return 1;
2322 } else {
2323 return -1;
2324 }
2325 }
2326
2327 /**
2328 * Generate id
2329 * @param {HTMLElement} el
2330 * @returns {String}
2331 * @private
2332 */
2333 function _generateId(el) {
2334 var str = el.tagName + el.className + el.src + el.href + el.textContent,
2335 i = str.length,
2336 sum = 0;
2337 while (i--) {
2338 sum += str.charCodeAt(i);
2339 }
2340 return sum.toString(36);
2341 }
2342 function _saveInputCheckedState(root) {
2343 savedInputChecked.length = 0;
2344 var inputs = root.getElementsByTagName('input');
2345 var idx = inputs.length;
2346 while (idx--) {
2347 var el = inputs[idx];
2348 el.checked && savedInputChecked.push(el);
2349 }
2350 }
2351 function _nextTick(fn) {
2352 return setTimeout(fn, 0);
2353 }
2354 function _cancelNextTick(id) {
2355 return clearTimeout(id);
2356 }
2357
2358 // Fixed #973:
2359 if (documentExists) {
2360 on(document, 'touchmove', function (evt) {
2361 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
2362 evt.preventDefault();
2363 }
2364 });
2365 }
2366
2367 // Export utils
2368 Sortable.utils = {
2369 on: on,
2370 off: off,
2371 css: css,
2372 find: find,
2373 is: function is(el, selector) {
2374 return !!closest(el, selector, el, false);
2375 },
2376 extend: extend,
2377 throttle: throttle,
2378 closest: closest,
2379 toggleClass: toggleClass,
2380 clone: clone,
2381 index: index,
2382 nextTick: _nextTick,
2383 cancelNextTick: _cancelNextTick,
2384 detectDirection: _detectDirection,
2385 getChild: getChild,
2386 expando: expando
2387 };
2388
2389 /**
2390 * Get the Sortable instance of an element
2391 * @param {HTMLElement} element The element
2392 * @return {Sortable|undefined} The instance of Sortable
2393 */
2394 Sortable.get = function (element) {
2395 return element[expando];
2396 };
2397
2398 /**
2399 * Mount a plugin to Sortable
2400 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
2401 */
2402 Sortable.mount = function () {
2403 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
2404 plugins[_key] = arguments[_key];
2405 }
2406 if (plugins[0].constructor === Array) plugins = plugins[0];
2407 plugins.forEach(function (plugin) {
2408 if (!plugin.prototype || !plugin.prototype.constructor) {
2409 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
2410 }
2411 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
2412 PluginManager.mount(plugin);
2413 });
2414 };
2415
2416 /**
2417 * Create sortable instance
2418 * @param {HTMLElement} el
2419 * @param {Object} [options]
2420 */
2421 Sortable.create = function (el, options) {
2422 return new Sortable(el, options);
2423 };
2424
2425 // Export
2426 Sortable.version = version;
2427
2428 var autoScrolls = [],
2429 scrollEl,
2430 scrollRootEl,
2431 scrolling = false,
2432 lastAutoScrollX,
2433 lastAutoScrollY,
2434 touchEvt$1,
2435 pointerElemChangedInterval;
2436 function AutoScrollPlugin() {
2437 function AutoScroll() {
2438 this.defaults = {
2439 scroll: true,
2440 forceAutoScrollFallback: false,
2441 scrollSensitivity: 30,
2442 scrollSpeed: 10,
2443 bubbleScroll: true
2444 };
2445
2446 // Bind all private methods
2447 for (var fn in this) {
2448 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
2449 this[fn] = this[fn].bind(this);
2450 }
2451 }
2452 }
2453 AutoScroll.prototype = {
2454 dragStarted: function dragStarted(_ref) {
2455 var originalEvent = _ref.originalEvent;
2456 if (this.sortable.nativeDraggable) {
2457 on(document, 'dragover', this._handleAutoScroll);
2458 } else {
2459 if (this.options.supportPointer) {
2460 on(document, 'pointermove', this._handleFallbackAutoScroll);
2461 } else if (originalEvent.touches) {
2462 on(document, 'touchmove', this._handleFallbackAutoScroll);
2463 } else {
2464 on(document, 'mousemove', this._handleFallbackAutoScroll);
2465 }
2466 }
2467 },
2468 dragOverCompleted: function dragOverCompleted(_ref2) {
2469 var originalEvent = _ref2.originalEvent;
2470 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
2471 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
2472 this._handleAutoScroll(originalEvent);
2473 }
2474 },
2475 drop: function drop() {
2476 if (this.sortable.nativeDraggable) {
2477 off(document, 'dragover', this._handleAutoScroll);
2478 } else {
2479 off(document, 'pointermove', this._handleFallbackAutoScroll);
2480 off(document, 'touchmove', this._handleFallbackAutoScroll);
2481 off(document, 'mousemove', this._handleFallbackAutoScroll);
2482 }
2483 clearPointerElemChangedInterval();
2484 clearAutoScrolls();
2485 cancelThrottle();
2486 },
2487 nulling: function nulling() {
2488 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
2489 autoScrolls.length = 0;
2490 },
2491 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
2492 this._handleAutoScroll(evt, true);
2493 },
2494 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
2495 var _this = this;
2496 var x = (evt.touches ? evt.touches[0] : evt).clientX,
2497 y = (evt.touches ? evt.touches[0] : evt).clientY,
2498 elem = document.elementFromPoint(x, y);
2499 touchEvt$1 = evt;
2500
2501 // IE does not seem to have native autoscroll,
2502 // Edge's autoscroll seems too conditional,
2503 // MACOS Safari does not have autoscroll,
2504 // Firefox and Chrome are good
2505 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
2506 autoScroll(evt, this.options, elem, fallback);
2507
2508 // Listener for pointer element change
2509 var ogElemScroller = getParentAutoScrollElement(elem, true);
2510 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
2511 pointerElemChangedInterval && clearPointerElemChangedInterval();
2512 // Detect for pointer elem change, emulating native DnD behaviour
2513 pointerElemChangedInterval = setInterval(function () {
2514 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
2515 if (newElem !== ogElemScroller) {
2516 ogElemScroller = newElem;
2517 clearAutoScrolls();
2518 }
2519 autoScroll(evt, _this.options, newElem, fallback);
2520 }, 10);
2521 lastAutoScrollX = x;
2522 lastAutoScrollY = y;
2523 }
2524 } else {
2525 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
2526 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
2527 clearAutoScrolls();
2528 return;
2529 }
2530 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
2531 }
2532 }
2533 };
2534 return _extends(AutoScroll, {
2535 pluginName: 'scroll',
2536 initializeByDefault: true
2537 });
2538 }
2539 function clearAutoScrolls() {
2540 autoScrolls.forEach(function (autoScroll) {
2541 clearInterval(autoScroll.pid);
2542 });
2543 autoScrolls = [];
2544 }
2545 function clearPointerElemChangedInterval() {
2546 clearInterval(pointerElemChangedInterval);
2547 }
2548 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
2549 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
2550 if (!options.scroll) return;
2551 var x = (evt.touches ? evt.touches[0] : evt).clientX,
2552 y = (evt.touches ? evt.touches[0] : evt).clientY,
2553 sens = options.scrollSensitivity,
2554 speed = options.scrollSpeed,
2555 winScroller = getWindowScrollingElement();
2556 var scrollThisInstance = false,
2557 scrollCustomFn;
2558
2559 // New scroll root, set scrollEl
2560 if (scrollRootEl !== rootEl) {
2561 scrollRootEl = rootEl;
2562 clearAutoScrolls();
2563 scrollEl = options.scroll;
2564 scrollCustomFn = options.scrollFn;
2565 if (scrollEl === true) {
2566 scrollEl = getParentAutoScrollElement(rootEl, true);
2567 }
2568 }
2569 var layersOut = 0;
2570 var currentParent = scrollEl;
2571 do {
2572 var el = currentParent,
2573 rect = getRect(el),
2574 top = rect.top,
2575 bottom = rect.bottom,
2576 left = rect.left,
2577 right = rect.right,
2578 width = rect.width,
2579 height = rect.height,
2580 canScrollX = void 0,
2581 canScrollY = void 0,
2582 scrollWidth = el.scrollWidth,
2583 scrollHeight = el.scrollHeight,
2584 elCSS = css(el),
2585 scrollPosX = el.scrollLeft,
2586 scrollPosY = el.scrollTop;
2587 if (el === winScroller) {
2588 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
2589 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
2590 } else {
2591 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
2592 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
2593 }
2594 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
2595 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
2596 if (!autoScrolls[layersOut]) {
2597 for (var i = 0; i <= layersOut; i++) {
2598 if (!autoScrolls[i]) {
2599 autoScrolls[i] = {};
2600 }
2601 }
2602 }
2603 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
2604 autoScrolls[layersOut].el = el;
2605 autoScrolls[layersOut].vx = vx;
2606 autoScrolls[layersOut].vy = vy;
2607 clearInterval(autoScrolls[layersOut].pid);
2608 if (vx != 0 || vy != 0) {
2609 scrollThisInstance = true;
2610 /* jshint loopfunc:true */
2611 autoScrolls[layersOut].pid = setInterval(function () {
2612 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
2613 if (isFallback && this.layer === 0) {
2614 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
2615 }
2616 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
2617 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
2618 if (typeof scrollCustomFn === 'function') {
2619 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
2620 return;
2621 }
2622 }
2623 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
2624 }.bind({
2625 layer: layersOut
2626 }), 24);
2627 }
2628 }
2629 layersOut++;
2630 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
2631 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
2632 }, 30);
2633
2634 var drop = function drop(_ref) {
2635 var originalEvent = _ref.originalEvent,
2636 putSortable = _ref.putSortable,
2637 dragEl = _ref.dragEl,
2638 activeSortable = _ref.activeSortable,
2639 dispatchSortableEvent = _ref.dispatchSortableEvent,
2640 hideGhostForTarget = _ref.hideGhostForTarget,
2641 unhideGhostForTarget = _ref.unhideGhostForTarget;
2642 if (!originalEvent) return;
2643 var toSortable = putSortable || activeSortable;
2644 hideGhostForTarget();
2645 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
2646 var target = document.elementFromPoint(touch.clientX, touch.clientY);
2647 unhideGhostForTarget();
2648 if (toSortable && !toSortable.el.contains(target)) {
2649 dispatchSortableEvent('spill');
2650 this.onSpill({
2651 dragEl: dragEl,
2652 putSortable: putSortable
2653 });
2654 }
2655 };
2656 function Revert() {}
2657 Revert.prototype = {
2658 startIndex: null,
2659 dragStart: function dragStart(_ref2) {
2660 var oldDraggableIndex = _ref2.oldDraggableIndex;
2661 this.startIndex = oldDraggableIndex;
2662 },
2663 onSpill: function onSpill(_ref3) {
2664 var dragEl = _ref3.dragEl,
2665 putSortable = _ref3.putSortable;
2666 this.sortable.captureAnimationState();
2667 if (putSortable) {
2668 putSortable.captureAnimationState();
2669 }
2670 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
2671 if (nextSibling) {
2672 this.sortable.el.insertBefore(dragEl, nextSibling);
2673 } else {
2674 this.sortable.el.appendChild(dragEl);
2675 }
2676 this.sortable.animateAll();
2677 if (putSortable) {
2678 putSortable.animateAll();
2679 }
2680 },
2681 drop: drop
2682 };
2683 _extends(Revert, {
2684 pluginName: 'revertOnSpill'
2685 });
2686 function Remove() {}
2687 Remove.prototype = {
2688 onSpill: function onSpill(_ref4) {
2689 var dragEl = _ref4.dragEl,
2690 putSortable = _ref4.putSortable;
2691 var parentSortable = putSortable || this.sortable;
2692 parentSortable.captureAnimationState();
2693 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
2694 parentSortable.animateAll();
2695 },
2696 drop: drop
2697 };
2698 _extends(Remove, {
2699 pluginName: 'removeOnSpill'
2700 });
2701
2702 var lastSwapEl;
2703 function SwapPlugin() {
2704 function Swap() {
2705 this.defaults = {
2706 swapClass: 'sortable-swap-highlight'
2707 };
2708 }
2709 Swap.prototype = {
2710 dragStart: function dragStart(_ref) {
2711 var dragEl = _ref.dragEl;
2712 lastSwapEl = dragEl;
2713 },
2714 dragOverValid: function dragOverValid(_ref2) {
2715 var completed = _ref2.completed,
2716 target = _ref2.target,
2717 onMove = _ref2.onMove,
2718 activeSortable = _ref2.activeSortable,
2719 changed = _ref2.changed,
2720 cancel = _ref2.cancel;
2721 if (!activeSortable.options.swap) return;
2722 var el = this.sortable.el,
2723 options = this.options;
2724 if (target && target !== el) {
2725 var prevSwapEl = lastSwapEl;
2726 if (onMove(target) !== false) {
2727 toggleClass(target, options.swapClass, true);
2728 lastSwapEl = target;
2729 } else {
2730 lastSwapEl = null;
2731 }
2732 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
2733 toggleClass(prevSwapEl, options.swapClass, false);
2734 }
2735 }
2736 changed();
2737 completed(true);
2738 cancel();
2739 },
2740 drop: function drop(_ref3) {
2741 var activeSortable = _ref3.activeSortable,
2742 putSortable = _ref3.putSortable,
2743 dragEl = _ref3.dragEl;
2744 var toSortable = putSortable || this.sortable;
2745 var options = this.options;
2746 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
2747 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
2748 if (dragEl !== lastSwapEl) {
2749 toSortable.captureAnimationState();
2750 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
2751 swapNodes(dragEl, lastSwapEl);
2752 toSortable.animateAll();
2753 if (toSortable !== activeSortable) activeSortable.animateAll();
2754 }
2755 }
2756 },
2757 nulling: function nulling() {
2758 lastSwapEl = null;
2759 }
2760 };
2761 return _extends(Swap, {
2762 pluginName: 'swap',
2763 eventProperties: function eventProperties() {
2764 return {
2765 swapItem: lastSwapEl
2766 };
2767 }
2768 });
2769 }
2770 function swapNodes(n1, n2) {
2771 var p1 = n1.parentNode,
2772 p2 = n2.parentNode,
2773 i1,
2774 i2;
2775 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
2776 i1 = index(n1);
2777 i2 = index(n2);
2778 if (p1.isEqualNode(p2) && i1 < i2) {
2779 i2++;
2780 }
2781 p1.insertBefore(n2, p1.children[i1]);
2782 p2.insertBefore(n1, p2.children[i2]);
2783 }
2784
2785 var multiDragElements = [],
2786 multiDragClones = [],
2787 lastMultiDragSelect,
2788 // for selection with modifier key down (SHIFT)
2789 multiDragSortable,
2790 initialFolding = false,
2791 // Initial multi-drag fold when drag started
2792 folding = false,
2793 // Folding any other time
2794 dragStarted = false,
2795 dragEl$1,
2796 clonesFromRect,
2797 clonesHidden;
2798 function MultiDragPlugin() {
2799 function MultiDrag(sortable) {
2800 // Bind all private methods
2801 for (var fn in this) {
2802 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
2803 this[fn] = this[fn].bind(this);
2804 }
2805 }
2806 if (!sortable.options.avoidImplicitDeselect) {
2807 if (sortable.options.supportPointer) {
2808 on(document, 'pointerup', this._deselectMultiDrag);
2809 } else {
2810 on(document, 'mouseup', this._deselectMultiDrag);
2811 on(document, 'touchend', this._deselectMultiDrag);
2812 }
2813 }
2814 on(document, 'keydown', this._checkKeyDown);
2815 on(document, 'keyup', this._checkKeyUp);
2816 this.defaults = {
2817 selectedClass: 'sortable-selected',
2818 multiDragKey: null,
2819 avoidImplicitDeselect: false,
2820 setData: function setData(dataTransfer, dragEl) {
2821 var data = '';
2822 if (multiDragElements.length && multiDragSortable === sortable) {
2823 multiDragElements.forEach(function (multiDragElement, i) {
2824 data += (!i ? '' : ', ') + multiDragElement.textContent;
2825 });
2826 } else {
2827 data = dragEl.textContent;
2828 }
2829 dataTransfer.setData('Text', data);
2830 }
2831 };
2832 }
2833 MultiDrag.prototype = {
2834 multiDragKeyDown: false,
2835 isMultiDrag: false,
2836 delayStartGlobal: function delayStartGlobal(_ref) {
2837 var dragged = _ref.dragEl;
2838 dragEl$1 = dragged;
2839 },
2840 delayEnded: function delayEnded() {
2841 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
2842 },
2843 setupClone: function setupClone(_ref2) {
2844 var sortable = _ref2.sortable,
2845 cancel = _ref2.cancel;
2846 if (!this.isMultiDrag) return;
2847 for (var i = 0; i < multiDragElements.length; i++) {
2848 multiDragClones.push(clone(multiDragElements[i]));
2849 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
2850 multiDragClones[i].draggable = false;
2851 multiDragClones[i].style['will-change'] = '';
2852 toggleClass(multiDragClones[i], this.options.selectedClass, false);
2853 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
2854 }
2855 sortable._hideClone();
2856 cancel();
2857 },
2858 clone: function clone(_ref3) {
2859 var sortable = _ref3.sortable,
2860 rootEl = _ref3.rootEl,
2861 dispatchSortableEvent = _ref3.dispatchSortableEvent,
2862 cancel = _ref3.cancel;
2863 if (!this.isMultiDrag) return;
2864 if (!this.options.removeCloneOnHide) {
2865 if (multiDragElements.length && multiDragSortable === sortable) {
2866 insertMultiDragClones(true, rootEl);
2867 dispatchSortableEvent('clone');
2868 cancel();
2869 }
2870 }
2871 },
2872 showClone: function showClone(_ref4) {
2873 var cloneNowShown = _ref4.cloneNowShown,
2874 rootEl = _ref4.rootEl,
2875 cancel = _ref4.cancel;
2876 if (!this.isMultiDrag) return;
2877 insertMultiDragClones(false, rootEl);
2878 multiDragClones.forEach(function (clone) {
2879 css(clone, 'display', '');
2880 });
2881 cloneNowShown();
2882 clonesHidden = false;
2883 cancel();
2884 },
2885 hideClone: function hideClone(_ref5) {
2886 var _this = this;
2887 var sortable = _ref5.sortable,
2888 cloneNowHidden = _ref5.cloneNowHidden,
2889 cancel = _ref5.cancel;
2890 if (!this.isMultiDrag) return;
2891 multiDragClones.forEach(function (clone) {
2892 css(clone, 'display', 'none');
2893 if (_this.options.removeCloneOnHide && clone.parentNode) {
2894 clone.parentNode.removeChild(clone);
2895 }
2896 });
2897 cloneNowHidden();
2898 clonesHidden = true;
2899 cancel();
2900 },
2901 dragStartGlobal: function dragStartGlobal(_ref6) {
2902 var sortable = _ref6.sortable;
2903 if (!this.isMultiDrag && multiDragSortable) {
2904 multiDragSortable.multiDrag._deselectMultiDrag();
2905 }
2906 multiDragElements.forEach(function (multiDragElement) {
2907 multiDragElement.sortableIndex = index(multiDragElement);
2908 });
2909
2910 // Sort multi-drag elements
2911 multiDragElements = multiDragElements.sort(function (a, b) {
2912 return a.sortableIndex - b.sortableIndex;
2913 });
2914 dragStarted = true;
2915 },
2916 dragStarted: function dragStarted(_ref7) {
2917 var _this2 = this;
2918 var sortable = _ref7.sortable;
2919 if (!this.isMultiDrag) return;
2920 if (this.options.sort) {
2921 // Capture rects,
2922 // hide multi drag elements (by positioning them absolute),
2923 // set multi drag elements rects to dragRect,
2924 // show multi drag elements,
2925 // animate to rects,
2926 // unset rects & remove from DOM
2927
2928 sortable.captureAnimationState();
2929 if (this.options.animation) {
2930 multiDragElements.forEach(function (multiDragElement) {
2931 if (multiDragElement === dragEl$1) return;
2932 css(multiDragElement, 'position', 'absolute');
2933 });
2934 var dragRect = getRect(dragEl$1, false, true, true);
2935 multiDragElements.forEach(function (multiDragElement) {
2936 if (multiDragElement === dragEl$1) return;
2937 setRect(multiDragElement, dragRect);
2938 });
2939 folding = true;
2940 initialFolding = true;
2941 }
2942 }
2943 sortable.animateAll(function () {
2944 folding = false;
2945 initialFolding = false;
2946 if (_this2.options.animation) {
2947 multiDragElements.forEach(function (multiDragElement) {
2948 unsetRect(multiDragElement);
2949 });
2950 }
2951
2952 // Remove all auxiliary multidrag items from el, if sorting enabled
2953 if (_this2.options.sort) {
2954 removeMultiDragElements();
2955 }
2956 });
2957 },
2958 dragOver: function dragOver(_ref8) {
2959 var target = _ref8.target,
2960 completed = _ref8.completed,
2961 cancel = _ref8.cancel;
2962 if (folding && ~multiDragElements.indexOf(target)) {
2963 completed(false);
2964 cancel();
2965 }
2966 },
2967 revert: function revert(_ref9) {
2968 var fromSortable = _ref9.fromSortable,
2969 rootEl = _ref9.rootEl,
2970 sortable = _ref9.sortable,
2971 dragRect = _ref9.dragRect;
2972 if (multiDragElements.length > 1) {
2973 // Setup unfold animation
2974 multiDragElements.forEach(function (multiDragElement) {
2975 sortable.addAnimationState({
2976 target: multiDragElement,
2977 rect: folding ? getRect(multiDragElement) : dragRect
2978 });
2979 unsetRect(multiDragElement);
2980 multiDragElement.fromRect = dragRect;
2981 fromSortable.removeAnimationState(multiDragElement);
2982 });
2983 folding = false;
2984 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
2985 }
2986 },
2987 dragOverCompleted: function dragOverCompleted(_ref10) {
2988 var sortable = _ref10.sortable,
2989 isOwner = _ref10.isOwner,
2990 insertion = _ref10.insertion,
2991 activeSortable = _ref10.activeSortable,
2992 parentEl = _ref10.parentEl,
2993 putSortable = _ref10.putSortable;
2994 var options = this.options;
2995 if (insertion) {
2996 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
2997 if (isOwner) {
2998 activeSortable._hideClone();
2999 }
3000 initialFolding = false;
3001 // If leaving sort:false root, or already folding - Fold to new location
3002 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
3003 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
3004 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
3005 multiDragElements.forEach(function (multiDragElement) {
3006 if (multiDragElement === dragEl$1) return;
3007 setRect(multiDragElement, dragRectAbsolute);
3008
3009 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
3010 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
3011 parentEl.appendChild(multiDragElement);
3012 });
3013 folding = true;
3014 }
3015
3016 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
3017 if (!isOwner) {
3018 // Only remove if not folding (folding will remove them anyways)
3019 if (!folding) {
3020 removeMultiDragElements();
3021 }
3022 if (multiDragElements.length > 1) {
3023 var clonesHiddenBefore = clonesHidden;
3024 activeSortable._showClone(sortable);
3025
3026 // Unfold animation for clones if showing from hidden
3027 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
3028 multiDragClones.forEach(function (clone) {
3029 activeSortable.addAnimationState({
3030 target: clone,
3031 rect: clonesFromRect
3032 });
3033 clone.fromRect = clonesFromRect;
3034 clone.thisAnimationDuration = null;
3035 });
3036 }
3037 } else {
3038 activeSortable._showClone(sortable);
3039 }
3040 }
3041 }
3042 },
3043 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
3044 var dragRect = _ref11.dragRect,
3045 isOwner = _ref11.isOwner,
3046 activeSortable = _ref11.activeSortable;
3047 multiDragElements.forEach(function (multiDragElement) {
3048 multiDragElement.thisAnimationDuration = null;
3049 });
3050 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
3051 clonesFromRect = _extends({}, dragRect);
3052 var dragMatrix = matrix(dragEl$1, true);
3053 clonesFromRect.top -= dragMatrix.f;
3054 clonesFromRect.left -= dragMatrix.e;
3055 }
3056 },
3057 dragOverAnimationComplete: function dragOverAnimationComplete() {
3058 if (folding) {
3059 folding = false;
3060 removeMultiDragElements();
3061 }
3062 },
3063 drop: function drop(_ref12) {
3064 var evt = _ref12.originalEvent,
3065 rootEl = _ref12.rootEl,
3066 parentEl = _ref12.parentEl,
3067 sortable = _ref12.sortable,
3068 dispatchSortableEvent = _ref12.dispatchSortableEvent,
3069 oldIndex = _ref12.oldIndex,
3070 putSortable = _ref12.putSortable;
3071 var toSortable = putSortable || this.sortable;
3072 if (!evt) return;
3073 var options = this.options,
3074 children = parentEl.children;
3075
3076 // Multi-drag selection
3077 if (!dragStarted) {
3078 if (options.multiDragKey && !this.multiDragKeyDown) {
3079 this._deselectMultiDrag();
3080 }
3081 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
3082 if (!~multiDragElements.indexOf(dragEl$1)) {
3083 multiDragElements.push(dragEl$1);
3084 dispatchEvent({
3085 sortable: sortable,
3086 rootEl: rootEl,
3087 name: 'select',
3088 targetEl: dragEl$1,
3089 originalEvent: evt
3090 });
3091
3092 // Modifier activated, select from last to dragEl
3093 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
3094 var lastIndex = index(lastMultiDragSelect),
3095 currentIndex = index(dragEl$1);
3096 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
3097 (function () {
3098 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
3099 // (but previous selection existed)
3100 var n, i;
3101 if (currentIndex > lastIndex) {
3102 i = lastIndex;
3103 n = currentIndex;
3104 } else {
3105 i = currentIndex;
3106 n = lastIndex + 1;
3107 }
3108 var filter = options.filter;
3109 for (; i < n; i++) {
3110 if (~multiDragElements.indexOf(children[i])) continue;
3111 // Check if element is draggable
3112 if (!closest(children[i], options.draggable, parentEl, false)) continue;
3113 // Check if element is filtered
3114 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
3115 return closest(children[i], criteria.trim(), parentEl, false);
3116 }));
3117 if (filtered) continue;
3118 toggleClass(children[i], options.selectedClass, true);
3119 multiDragElements.push(children[i]);
3120 dispatchEvent({
3121 sortable: sortable,
3122 rootEl: rootEl,
3123 name: 'select',
3124 targetEl: children[i],
3125 originalEvent: evt
3126 });
3127 }
3128 })();
3129 }
3130 } else {
3131 lastMultiDragSelect = dragEl$1;
3132 }
3133 multiDragSortable = toSortable;
3134 } else {
3135 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
3136 lastMultiDragSelect = null;
3137 dispatchEvent({
3138 sortable: sortable,
3139 rootEl: rootEl,
3140 name: 'deselect',
3141 targetEl: dragEl$1,
3142 originalEvent: evt
3143 });
3144 }
3145 }
3146
3147 // Multi-drag drop
3148 if (dragStarted && this.isMultiDrag) {
3149 folding = false;
3150 // Do not "unfold" after around dragEl if reverted
3151 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
3152 var dragRect = getRect(dragEl$1),
3153 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
3154 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
3155 toSortable.captureAnimationState();
3156 if (!initialFolding) {
3157 if (options.animation) {
3158 dragEl$1.fromRect = dragRect;
3159 multiDragElements.forEach(function (multiDragElement) {
3160 multiDragElement.thisAnimationDuration = null;
3161 if (multiDragElement !== dragEl$1) {
3162 var rect = folding ? getRect(multiDragElement) : dragRect;
3163 multiDragElement.fromRect = rect;
3164
3165 // Prepare unfold animation
3166 toSortable.addAnimationState({
3167 target: multiDragElement,
3168 rect: rect
3169 });
3170 }
3171 });
3172 }
3173
3174 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
3175 // properly they must all be removed
3176 removeMultiDragElements();
3177 multiDragElements.forEach(function (multiDragElement) {
3178 if (children[multiDragIndex]) {
3179 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
3180 } else {
3181 parentEl.appendChild(multiDragElement);
3182 }
3183 multiDragIndex++;
3184 });
3185
3186 // If initial folding is done, the elements may have changed position because they are now
3187 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
3188 // must be fired here as Sortable will not.
3189 if (oldIndex === index(dragEl$1)) {
3190 var update = false;
3191 multiDragElements.forEach(function (multiDragElement) {
3192 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
3193 update = true;
3194 return;
3195 }
3196 });
3197 if (update) {
3198 dispatchSortableEvent('update');
3199 dispatchSortableEvent('sort');
3200 }
3201 }
3202 }
3203
3204 // Must be done after capturing individual rects (scroll bar)
3205 multiDragElements.forEach(function (multiDragElement) {
3206 unsetRect(multiDragElement);
3207 });
3208 toSortable.animateAll();
3209 }
3210 multiDragSortable = toSortable;
3211 }
3212
3213 // Remove clones if necessary
3214 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
3215 multiDragClones.forEach(function (clone) {
3216 clone.parentNode && clone.parentNode.removeChild(clone);
3217 });
3218 }
3219 },
3220 nullingGlobal: function nullingGlobal() {
3221 this.isMultiDrag = dragStarted = false;
3222 multiDragClones.length = 0;
3223 },
3224 destroyGlobal: function destroyGlobal() {
3225 this._deselectMultiDrag();
3226 off(document, 'pointerup', this._deselectMultiDrag);
3227 off(document, 'mouseup', this._deselectMultiDrag);
3228 off(document, 'touchend', this._deselectMultiDrag);
3229 off(document, 'keydown', this._checkKeyDown);
3230 off(document, 'keyup', this._checkKeyUp);
3231 },
3232 _deselectMultiDrag: function _deselectMultiDrag(evt) {
3233 if (typeof dragStarted !== "undefined" && dragStarted) return;
3234
3235 // Only deselect if selection is in this sortable
3236 if (multiDragSortable !== this.sortable) return;
3237
3238 // Only deselect if target is not item in this sortable
3239 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
3240
3241 // Only deselect if left click
3242 if (evt && evt.button !== 0) return;
3243 while (multiDragElements.length) {
3244 var el = multiDragElements[0];
3245 toggleClass(el, this.options.selectedClass, false);
3246 multiDragElements.shift();
3247 dispatchEvent({
3248 sortable: this.sortable,
3249 rootEl: this.sortable.el,
3250 name: 'deselect',
3251 targetEl: el,
3252 originalEvent: evt
3253 });
3254 }
3255 },
3256 _checkKeyDown: function _checkKeyDown(evt) {
3257 if (evt.key === this.options.multiDragKey) {
3258 this.multiDragKeyDown = true;
3259 }
3260 },
3261 _checkKeyUp: function _checkKeyUp(evt) {
3262 if (evt.key === this.options.multiDragKey) {
3263 this.multiDragKeyDown = false;
3264 }
3265 }
3266 };
3267 return _extends(MultiDrag, {
3268 // Static methods & properties
3269 pluginName: 'multiDrag',
3270 utils: {
3271 /**
3272 * Selects the provided multi-drag item
3273 * @param {HTMLElement} el The element to be selected
3274 */
3275 select: function select(el) {
3276 var sortable = el.parentNode[expando];
3277 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
3278 if (multiDragSortable && multiDragSortable !== sortable) {
3279 multiDragSortable.multiDrag._deselectMultiDrag();
3280 multiDragSortable = sortable;
3281 }
3282 toggleClass(el, sortable.options.selectedClass, true);
3283 multiDragElements.push(el);
3284 },
3285 /**
3286 * Deselects the provided multi-drag item
3287 * @param {HTMLElement} el The element to be deselected
3288 */
3289 deselect: function deselect(el) {
3290 var sortable = el.parentNode[expando],
3291 index = multiDragElements.indexOf(el);
3292 if (!sortable || !sortable.options.multiDrag || !~index) return;
3293 toggleClass(el, sortable.options.selectedClass, false);
3294 multiDragElements.splice(index, 1);
3295 }
3296 },
3297 eventProperties: function eventProperties() {
3298 var _this3 = this;
3299 var oldIndicies = [],
3300 newIndicies = [];
3301 multiDragElements.forEach(function (multiDragElement) {
3302 oldIndicies.push({
3303 multiDragElement: multiDragElement,
3304 index: multiDragElement.sortableIndex
3305 });
3306
3307 // multiDragElements will already be sorted if folding
3308 var newIndex;
3309 if (folding && multiDragElement !== dragEl$1) {
3310 newIndex = -1;
3311 } else if (folding) {
3312 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
3313 } else {
3314 newIndex = index(multiDragElement);
3315 }
3316 newIndicies.push({
3317 multiDragElement: multiDragElement,
3318 index: newIndex
3319 });
3320 });
3321 return {
3322 items: _toConsumableArray(multiDragElements),
3323 clones: [].concat(multiDragClones),
3324 oldIndicies: oldIndicies,
3325 newIndicies: newIndicies
3326 };
3327 },
3328 optionListeners: {
3329 multiDragKey: function multiDragKey(key) {
3330 key = key.toLowerCase();
3331 if (key === 'ctrl') {
3332 key = 'Control';
3333 } else if (key.length > 1) {
3334 key = key.charAt(0).toUpperCase() + key.substr(1);
3335 }
3336 return key;
3337 }
3338 }
3339 });
3340 }
3341 function insertMultiDragElements(clonesInserted, rootEl) {
3342 multiDragElements.forEach(function (multiDragElement, i) {
3343 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
3344 if (target) {
3345 rootEl.insertBefore(multiDragElement, target);
3346 } else {
3347 rootEl.appendChild(multiDragElement);
3348 }
3349 });
3350 }
3351
3352 /**
3353 * Insert multi-drag clones
3354 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
3355 * @param {HTMLElement} rootEl
3356 */
3357 function insertMultiDragClones(elementsInserted, rootEl) {
3358 multiDragClones.forEach(function (clone, i) {
3359 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
3360 if (target) {
3361 rootEl.insertBefore(clone, target);
3362 } else {
3363 rootEl.appendChild(clone);
3364 }
3365 });
3366 }
3367 function removeMultiDragElements() {
3368 multiDragElements.forEach(function (multiDragElement) {
3369 if (multiDragElement === dragEl$1) return;
3370 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
3371 });
3372 }
3373
3374 Sortable.mount(new AutoScrollPlugin());
3375 Sortable.mount(Remove, Revert);
3376
3377 Sortable.mount(new SwapPlugin());
3378 Sortable.mount(new MultiDragPlugin());
3379
3380 export default Sortable;
3381