in src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Scripts/Sortable.js [3099:3662]
function MultiDragPlugin() {
function MultiDrag(sortable) {
// Bind all private methods
for (var fn in this) {
if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
this[fn] = this[fn].bind(this);
}
}
if (sortable.options.supportPointer) {
on(document, 'pointerup', this._deselectMultiDrag);
} else {
on(document, 'mouseup', this._deselectMultiDrag);
on(document, 'touchend', this._deselectMultiDrag);
}
on(document, 'keydown', this._checkKeyDown);
on(document, 'keyup', this._checkKeyUp);
this.defaults = {
selectedClass: 'sortable-selected',
multiDragKey: null,
setData: function setData(dataTransfer, dragEl) {
var data = '';
if (multiDragElements.length && multiDragSortable === sortable) {
multiDragElements.forEach(function (multiDragElement, i) {
data += (!i ? '' : ', ') + multiDragElement.textContent;
});
} else {
data = dragEl.textContent;
}
dataTransfer.setData('Text', data);
}
};
}
MultiDrag.prototype = {
multiDragKeyDown: false,
isMultiDrag: false,
delayStartGlobal: function delayStartGlobal(_ref) {
var dragged = _ref.dragEl;
dragEl$1 = dragged;
},
delayEnded: function delayEnded() {
this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
},
setupClone: function setupClone(_ref2) {
var sortable = _ref2.sortable,
cancel = _ref2.cancel;
if (!this.isMultiDrag) return;
for (var i = 0; i < multiDragElements.length; i++) {
multiDragClones.push(clone(multiDragElements[i]));
multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
multiDragClones[i].draggable = false;
multiDragClones[i].style['will-change'] = '';
toggleClass(multiDragClones[i], this.options.selectedClass, false);
multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
}
sortable._hideClone();
cancel();
},
clone: function clone(_ref3) {
var sortable = _ref3.sortable,
rootEl = _ref3.rootEl,
dispatchSortableEvent = _ref3.dispatchSortableEvent,
cancel = _ref3.cancel;
if (!this.isMultiDrag) return;
if (!this.options.removeCloneOnHide) {
if (multiDragElements.length && multiDragSortable === sortable) {
insertMultiDragClones(true, rootEl);
dispatchSortableEvent('clone');
cancel();
}
}
},
showClone: function showClone(_ref4) {
var cloneNowShown = _ref4.cloneNowShown,
rootEl = _ref4.rootEl,
cancel = _ref4.cancel;
if (!this.isMultiDrag) return;
insertMultiDragClones(false, rootEl);
multiDragClones.forEach(function (clone) {
css(clone, 'display', '');
});
cloneNowShown();
clonesHidden = false;
cancel();
},
hideClone: function hideClone(_ref5) {
var _this = this;
var sortable = _ref5.sortable,
cloneNowHidden = _ref5.cloneNowHidden,
cancel = _ref5.cancel;
if (!this.isMultiDrag) return;
multiDragClones.forEach(function (clone) {
css(clone, 'display', 'none');
if (_this.options.removeCloneOnHide && clone.parentNode) {
clone.parentNode.removeChild(clone);
}
});
cloneNowHidden();
clonesHidden = true;
cancel();
},
dragStartGlobal: function dragStartGlobal(_ref6) {
var sortable = _ref6.sortable;
if (!this.isMultiDrag && multiDragSortable) {
multiDragSortable.multiDrag._deselectMultiDrag();
}
multiDragElements.forEach(function (multiDragElement) {
multiDragElement.sortableIndex = index(multiDragElement);
}); // Sort multi-drag elements
multiDragElements = multiDragElements.sort(function (a, b) {
return a.sortableIndex - b.sortableIndex;
});
dragStarted = true;
},
dragStarted: function dragStarted(_ref7) {
var _this2 = this;
var sortable = _ref7.sortable;
if (!this.isMultiDrag) return;
if (this.options.sort) {
// Capture rects,
// hide multi drag elements (by positioning them absolute),
// set multi drag elements rects to dragRect,
// show multi drag elements,
// animate to rects,
// unset rects & remove from DOM
sortable.captureAnimationState();
if (this.options.animation) {
multiDragElements.forEach(function (multiDragElement) {
if (multiDragElement === dragEl$1) return;
css(multiDragElement, 'position', 'absolute');
});
var dragRect = getRect(dragEl$1, false, true, true);
multiDragElements.forEach(function (multiDragElement) {
if (multiDragElement === dragEl$1) return;
setRect(multiDragElement, dragRect);
});
folding = true;
initialFolding = true;
}
}
sortable.animateAll(function () {
folding = false;
initialFolding = false;
if (_this2.options.animation) {
multiDragElements.forEach(function (multiDragElement) {
unsetRect(multiDragElement);
});
} // Remove all auxiliary multidrag items from el, if sorting enabled
if (_this2.options.sort) {
removeMultiDragElements();
}
});
},
dragOver: function dragOver(_ref8) {
var target = _ref8.target,
completed = _ref8.completed,
cancel = _ref8.cancel;
if (folding && ~multiDragElements.indexOf(target)) {
completed(false);
cancel();
}
},
revert: function revert(_ref9) {
var fromSortable = _ref9.fromSortable,
rootEl = _ref9.rootEl,
sortable = _ref9.sortable,
dragRect = _ref9.dragRect;
if (multiDragElements.length > 1) {
// Setup unfold animation
multiDragElements.forEach(function (multiDragElement) {
sortable.addAnimationState({
target: multiDragElement,
rect: folding ? getRect(multiDragElement) : dragRect
});
unsetRect(multiDragElement);
multiDragElement.fromRect = dragRect;
fromSortable.removeAnimationState(multiDragElement);
});
folding = false;
insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
}
},
dragOverCompleted: function dragOverCompleted(_ref10) {
var sortable = _ref10.sortable,
isOwner = _ref10.isOwner,
insertion = _ref10.insertion,
activeSortable = _ref10.activeSortable,
parentEl = _ref10.parentEl,
putSortable = _ref10.putSortable;
var options = this.options;
if (insertion) {
// Clones must be hidden before folding animation to capture dragRectAbsolute properly
if (isOwner) {
activeSortable._hideClone();
}
initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location
if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
// Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
var dragRectAbsolute = getRect(dragEl$1, false, true, true);
multiDragElements.forEach(function (multiDragElement) {
if (multiDragElement === dragEl$1) return;
setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
// while folding, and so that we can capture them again because old sortable will no longer be fromSortable
parentEl.appendChild(multiDragElement);
});
folding = true;
} // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
if (!isOwner) {
// Only remove if not folding (folding will remove them anyways)
if (!folding) {
removeMultiDragElements();
}
if (multiDragElements.length > 1) {
var clonesHiddenBefore = clonesHidden;
activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden
if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
multiDragClones.forEach(function (clone) {
activeSortable.addAnimationState({
target: clone,
rect: clonesFromRect
});
clone.fromRect = clonesFromRect;
clone.thisAnimationDuration = null;
});
}
} else {
activeSortable._showClone(sortable);
}
}
}
},
dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
var dragRect = _ref11.dragRect,
isOwner = _ref11.isOwner,
activeSortable = _ref11.activeSortable;
multiDragElements.forEach(function (multiDragElement) {
multiDragElement.thisAnimationDuration = null;
});
if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
clonesFromRect = _extends({}, dragRect);
var dragMatrix = matrix(dragEl$1, true);
clonesFromRect.top -= dragMatrix.f;
clonesFromRect.left -= dragMatrix.e;
}
},
dragOverAnimationComplete: function dragOverAnimationComplete() {
if (folding) {
folding = false;
removeMultiDragElements();
}
},
drop: function drop(_ref12) {
var evt = _ref12.originalEvent,
rootEl = _ref12.rootEl,
parentEl = _ref12.parentEl,
sortable = _ref12.sortable,
dispatchSortableEvent = _ref12.dispatchSortableEvent,
oldIndex = _ref12.oldIndex,
putSortable = _ref12.putSortable;
var toSortable = putSortable || this.sortable;
if (!evt) return;
var options = this.options,
children = parentEl.children; // Multi-drag selection
if (!dragStarted) {
if (options.multiDragKey && !this.multiDragKeyDown) {
this._deselectMultiDrag();
}
toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
if (!~multiDragElements.indexOf(dragEl$1)) {
multiDragElements.push(dragEl$1);
dispatchEvent({
sortable: sortable,
rootEl: rootEl,
name: 'select',
targetEl: dragEl$1,
originalEvt: evt
}); // Modifier activated, select from last to dragEl
if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
var lastIndex = index(lastMultiDragSelect),
currentIndex = index(dragEl$1);
if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
// Must include lastMultiDragSelect (select it), in case modified selection from no selection
// (but previous selection existed)
var n, i;
if (currentIndex > lastIndex) {
i = lastIndex;
n = currentIndex;
} else {
i = currentIndex;
n = lastIndex + 1;
}
for (; i < n; i++) {
if (~multiDragElements.indexOf(children[i])) continue;
toggleClass(children[i], options.selectedClass, true);
multiDragElements.push(children[i]);
dispatchEvent({
sortable: sortable,
rootEl: rootEl,
name: 'select',
targetEl: children[i],
originalEvt: evt
});
}
}
} else {
lastMultiDragSelect = dragEl$1;
}
multiDragSortable = toSortable;
} else {
multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
lastMultiDragSelect = null;
dispatchEvent({
sortable: sortable,
rootEl: rootEl,
name: 'deselect',
targetEl: dragEl$1,
originalEvt: evt
});
}
} // Multi-drag drop
if (dragStarted && this.isMultiDrag) {
// Do not "unfold" after around dragEl if reverted
if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
var dragRect = getRect(dragEl$1),
multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
toSortable.captureAnimationState();
if (!initialFolding) {
if (options.animation) {
dragEl$1.fromRect = dragRect;
multiDragElements.forEach(function (multiDragElement) {
multiDragElement.thisAnimationDuration = null;
if (multiDragElement !== dragEl$1) {
var rect = folding ? getRect(multiDragElement) : dragRect;
multiDragElement.fromRect = rect; // Prepare unfold animation
toSortable.addAnimationState({
target: multiDragElement,
rect: rect
});
}
});
} // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
// properly they must all be removed
removeMultiDragElements();
multiDragElements.forEach(function (multiDragElement) {
if (children[multiDragIndex]) {
parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
} else {
parentEl.appendChild(multiDragElement);
}
multiDragIndex++;
}); // If initial folding is done, the elements may have changed position because they are now
// unfolding around dragEl, even though dragEl may not have his index changed, so update event
// must be fired here as Sortable will not.
if (oldIndex === index(dragEl$1)) {
var update = false;
multiDragElements.forEach(function (multiDragElement) {
if (multiDragElement.sortableIndex !== index(multiDragElement)) {
update = true;
return;
}
});
if (update) {
dispatchSortableEvent('update');
}
}
} // Must be done after capturing individual rects (scroll bar)
multiDragElements.forEach(function (multiDragElement) {
unsetRect(multiDragElement);
});
toSortable.animateAll();
}
multiDragSortable = toSortable;
} // Remove clones if necessary
if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
multiDragClones.forEach(function (clone) {
clone.parentNode && clone.parentNode.removeChild(clone);
});
}
},
nullingGlobal: function nullingGlobal() {
this.isMultiDrag = dragStarted = false;
multiDragClones.length = 0;
},
destroyGlobal: function destroyGlobal() {
this._deselectMultiDrag();
off(document, 'pointerup', this._deselectMultiDrag);
off(document, 'mouseup', this._deselectMultiDrag);
off(document, 'touchend', this._deselectMultiDrag);
off(document, 'keydown', this._checkKeyDown);
off(document, 'keyup', this._checkKeyUp);
},
_deselectMultiDrag: function _deselectMultiDrag(evt) {
if (typeof dragStarted !== "undefined" && dragStarted) return; // Only deselect if selection is in this sortable
if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable
if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click
if (evt && evt.button !== 0) return;
while (multiDragElements.length) {
var el = multiDragElements[0];
toggleClass(el, this.options.selectedClass, false);
multiDragElements.shift();
dispatchEvent({
sortable: this.sortable,
rootEl: this.sortable.el,
name: 'deselect',
targetEl: el,
originalEvt: evt
});
}
},
_checkKeyDown: function _checkKeyDown(evt) {
if (evt.key === this.options.multiDragKey) {
this.multiDragKeyDown = true;
}
},
_checkKeyUp: function _checkKeyUp(evt) {
if (evt.key === this.options.multiDragKey) {
this.multiDragKeyDown = false;
}
}
};
return _extends(MultiDrag, {
// Static methods & properties
pluginName: 'multiDrag',
utils: {
/**
* Selects the provided multi-drag item
* @param {HTMLElement} el The element to be selected
*/
select: function select(el) {
var sortable = el.parentNode[expando];
if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
if (multiDragSortable && multiDragSortable !== sortable) {
multiDragSortable.multiDrag._deselectMultiDrag();
multiDragSortable = sortable;
}
toggleClass(el, sortable.options.selectedClass, true);
multiDragElements.push(el);
},
/**
* Deselects the provided multi-drag item
* @param {HTMLElement} el The element to be deselected
*/
deselect: function deselect(el) {
var sortable = el.parentNode[expando],
index = multiDragElements.indexOf(el);
if (!sortable || !sortable.options.multiDrag || !~index) return;
toggleClass(el, sortable.options.selectedClass, false);
multiDragElements.splice(index, 1);
}
},
eventProperties: function eventProperties() {
var _this3 = this;
var oldIndicies = [],
newIndicies = [];
multiDragElements.forEach(function (multiDragElement) {
oldIndicies.push({
multiDragElement: multiDragElement,
index: multiDragElement.sortableIndex
}); // multiDragElements will already be sorted if folding
var newIndex;
if (folding && multiDragElement !== dragEl$1) {
newIndex = -1;
} else if (folding) {
newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
} else {
newIndex = index(multiDragElement);
}
newIndicies.push({
multiDragElement: multiDragElement,
index: newIndex
});
});
return {
items: _toConsumableArray(multiDragElements),
clones: [].concat(multiDragClones),
oldIndicies: oldIndicies,
newIndicies: newIndicies
};
},
optionListeners: {
multiDragKey: function multiDragKey(key) {
key = key.toLowerCase();
if (key === 'ctrl') {
key = 'Control';
} else if (key.length > 1) {
key = key.charAt(0).toUpperCase() + key.substr(1);
}
return key;
}
}
});
}