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