public/external/@shopify/draggable/build/umd/index.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Draggable = {}));
})(this, (function (exports) { 'use strict';
class AbstractEvent {
constructor(data) {
this._canceled = false;
this.data = data;
}
get type() {
return this.constructor.type;
}
get cancelable() {
return this.constructor.cancelable;
}
cancel() {
this._canceled = true;
}
canceled() {
return this._canceled;
}
clone(data) {
return new this.constructor({
...this.data,
...data
});
}
}
AbstractEvent.type = 'event';
AbstractEvent.cancelable = false;
class AbstractPlugin {
constructor(draggable) {
this.draggable = draggable;
}
attach() {
throw new Error('Not Implemented');
}
detach() {
throw new Error('Not Implemented');
}
}
const defaultDelay = {
mouse: 0,
drag: 0,
touch: 100
};
class Sensor {
constructor(containers = [], options = {}) {
this.containers = [...containers];
this.options = {
...options
};
this.dragging = false;
this.currentContainer = null;
this.originalSource = null;
this.startEvent = null;
this.delay = calcDelay(options.delay);
}
attach() {
return this;
}
detach() {
return this;
}
addContainer(...containers) {
this.containers = [...this.containers, ...containers];
}
removeContainer(...containers) {
this.containers = this.containers.filter(container => !containers.includes(container));
}
trigger(element, sensorEvent) {
const event = document.createEvent('Event');
event.detail = sensorEvent;
event.initEvent(sensorEvent.type, true, true);
element.dispatchEvent(event);
this.lastEvent = sensorEvent;
return sensorEvent;
}
}
function calcDelay(optionsDelay) {
const delay = {};
if (optionsDelay === undefined) {
return {
...defaultDelay
};
}
if (typeof optionsDelay === 'number') {
for (const key in defaultDelay) {
if (Object.prototype.hasOwnProperty.call(defaultDelay, key)) {
delay[key] = optionsDelay;
}
}
return delay;
}
for (const key in defaultDelay) {
if (Object.prototype.hasOwnProperty.call(defaultDelay, key)) {
if (optionsDelay[key] === undefined) {
delay[key] = defaultDelay[key];
} else {
delay[key] = optionsDelay[key];
}
}
}
return delay;
}
function closest(node, value) {
if (node == null) {
return null;
}
function conditionFn(currentNode) {
if (currentNode == null || value == null) {
return false;
} else if (isSelector(value)) {
return Element.prototype.matches.call(currentNode, value);
} else if (isNodeList(value)) {
return [...value].includes(currentNode);
} else if (isElement(value)) {
return value === currentNode;
} else if (isFunction(value)) {
return value(currentNode);
} else {
return false;
}
}
let current = node;
do {
current = current.correspondingUseElement || current.correspondingElement || current;
if (conditionFn(current)) {
return current;
}
current = current?.parentNode || null;
} while (current != null && current !== document.body && current !== document);
return null;
}
function isSelector(value) {
return Boolean(typeof value === 'string');
}
function isNodeList(value) {
return Boolean(value instanceof NodeList || value instanceof Array);
}
function isElement(value) {
return Boolean(value instanceof Node);
}
function isFunction(value) {
return Boolean(typeof value === 'function');
}
function AutoBind(originalMethod, {
name,
addInitializer
}) {
addInitializer(function () {
this[name] = originalMethod.bind(this);
});
}
function requestNextAnimationFrame(callback) {
return requestAnimationFrame(() => {
requestAnimationFrame(callback);
});
}
function distance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}
function touchCoords(event) {
const {
touches,
changedTouches
} = event;
return touches && touches[0] || changedTouches && changedTouches[0];
}
class SensorEvent extends AbstractEvent {
get originalEvent() {
return this.data.originalEvent;
}
get clientX() {
return this.data.clientX;
}
get clientY() {
return this.data.clientY;
}
get target() {
return this.data.target;
}
get container() {
return this.data.container;
}
get originalSource() {
return this.data.originalSource;
}
get pressure() {
return this.data.pressure;
}
}
class DragStartSensorEvent extends SensorEvent {}
DragStartSensorEvent.type = 'drag:start';
class DragMoveSensorEvent extends SensorEvent {}
DragMoveSensorEvent.type = 'drag:move';
class DragStopSensorEvent extends SensorEvent {}
DragStopSensorEvent.type = 'drag:stop';
class DragPressureSensorEvent extends SensorEvent {}
DragPressureSensorEvent.type = 'drag:pressure';
const onContextMenuWhileDragging = Symbol('onContextMenuWhileDragging');
const onMouseDown$2 = Symbol('onMouseDown');
const onMouseMove$1 = Symbol('onMouseMove');
const onMouseUp$2 = Symbol('onMouseUp');
const startDrag$1 = Symbol('startDrag');
const onDistanceChange$1 = Symbol('onDistanceChange');
class MouseSensor extends Sensor {
constructor(containers = [], options = {}) {
super(containers, options);
this.mouseDownTimeout = null;
this.pageX = null;
this.pageY = null;
this[onContextMenuWhileDragging] = this[onContextMenuWhileDragging].bind(this);
this[onMouseDown$2] = this[onMouseDown$2].bind(this);
this[onMouseMove$1] = this[onMouseMove$1].bind(this);
this[onMouseUp$2] = this[onMouseUp$2].bind(this);
this[startDrag$1] = this[startDrag$1].bind(this);
this[onDistanceChange$1] = this[onDistanceChange$1].bind(this);
}
attach() {
document.addEventListener('mousedown', this[onMouseDown$2], true);
}
detach() {
document.removeEventListener('mousedown', this[onMouseDown$2], true);
}
[onMouseDown$2](event) {
if (event.button !== 0 || event.ctrlKey || event.metaKey) {
return;
}
const container = closest(event.target, this.containers);
if (!container) {
return;
}
if (this.options.handle && event.target && !closest(event.target, this.options.handle)) {
return;
}
const originalSource = closest(event.target, this.options.draggable);
if (!originalSource) {
return;
}
const {
delay
} = this;
const {
pageX,
pageY
} = event;
Object.assign(this, {
pageX,
pageY
});
this.onMouseDownAt = Date.now();
this.startEvent = event;
this.currentContainer = container;
this.originalSource = originalSource;
document.addEventListener('mouseup', this[onMouseUp$2]);
document.addEventListener('dragstart', preventNativeDragStart);
document.addEventListener('mousemove', this[onDistanceChange$1]);
this.mouseDownTimeout = window.setTimeout(() => {
this[onDistanceChange$1]({
pageX: this.pageX,
pageY: this.pageY
});
}, delay.mouse);
}
[startDrag$1]() {
const startEvent = this.startEvent;
const container = this.currentContainer;
const originalSource = this.originalSource;
const dragStartEvent = new DragStartSensorEvent({
clientX: startEvent.clientX,
clientY: startEvent.clientY,
target: startEvent.target,
container,
originalSource,
originalEvent: startEvent
});
this.trigger(this.currentContainer, dragStartEvent);
this.dragging = !dragStartEvent.canceled();
if (this.dragging) {
document.addEventListener('contextmenu', this[onContextMenuWhileDragging], true);
document.addEventListener('mousemove', this[onMouseMove$1]);
}
}
[onDistanceChange$1](event) {
const {
pageX,
pageY
} = event;
const {
distance: distance$1
} = this.options;
const {
startEvent,
delay
} = this;
Object.assign(this, {
pageX,
pageY
});
if (!this.currentContainer) {
return;
}
const timeElapsed = Date.now() - this.onMouseDownAt;
const distanceTravelled = distance(startEvent.pageX, startEvent.pageY, pageX, pageY) || 0;
clearTimeout(this.mouseDownTimeout);
if (timeElapsed < delay.mouse) {
document.removeEventListener('mousemove', this[onDistanceChange$1]);
} else if (distanceTravelled >= distance$1) {
document.removeEventListener('mousemove', this[onDistanceChange$1]);
this[startDrag$1]();
}
}
[onMouseMove$1](event) {
if (!this.dragging) {
return;
}
const target = document.elementFromPoint(event.clientX, event.clientY);
const dragMoveEvent = new DragMoveSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragMoveEvent);
}
[onMouseUp$2](event) {
clearTimeout(this.mouseDownTimeout);
if (event.button !== 0) {
return;
}
document.removeEventListener('mouseup', this[onMouseUp$2]);
document.removeEventListener('dragstart', preventNativeDragStart);
document.removeEventListener('mousemove', this[onDistanceChange$1]);
if (!this.dragging) {
return;
}
const target = document.elementFromPoint(event.clientX, event.clientY);
const dragStopEvent = new DragStopSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragStopEvent);
document.removeEventListener('contextmenu', this[onContextMenuWhileDragging], true);
document.removeEventListener('mousemove', this[onMouseMove$1]);
this.currentContainer = null;
this.dragging = false;
this.startEvent = null;
}
[onContextMenuWhileDragging](event) {
event.preventDefault();
}
}
function preventNativeDragStart(event) {
event.preventDefault();
}
const onTouchStart = Symbol('onTouchStart');
const onTouchEnd = Symbol('onTouchEnd');
const onTouchMove = Symbol('onTouchMove');
const startDrag = Symbol('startDrag');
const onDistanceChange = Symbol('onDistanceChange');
let preventScrolling = false;
window.addEventListener('touchmove', event => {
if (!preventScrolling) {
return;
}
event.preventDefault();
}, {
passive: false
});
class TouchSensor extends Sensor {
constructor(containers = [], options = {}) {
super(containers, options);
this.currentScrollableParent = null;
this.tapTimeout = null;
this.touchMoved = false;
this.pageX = null;
this.pageY = null;
this[onTouchStart] = this[onTouchStart].bind(this);
this[onTouchEnd] = this[onTouchEnd].bind(this);
this[onTouchMove] = this[onTouchMove].bind(this);
this[startDrag] = this[startDrag].bind(this);
this[onDistanceChange] = this[onDistanceChange].bind(this);
}
attach() {
document.addEventListener('touchstart', this[onTouchStart]);
}
detach() {
document.removeEventListener('touchstart', this[onTouchStart]);
}
[onTouchStart](event) {
const container = closest(event.target, this.containers);
if (!container) {
return;
}
if (this.options.handle && event.target && !closest(event.target, this.options.handle)) {
return;
}
const originalSource = closest(event.target, this.options.draggable);
if (!originalSource) {
return;
}
const {
distance = 0
} = this.options;
const {
delay
} = this;
const {
pageX,
pageY
} = touchCoords(event);
Object.assign(this, {
pageX,
pageY
});
this.onTouchStartAt = Date.now();
this.startEvent = event;
this.currentContainer = container;
this.originalSource = originalSource;
document.addEventListener('touchend', this[onTouchEnd]);
document.addEventListener('touchcancel', this[onTouchEnd]);
document.addEventListener('touchmove', this[onDistanceChange]);
container.addEventListener('contextmenu', onContextMenu);
if (distance) {
preventScrolling = true;
}
this.tapTimeout = window.setTimeout(() => {
this[onDistanceChange]({
touches: [{
pageX: this.pageX,
pageY: this.pageY
}]
});
}, delay.touch);
}
[startDrag]() {
const startEvent = this.startEvent;
const container = this.currentContainer;
const touch = touchCoords(startEvent);
const originalSource = this.originalSource;
const dragStartEvent = new DragStartSensorEvent({
clientX: touch.pageX,
clientY: touch.pageY,
target: startEvent.target,
container,
originalSource,
originalEvent: startEvent
});
this.trigger(this.currentContainer, dragStartEvent);
this.dragging = !dragStartEvent.canceled();
if (this.dragging) {
document.addEventListener('touchmove', this[onTouchMove]);
}
preventScrolling = this.dragging;
}
[onDistanceChange](event) {
const {
distance: distance$1
} = this.options;
const {
startEvent,
delay
} = this;
const start = touchCoords(startEvent);
const current = touchCoords(event);
const timeElapsed = Date.now() - this.onTouchStartAt;
const distanceTravelled = distance(start.pageX, start.pageY, current.pageX, current.pageY);
Object.assign(this, current);
clearTimeout(this.tapTimeout);
if (timeElapsed < delay.touch) {
document.removeEventListener('touchmove', this[onDistanceChange]);
} else if (distanceTravelled >= distance$1) {
document.removeEventListener('touchmove', this[onDistanceChange]);
this[startDrag]();
}
}
[onTouchMove](event) {
if (!this.dragging) {
return;
}
const {
pageX,
pageY
} = touchCoords(event);
const target = document.elementFromPoint(pageX - window.scrollX, pageY - window.scrollY);
const dragMoveEvent = new DragMoveSensorEvent({
clientX: pageX,
clientY: pageY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragMoveEvent);
}
[onTouchEnd](event) {
clearTimeout(this.tapTimeout);
preventScrolling = false;
document.removeEventListener('touchend', this[onTouchEnd]);
document.removeEventListener('touchcancel', this[onTouchEnd]);
document.removeEventListener('touchmove', this[onDistanceChange]);
if (this.currentContainer) {
this.currentContainer.removeEventListener('contextmenu', onContextMenu);
}
if (!this.dragging) {
return;
}
document.removeEventListener('touchmove', this[onTouchMove]);
const {
pageX,
pageY
} = touchCoords(event);
const target = document.elementFromPoint(pageX - window.scrollX, pageY - window.scrollY);
event.preventDefault();
const dragStopEvent = new DragStopSensorEvent({
clientX: pageX,
clientY: pageY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragStopEvent);
this.currentContainer = null;
this.dragging = false;
this.startEvent = null;
}
}
function onContextMenu(event) {
event.preventDefault();
event.stopPropagation();
}
const onMouseDown$1 = Symbol('onMouseDown');
const onMouseUp$1 = Symbol('onMouseUp');
const onDragStart$7 = Symbol('onDragStart');
const onDragOver$3 = Symbol('onDragOver');
const onDragEnd = Symbol('onDragEnd');
const onDrop = Symbol('onDrop');
const reset = Symbol('reset');
class DragSensor extends Sensor {
constructor(containers = [], options = {}) {
super(containers, options);
this.mouseDownTimeout = null;
this.draggableElement = null;
this.nativeDraggableElement = null;
this[onMouseDown$1] = this[onMouseDown$1].bind(this);
this[onMouseUp$1] = this[onMouseUp$1].bind(this);
this[onDragStart$7] = this[onDragStart$7].bind(this);
this[onDragOver$3] = this[onDragOver$3].bind(this);
this[onDragEnd] = this[onDragEnd].bind(this);
this[onDrop] = this[onDrop].bind(this);
}
attach() {
document.addEventListener('mousedown', this[onMouseDown$1], true);
}
detach() {
document.removeEventListener('mousedown', this[onMouseDown$1], true);
}
[onDragStart$7](event) {
event.dataTransfer.setData('text', '');
event.dataTransfer.effectAllowed = this.options.type;
const target = document.elementFromPoint(event.clientX, event.clientY);
const originalSource = this.draggableElement;
if (!originalSource) {
return;
}
const dragStartEvent = new DragStartSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
originalSource,
container: this.currentContainer,
originalEvent: event
});
setTimeout(() => {
this.trigger(this.currentContainer, dragStartEvent);
if (dragStartEvent.canceled()) {
this.dragging = false;
} else {
this.dragging = true;
}
}, 0);
}
[onDragOver$3](event) {
if (!this.dragging) {
return;
}
const target = document.elementFromPoint(event.clientX, event.clientY);
const container = this.currentContainer;
const dragMoveEvent = new DragMoveSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container,
originalEvent: event
});
this.trigger(container, dragMoveEvent);
if (!dragMoveEvent.canceled()) {
event.preventDefault();
event.dataTransfer.dropEffect = this.options.type;
}
}
[onDragEnd](event) {
if (!this.dragging) {
return;
}
document.removeEventListener('mouseup', this[onMouseUp$1], true);
const target = document.elementFromPoint(event.clientX, event.clientY);
const container = this.currentContainer;
const dragStopEvent = new DragStopSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container,
originalEvent: event
});
this.trigger(container, dragStopEvent);
this.dragging = false;
this.startEvent = null;
this[reset]();
}
[onDrop](event) {
event.preventDefault();
}
[onMouseDown$1](event) {
if (event.target && (event.target.form || event.target.contenteditable)) {
return;
}
const target = event.target;
this.currentContainer = closest(target, this.containers);
if (!this.currentContainer) {
return;
}
if (this.options.handle && target && !closest(target, this.options.handle)) {
return;
}
const originalSource = closest(target, this.options.draggable);
if (!originalSource) {
return;
}
const nativeDraggableElement = closest(event.target, element => element.draggable);
if (nativeDraggableElement) {
nativeDraggableElement.draggable = false;
this.nativeDraggableElement = nativeDraggableElement;
}
document.addEventListener('mouseup', this[onMouseUp$1], true);
document.addEventListener('dragstart', this[onDragStart$7], false);
document.addEventListener('dragover', this[onDragOver$3], false);
document.addEventListener('dragend', this[onDragEnd], false);
document.addEventListener('drop', this[onDrop], false);
this.startEvent = event;
this.mouseDownTimeout = setTimeout(() => {
originalSource.draggable = true;
this.draggableElement = originalSource;
}, this.delay.drag);
}
[onMouseUp$1]() {
this[reset]();
}
[reset]() {
clearTimeout(this.mouseDownTimeout);
document.removeEventListener('mouseup', this[onMouseUp$1], true);
document.removeEventListener('dragstart', this[onDragStart$7], false);
document.removeEventListener('dragover', this[onDragOver$3], false);
document.removeEventListener('dragend', this[onDragEnd], false);
document.removeEventListener('drop', this[onDrop], false);
if (this.nativeDraggableElement) {
this.nativeDraggableElement.draggable = true;
this.nativeDraggableElement = null;
}
if (this.draggableElement) {
this.draggableElement.draggable = false;
this.draggableElement = null;
}
}
}
const onMouseForceWillBegin = Symbol('onMouseForceWillBegin');
const onMouseForceDown = Symbol('onMouseForceDown');
const onMouseDown = Symbol('onMouseDown');
const onMouseForceChange = Symbol('onMouseForceChange');
const onMouseMove = Symbol('onMouseMove');
const onMouseUp = Symbol('onMouseUp');
const onMouseForceGlobalChange = Symbol('onMouseForceGlobalChange');
class ForceTouchSensor extends Sensor {
constructor(containers = [], options = {}) {
super(containers, options);
this.mightDrag = false;
this[onMouseForceWillBegin] = this[onMouseForceWillBegin].bind(this);
this[onMouseForceDown] = this[onMouseForceDown].bind(this);
this[onMouseDown] = this[onMouseDown].bind(this);
this[onMouseForceChange] = this[onMouseForceChange].bind(this);
this[onMouseMove] = this[onMouseMove].bind(this);
this[onMouseUp] = this[onMouseUp].bind(this);
}
attach() {
for (const container of this.containers) {
container.addEventListener('webkitmouseforcewillbegin', this[onMouseForceWillBegin], false);
container.addEventListener('webkitmouseforcedown', this[onMouseForceDown], false);
container.addEventListener('mousedown', this[onMouseDown], true);
container.addEventListener('webkitmouseforcechanged', this[onMouseForceChange], false);
}
document.addEventListener('mousemove', this[onMouseMove]);
document.addEventListener('mouseup', this[onMouseUp]);
}
detach() {
for (const container of this.containers) {
container.removeEventListener('webkitmouseforcewillbegin', this[onMouseForceWillBegin], false);
container.removeEventListener('webkitmouseforcedown', this[onMouseForceDown], false);
container.removeEventListener('mousedown', this[onMouseDown], true);
container.removeEventListener('webkitmouseforcechanged', this[onMouseForceChange], false);
}
document.removeEventListener('mousemove', this[onMouseMove]);
document.removeEventListener('mouseup', this[onMouseUp]);
}
[onMouseForceWillBegin](event) {
event.preventDefault();
this.mightDrag = true;
}
[onMouseForceDown](event) {
if (this.dragging) {
return;
}
const target = document.elementFromPoint(event.clientX, event.clientY);
const container = event.currentTarget;
if (this.options.handle && target && !closest(target, this.options.handle)) {
return;
}
const originalSource = closest(target, this.options.draggable);
if (!originalSource) {
return;
}
const dragStartEvent = new DragStartSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container,
originalSource,
originalEvent: event
});
this.trigger(container, dragStartEvent);
this.currentContainer = container;
this.dragging = !dragStartEvent.canceled();
this.mightDrag = false;
}
[onMouseUp](event) {
if (!this.dragging) {
return;
}
const dragStopEvent = new DragStopSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target: null,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragStopEvent);
this.currentContainer = null;
this.dragging = false;
this.mightDrag = false;
}
[onMouseDown](event) {
if (!this.mightDrag) {
return;
}
event.stopPropagation();
event.stopImmediatePropagation();
event.preventDefault();
}
[onMouseMove](event) {
if (!this.dragging) {
return;
}
const target = document.elementFromPoint(event.clientX, event.clientY);
const dragMoveEvent = new DragMoveSensorEvent({
clientX: event.clientX,
clientY: event.clientY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragMoveEvent);
}
[onMouseForceChange](event) {
if (this.dragging) {
return;
}
const target = event.target;
const container = event.currentTarget;
const dragPressureEvent = new DragPressureSensorEvent({
pressure: event.webkitForce,
clientX: event.clientX,
clientY: event.clientY,
target,
container,
originalEvent: event
});
this.trigger(container, dragPressureEvent);
}
[onMouseForceGlobalChange](event) {
if (!this.dragging) {
return;
}
const target = event.target;
const dragPressureEvent = new DragPressureSensorEvent({
pressure: event.webkitForce,
clientX: event.clientX,
clientY: event.clientY,
target,
container: this.currentContainer,
originalEvent: event
});
this.trigger(this.currentContainer, dragPressureEvent);
}
}
var index$2 = /*#__PURE__*/Object.freeze({
__proto__: null,
DragMoveSensorEvent: DragMoveSensorEvent,
DragPressureSensorEvent: DragPressureSensorEvent,
DragSensor: DragSensor,
DragStartSensorEvent: DragStartSensorEvent,
DragStopSensorEvent: DragStopSensorEvent,
ForceTouchSensor: ForceTouchSensor,
MouseSensor: MouseSensor,
Sensor: Sensor,
SensorEvent: SensorEvent,
TouchSensor: TouchSensor
});
class CollidableEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get dragEvent() {
return this.data.dragEvent;
}
}
CollidableEvent.type = 'collidable';
class CollidableInEvent extends CollidableEvent {
get collidingElement() {
return this.data.collidingElement;
}
}
CollidableInEvent.type = 'collidable:in';
class CollidableOutEvent extends CollidableEvent {
get collidingElement() {
return this.data.collidingElement;
}
}
CollidableOutEvent.type = 'collidable:out';
const onDragMove$4 = Symbol('onDragMove');
const onDragStop$7 = Symbol('onDragStop');
const onRequestAnimationFrame = Symbol('onRequestAnimationFrame');
class Collidable extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.currentlyCollidingElement = null;
this.lastCollidingElement = null;
this.currentAnimationFrame = null;
this[onDragMove$4] = this[onDragMove$4].bind(this);
this[onDragStop$7] = this[onDragStop$7].bind(this);
this[onRequestAnimationFrame] = this[onRequestAnimationFrame].bind(this);
}
attach() {
this.draggable.on('drag:move', this[onDragMove$4]).on('drag:stop', this[onDragStop$7]);
}
detach() {
this.draggable.off('drag:move', this[onDragMove$4]).off('drag:stop', this[onDragStop$7]);
}
getCollidables() {
const collidables = this.draggable.options.collidables;
if (typeof collidables === 'string') {
return Array.prototype.slice.call(document.querySelectorAll(collidables));
} else if (collidables instanceof NodeList || collidables instanceof Array) {
return Array.prototype.slice.call(collidables);
} else if (collidables instanceof HTMLElement) {
return [collidables];
} else if (typeof collidables === 'function') {
return collidables();
} else {
return [];
}
}
[onDragMove$4](event) {
const target = event.sensorEvent.target;
this.currentAnimationFrame = requestAnimationFrame(this[onRequestAnimationFrame](target));
if (this.currentlyCollidingElement) {
event.cancel();
}
const collidableInEvent = new CollidableInEvent({
dragEvent: event,
collidingElement: this.currentlyCollidingElement
});
const collidableOutEvent = new CollidableOutEvent({
dragEvent: event,
collidingElement: this.lastCollidingElement
});
const enteringCollidable = Boolean(this.currentlyCollidingElement && this.lastCollidingElement !== this.currentlyCollidingElement);
const leavingCollidable = Boolean(!this.currentlyCollidingElement && this.lastCollidingElement);
if (enteringCollidable) {
if (this.lastCollidingElement) {
this.draggable.trigger(collidableOutEvent);
}
this.draggable.trigger(collidableInEvent);
} else if (leavingCollidable) {
this.draggable.trigger(collidableOutEvent);
}
this.lastCollidingElement = this.currentlyCollidingElement;
}
[onDragStop$7](event) {
const lastCollidingElement = this.currentlyCollidingElement || this.lastCollidingElement;
const collidableOutEvent = new CollidableOutEvent({
dragEvent: event,
collidingElement: lastCollidingElement
});
if (lastCollidingElement) {
this.draggable.trigger(collidableOutEvent);
}
this.lastCollidingElement = null;
this.currentlyCollidingElement = null;
}
[onRequestAnimationFrame](target) {
return () => {
const collidables = this.getCollidables();
this.currentlyCollidingElement = closest(target, element => collidables.includes(element));
};
}
}
function createAddInitializerMethod(e, t) {
return function (r) {
assertNotFinished(t, "addInitializer"), assertCallable(r, "An initializer"), e.push(r);
};
}
function assertInstanceIfPrivate(e, t) {
if (!e(t)) throw new TypeError("Attempted to access private element on non-instance");
}
function memberDec(e, t, r, a, n, i, s, o, c, l, u) {
var f;
switch (i) {
case 1:
f = "accessor";
break;
case 2:
f = "method";
break;
case 3:
f = "getter";
break;
case 4:
f = "setter";
break;
default:
f = "field";
}
var d,
p,
h = {
kind: f,
name: o ? "#" + r : r,
static: s,
private: o,
metadata: u
},
v = {
v: !1
};
if (0 !== i && (h.addInitializer = createAddInitializerMethod(n, v)), o || 0 !== i && 2 !== i) {
if (2 === i) d = function (e) {
return assertInstanceIfPrivate(l, e), a.value;
};else {
var y = 0 === i || 1 === i;
(y || 3 === i) && (d = o ? function (e) {
return assertInstanceIfPrivate(l, e), a.get.call(e);
} : function (e) {
return a.get.call(e);
}), (y || 4 === i) && (p = o ? function (e, t) {
assertInstanceIfPrivate(l, e), a.set.call(e, t);
} : function (e, t) {
a.set.call(e, t);
});
}
} else d = function (e) {
return e[r];
}, 0 === i && (p = function (e, t) {
e[r] = t;
});
var m = o ? l.bind() : function (e) {
return r in e;
};
h.access = d && p ? {
get: d,
set: p,
has: m
} : d ? {
get: d,
has: m
} : {
set: p,
has: m
};
try {
return e.call(t, c, h);
} finally {
v.v = !0;
}
}
function assertNotFinished(e, t) {
if (e.v) throw new Error("attempted to call " + t + " after decoration was finished");
}
function assertCallable(e, t) {
if ("function" != typeof e) throw new TypeError(t + " must be a function");
}
function assertValidReturnValue(e, t) {
var r = typeof t;
if (1 === e) {
if ("object" !== r || null === t) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
void 0 !== t.get && assertCallable(t.get, "accessor.get"), void 0 !== t.set && assertCallable(t.set, "accessor.set"), void 0 !== t.init && assertCallable(t.init, "accessor.init");
} else if ("function" !== r) {
var a;
throw a = 0 === e ? "field" : 5 === e ? "class" : "method", new TypeError(a + " decorators must return a function or void 0");
}
}
function curryThis1(e) {
return function () {
return e(this);
};
}
function curryThis2(e) {
return function (t) {
e(this, t);
};
}
function applyMemberDec(e, t, r, a, n, i, s, o, c, l, u) {
var f,
d,
p,
h,
v,
y,
m = r[0];
a || Array.isArray(m) || (m = [m]), o ? f = 0 === i || 1 === i ? {
get: curryThis1(r[3]),
set: curryThis2(r[4])
} : 3 === i ? {
get: r[3]
} : 4 === i ? {
set: r[3]
} : {
value: r[3]
} : 0 !== i && (f = Object.getOwnPropertyDescriptor(t, n)), 1 === i ? p = {
get: f.get,
set: f.set
} : 2 === i ? p = f.value : 3 === i ? p = f.get : 4 === i && (p = f.set);
for (var g = a ? 2 : 1, b = m.length - 1; b >= 0; b -= g) {
var I;
if (void 0 !== (h = memberDec(m[b], a ? m[b - 1] : void 0, n, f, c, i, s, o, p, l, u))) assertValidReturnValue(i, h), 0 === i ? I = h : 1 === i ? (I = h.init, v = h.get || p.get, y = h.set || p.set, p = {
get: v,
set: y
}) : p = h, void 0 !== I && (void 0 === d ? d = I : "function" == typeof d ? d = [d, I] : d.push(I));
}
if (0 === i || 1 === i) {
if (void 0 === d) d = function (e, t) {
return t;
};else if ("function" != typeof d) {
var w = d;
d = function (e, t) {
for (var r = t, a = w.length - 1; a >= 0; a--) r = w[a].call(e, r);
return r;
};
} else {
var M = d;
d = function (e, t) {
return M.call(e, t);
};
}
e.push(d);
}
0 !== i && (1 === i ? (f.get = p.get, f.set = p.set) : 2 === i ? f.value = p : 3 === i ? f.get = p : 4 === i && (f.set = p), o ? 1 === i ? (e.push(function (e, t) {
return p.get.call(e, t);
}), e.push(function (e, t) {
return p.set.call(e, t);
})) : 2 === i ? e.push(p) : e.push(function (e, t) {
return p.call(e, t);
}) : Object.defineProperty(t, n, f));
}
function applyMemberDecs(e, t, r, a) {
for (var n, i, s, o = [], c = new Map(), l = new Map(), u = 0; u < t.length; u++) {
var f = t[u];
if (Array.isArray(f)) {
var d,
p,
h = f[1],
v = f[2],
y = f.length > 3,
m = 16 & h,
g = !!(8 & h),
b = r;
if (h &= 7, g ? (d = e, 0 !== h && (p = i = i || []), y && !s && (s = function (t) {
return _checkInRHS(t) === e;
}), b = s) : (d = e.prototype, 0 !== h && (p = n = n || [])), 0 !== h && !y) {
var I = g ? l : c,
w = I.get(v) || 0;
if (!0 === w || 3 === w && 4 !== h || 4 === w && 3 !== h) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + v);
I.set(v, !(!w && h > 2) || h);
}
applyMemberDec(o, d, f, m, v, h, g, y, p, b, a);
}
}
return pushInitializers(o, n), pushInitializers(o, i), o;
}
function pushInitializers(e, t) {
t && e.push(function (e) {
for (var r = 0; r < t.length; r++) t[r].call(e);
return e;
});
}
function applyClassDecs(e, t, r, a) {
if (t.length) {
for (var n = [], i = e, s = e.name, o = r ? 2 : 1, c = t.length - 1; c >= 0; c -= o) {
var l = {
v: !1
};
try {
var u = t[c].call(r ? t[c - 1] : void 0, i, {
kind: "class",
name: s,
addInitializer: createAddInitializerMethod(n, l),
metadata: a
});
} finally {
l.v = !0;
}
void 0 !== u && (assertValidReturnValue(5, u), i = u);
}
return [defineMetadata(i, a), function () {
for (var e = 0; e < n.length; e++) n[e].call(i);
}];
}
}
function defineMetadata(e, t) {
return Object.defineProperty(e, Symbol.metadata || Symbol.for("Symbol.metadata"), {
configurable: !0,
enumerable: !0,
value: t
});
}
function _applyDecs2305(e, t, r, a, n, i) {
if (arguments.length >= 6) var s = i[Symbol.metadata || Symbol.for("Symbol.metadata")];
var o = Object.create(void 0 === s ? null : s),
c = applyMemberDecs(e, t, n, o);
return r.length || defineMetadata(e, o), {
e: c,
get c() {
return applyClassDecs(e, r, a, o);
}
};
}
function _checkInRHS(e) {
if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
return e;
}
class DragEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get source() {
return this.data.source;
}
get originalSource() {
return this.data.originalSource;
}
get mirror() {
return this.data.mirror;
}
get sourceContainer() {
return this.data.sourceContainer;
}
get sensorEvent() {
return this.data.sensorEvent;
}
get originalEvent() {
if (this.sensorEvent) {
return this.sensorEvent.originalEvent;
}
return null;
}
}
DragEvent.type = 'drag';
class DragStartEvent extends DragEvent {}
DragStartEvent.type = 'drag:start';
DragStartEvent.cancelable = true;
class DragMoveEvent extends DragEvent {}
DragMoveEvent.type = 'drag:move';
class DragOverEvent extends DragEvent {
get overContainer() {
return this.data.overContainer;
}
get over() {
return this.data.over;
}
}
DragOverEvent.type = 'drag:over';
DragOverEvent.cancelable = true;
function isDragOverEvent(event) {
return event.type === DragOverEvent.type;
}
class DragOutEvent extends DragEvent {
get overContainer() {
return this.data.overContainer;
}
get over() {
return this.data.over;
}
}
DragOutEvent.type = 'drag:out';
class DragOverContainerEvent extends DragEvent {
get overContainer() {
return this.data.overContainer;
}
}
DragOverContainerEvent.type = 'drag:over:container';
class DragOutContainerEvent extends DragEvent {
get overContainer() {
return this.data.overContainer;
}
}
DragOutContainerEvent.type = 'drag:out:container';
class DragPressureEvent extends DragEvent {
get pressure() {
return this.data.pressure;
}
}
DragPressureEvent.type = 'drag:pressure';
class DragStopEvent extends DragEvent {}
DragStopEvent.type = 'drag:stop';
DragStopEvent.cancelable = true;
class DragStoppedEvent extends DragEvent {}
DragStoppedEvent.type = 'drag:stopped';
var _initProto$1, _class$1;
const defaultOptions$8 = {};
class ResizeMirror extends AbstractPlugin {
constructor(draggable) {
_initProto$1(super(draggable));
this.lastWidth = 0;
this.lastHeight = 0;
this.mirror = null;
}
attach() {
this.draggable.on('mirror:created', this.onMirrorCreated).on('drag:over', this.onDragOver).on('drag:over:container', this.onDragOver);
}
detach() {
this.draggable.off('mirror:created', this.onMirrorCreated).off('mirror:destroy', this.onMirrorDestroy).off('drag:over', this.onDragOver).off('drag:over:container', this.onDragOver);
}
getOptions() {
return this.draggable.options.resizeMirror || {};
}
onMirrorCreated({
mirror
}) {
this.mirror = mirror;
}
onMirrorDestroy() {
this.mirror = null;
}
onDragOver(dragEvent) {
this.resize(dragEvent);
}
resize(dragEvent) {
requestAnimationFrame(() => {
let over = null;
const {
overContainer
} = dragEvent;
if (this.mirror == null || this.mirror.parentNode == null) {
return;
}
if (this.mirror.parentNode !== overContainer) {
overContainer.appendChild(this.mirror);
}
if (isDragOverEvent(dragEvent)) {
over = dragEvent.over;
}
const overElement = over || this.draggable.getDraggableElementsForContainer(overContainer)[0];
if (!overElement) {
return;
}
requestNextAnimationFrame(() => {
const overRect = overElement.getBoundingClientRect();
if (this.mirror == null || this.lastHeight === overRect.height && this.lastWidth === overRect.width) {
return;
}
this.mirror.style.width = `${overRect.width}px`;
this.mirror.style.height = `${overRect.height}px`;
this.lastWidth = overRect.width;
this.lastHeight = overRect.height;
});
});
}
}
_class$1 = ResizeMirror;
[_initProto$1] = _applyDecs2305(_class$1, [[AutoBind, 2, "onMirrorCreated"], [AutoBind, 2, "onMirrorDestroy"], [AutoBind, 2, "onDragOver"]], [], 0, void 0, AbstractPlugin).e;
class SnapEvent extends AbstractEvent {
get dragEvent() {
return this.data.dragEvent;
}
get snappable() {
return this.data.snappable;
}
}
SnapEvent.type = 'snap';
class SnapInEvent extends SnapEvent {}
SnapInEvent.type = 'snap:in';
SnapInEvent.cancelable = true;
class SnapOutEvent extends SnapEvent {}
SnapOutEvent.type = 'snap:out';
SnapOutEvent.cancelable = true;
const onDragStart$6 = Symbol('onDragStart');
const onDragStop$6 = Symbol('onDragStop');
const onDragOver$2 = Symbol('onDragOver');
const onDragOut = Symbol('onDragOut');
const onMirrorCreated$1 = Symbol('onMirrorCreated');
const onMirrorDestroy = Symbol('onMirrorDestroy');
class Snappable extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.firstSource = null;
this.mirror = null;
this[onDragStart$6] = this[onDragStart$6].bind(this);
this[onDragStop$6] = this[onDragStop$6].bind(this);
this[onDragOver$2] = this[onDragOver$2].bind(this);
this[onDragOut] = this[onDragOut].bind(this);
this[onMirrorCreated$1] = this[onMirrorCreated$1].bind(this);
this[onMirrorDestroy] = this[onMirrorDestroy].bind(this);
}
attach() {
this.draggable.on('drag:start', this[onDragStart$6]).on('drag:stop', this[onDragStop$6]).on('drag:over', this[onDragOver$2]).on('drag:out', this[onDragOut]).on('droppable:over', this[onDragOver$2]).on('droppable:out', this[onDragOut]).on('mirror:created', this[onMirrorCreated$1]).on('mirror:destroy', this[onMirrorDestroy]);
}
detach() {
this.draggable.off('drag:start', this[onDragStart$6]).off('drag:stop', this[onDragStop$6]).off('drag:over', this[onDragOver$2]).off('drag:out', this[onDragOut]).off('droppable:over', this[onDragOver$2]).off('droppable:out', this[onDragOut]).off('mirror:created', this[onMirrorCreated$1]).off('mirror:destroy', this[onMirrorDestroy]);
}
[onDragStart$6](event) {
if (event.canceled()) {
return;
}
this.firstSource = event.source;
}
[onDragStop$6]() {
this.firstSource = null;
}
[onDragOver$2](event) {
if (event.canceled()) {
return;
}
const source = event.source || event.dragEvent.source;
if (source === this.firstSource) {
this.firstSource = null;
return;
}
const snapInEvent = new SnapInEvent({
dragEvent: event,
snappable: event.over || event.droppable
});
this.draggable.trigger(snapInEvent);
if (snapInEvent.canceled()) {
return;
}
if (this.mirror) {
this.mirror.style.display = 'none';
}
source.classList.remove(...this.draggable.getClassNamesFor('source:dragging'));
source.classList.add(...this.draggable.getClassNamesFor('source:placed'));
setTimeout(() => {
source.classList.remove(...this.draggable.getClassNamesFor('source:placed'));
}, this.draggable.options.placedTimeout);
}
[onDragOut](event) {
if (event.canceled()) {
return;
}
const source = event.source || event.dragEvent.source;
const snapOutEvent = new SnapOutEvent({
dragEvent: event,
snappable: event.over || event.droppable
});
this.draggable.trigger(snapOutEvent);
if (snapOutEvent.canceled()) {
return;
}
if (this.mirror) {
this.mirror.style.display = '';
}
source.classList.add(...this.draggable.getClassNamesFor('source:dragging'));
}
[onMirrorCreated$1]({
mirror
}) {
this.mirror = mirror;
}
[onMirrorDestroy]() {
this.mirror = null;
}
}
var _initProto, _class;
const defaultOptions$7 = {
duration: 150,
easingFunction: 'ease-in-out',
horizontal: false
};
class SwapAnimation extends AbstractPlugin {
constructor(draggable) {
_initProto(super(draggable));
this.options = {
...defaultOptions$7,
...this.getOptions()
};
this.lastAnimationFrame = null;
}
attach() {
this.draggable.on('sortable:sorted', this.onSortableSorted);
}
detach() {
this.draggable.off('sortable:sorted', this.onSortableSorted);
}
getOptions() {
return this.draggable.options.swapAnimation || {};
}
onSortableSorted({
oldIndex,
newIndex,
dragEvent
}) {
const {
source,
over
} = dragEvent;
if (this.lastAnimationFrame) {
cancelAnimationFrame(this.lastAnimationFrame);
}
this.lastAnimationFrame = requestAnimationFrame(() => {
if (oldIndex >= newIndex) {
animate$1(source, over, this.options);
} else {
animate$1(over, source, this.options);
}
});
}
}
_class = SwapAnimation;
[_initProto] = _applyDecs2305(_class, [[AutoBind, 2, "onSortableSorted"]], [], 0, void 0, AbstractPlugin).e;
function animate$1(from, to, {
duration,
easingFunction,
horizontal
}) {
for (const element of [from, to]) {
element.style.pointerEvents = 'none';
}
if (horizontal) {
const width = from.offsetWidth;
from.style.transform = `translate3d(${width}px, 0, 0)`;
to.style.transform = `translate3d(-${width}px, 0, 0)`;
} else {
const height = from.offsetHeight;
from.style.transform = `translate3d(0, ${height}px, 0)`;
to.style.transform = `translate3d(0, -${height}px, 0)`;
}
requestAnimationFrame(() => {
for (const element of [from, to]) {
element.addEventListener('transitionend', resetElementOnTransitionEnd$1);
element.style.transition = `transform ${duration}ms ${easingFunction}`;
element.style.transform = '';
}
});
}
function resetElementOnTransitionEnd$1(event) {
if (event.target == null || !isHTMLElement(event.target)) {
return;
}
event.target.style.transition = '';
event.target.style.pointerEvents = '';
event.target.removeEventListener('transitionend', resetElementOnTransitionEnd$1);
}
function isHTMLElement(eventTarget) {
return Boolean('style' in eventTarget);
}
const onSortableSorted = Symbol('onSortableSorted');
const onSortableSort = Symbol('onSortableSort');
const defaultOptions$6 = {
duration: 150,
easingFunction: 'ease-in-out'
};
class SortAnimation extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.options = {
...defaultOptions$6,
...this.getOptions()
};
this.lastAnimationFrame = null;
this.lastElements = [];
this[onSortableSorted] = this[onSortableSorted].bind(this);
this[onSortableSort] = this[onSortableSort].bind(this);
}
attach() {
this.draggable.on('sortable:sort', this[onSortableSort]);
this.draggable.on('sortable:sorted', this[onSortableSorted]);
}
detach() {
this.draggable.off('sortable:sort', this[onSortableSort]);
this.draggable.off('sortable:sorted', this[onSortableSorted]);
}
getOptions() {
return this.draggable.options.sortAnimation || {};
}
[onSortableSort]({
dragEvent
}) {
const {
sourceContainer
} = dragEvent;
const elements = this.draggable.getDraggableElementsForContainer(sourceContainer);
this.lastElements = Array.from(elements).map(el => {
return {
domEl: el,
offsetTop: el.offsetTop,
offsetLeft: el.offsetLeft
};
});
}
[onSortableSorted]({
oldIndex,
newIndex
}) {
if (oldIndex === newIndex) {
return;
}
const effectedElements = [];
let start;
let end;
let num;
if (oldIndex > newIndex) {
start = newIndex;
end = oldIndex - 1;
num = 1;
} else {
start = oldIndex + 1;
end = newIndex;
num = -1;
}
for (let i = start; i <= end; i++) {
const from = this.lastElements[i];
const to = this.lastElements[i + num];
effectedElements.push({
from,
to
});
}
cancelAnimationFrame(this.lastAnimationFrame);
this.lastAnimationFrame = requestAnimationFrame(() => {
effectedElements.forEach(element => animate(element, this.options));
});
}
}
function animate({
from,
to
}, {
duration,
easingFunction
}) {
const domEl = from.domEl;
const x = from.offsetLeft - to.offsetLeft;
const y = from.offsetTop - to.offsetTop;
domEl.style.pointerEvents = 'none';
domEl.style.transform = `translate3d(${x}px, ${y}px, 0)`;
requestAnimationFrame(() => {
domEl.addEventListener('transitionend', resetElementOnTransitionEnd);
domEl.style.transition = `transform ${duration}ms ${easingFunction}`;
domEl.style.transform = '';
});
}
function resetElementOnTransitionEnd(event) {
event.target.style.transition = '';
event.target.style.pointerEvents = '';
event.target.removeEventListener('transitionend', resetElementOnTransitionEnd);
}
var index$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
Collidable: Collidable,
ResizeMirror: ResizeMirror,
Snappable: Snappable,
SortAnimation: SortAnimation,
SwapAnimation: SwapAnimation,
defaultResizeMirrorOptions: defaultOptions$8,
defaultSortAnimationOptions: defaultOptions$6,
defaultSwapAnimationOptions: defaultOptions$7
});
const onInitialize$1 = Symbol('onInitialize');
const onDestroy$1 = Symbol('onDestroy');
const announceEvent = Symbol('announceEvent');
const announceMessage = Symbol('announceMessage');
const ARIA_RELEVANT = 'aria-relevant';
const ARIA_ATOMIC = 'aria-atomic';
const ARIA_LIVE = 'aria-live';
const ROLE = 'role';
const defaultOptions$5 = {
expire: 7000
};
class Announcement extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.options = {
...defaultOptions$5,
...this.getOptions()
};
this.originalTriggerMethod = this.draggable.trigger;
this[onInitialize$1] = this[onInitialize$1].bind(this);
this[onDestroy$1] = this[onDestroy$1].bind(this);
}
attach() {
this.draggable.on('draggable:initialize', this[onInitialize$1]);
}
detach() {
this.draggable.off('draggable:destroy', this[onDestroy$1]);
}
getOptions() {
return this.draggable.options.announcements || {};
}
[announceEvent](event) {
const message = this.options[event.type];
if (message && typeof message === 'string') {
this[announceMessage](message);
}
if (message && typeof message === 'function') {
this[announceMessage](message(event));
}
}
[announceMessage](message) {
announce(message, {
expire: this.options.expire
});
}
[onInitialize$1]() {
this.draggable.trigger = event => {
try {
this[announceEvent](event);
} finally {
this.originalTriggerMethod.call(this.draggable, event);
}
};
}
[onDestroy$1]() {
this.draggable.trigger = this.originalTriggerMethod;
}
}
const liveRegion = createRegion();
function announce(message, {
expire
}) {
const element = document.createElement('div');
element.textContent = message;
liveRegion.appendChild(element);
return setTimeout(() => {
liveRegion.removeChild(element);
}, expire);
}
function createRegion() {
const element = document.createElement('div');
element.setAttribute('id', 'draggable-live-region');
element.setAttribute(ARIA_RELEVANT, 'additions');
element.setAttribute(ARIA_ATOMIC, 'true');
element.setAttribute(ARIA_LIVE, 'assertive');
element.setAttribute(ROLE, 'log');
element.style.position = 'fixed';
element.style.width = '1px';
element.style.height = '1px';
element.style.top = '-1px';
element.style.overflow = 'hidden';
return element;
}
document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(liveRegion);
});
const onInitialize = Symbol('onInitialize');
const onDestroy = Symbol('onDestroy');
const defaultOptions$4 = {};
class Focusable extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.options = {
...defaultOptions$4,
...this.getOptions()
};
this[onInitialize] = this[onInitialize].bind(this);
this[onDestroy] = this[onDestroy].bind(this);
}
attach() {
this.draggable.on('draggable:initialize', this[onInitialize]).on('draggable:destroy', this[onDestroy]);
}
detach() {
this.draggable.off('draggable:initialize', this[onInitialize]).off('draggable:destroy', this[onDestroy]);
this[onDestroy]();
}
getOptions() {
return this.draggable.options.focusable || {};
}
getElements() {
return [...this.draggable.containers, ...this.draggable.getDraggableElements()];
}
[onInitialize]() {
requestAnimationFrame(() => {
this.getElements().forEach(element => decorateElement(element));
});
}
[onDestroy]() {
requestAnimationFrame(() => {
this.getElements().forEach(element => stripElement(element));
});
}
}
const elementsWithMissingTabIndex = [];
function decorateElement(element) {
const hasMissingTabIndex = Boolean(!element.getAttribute('tabindex') && element.tabIndex === -1);
if (hasMissingTabIndex) {
elementsWithMissingTabIndex.push(element);
element.tabIndex = 0;
}
}
function stripElement(element) {
const tabIndexElementPosition = elementsWithMissingTabIndex.indexOf(element);
if (tabIndexElementPosition !== -1) {
element.tabIndex = -1;
elementsWithMissingTabIndex.splice(tabIndexElementPosition, 1);
}
}
class MirrorEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get source() {
return this.data.source;
}
get originalSource() {
return this.data.originalSource;
}
get sourceContainer() {
return this.data.sourceContainer;
}
get sensorEvent() {
return this.data.sensorEvent;
}
get dragEvent() {
return this.data.dragEvent;
}
get originalEvent() {
if (this.sensorEvent) {
return this.sensorEvent.originalEvent;
}
return null;
}
}
class MirrorCreateEvent extends MirrorEvent {}
MirrorCreateEvent.type = 'mirror:create';
class MirrorCreatedEvent extends MirrorEvent {
get mirror() {
return this.data.mirror;
}
}
MirrorCreatedEvent.type = 'mirror:created';
class MirrorAttachedEvent extends MirrorEvent {
get mirror() {
return this.data.mirror;
}
}
MirrorAttachedEvent.type = 'mirror:attached';
class MirrorMoveEvent extends MirrorEvent {
get mirror() {
return this.data.mirror;
}
get passedThreshX() {
return this.data.passedThreshX;
}
get passedThreshY() {
return this.data.passedThreshY;
}
}
MirrorMoveEvent.type = 'mirror:move';
MirrorMoveEvent.cancelable = true;
class MirrorMovedEvent extends MirrorEvent {
get mirror() {
return this.data.mirror;
}
get passedThreshX() {
return this.data.passedThreshX;
}
get passedThreshY() {
return this.data.passedThreshY;
}
}
MirrorMovedEvent.type = 'mirror:moved';
class MirrorDestroyEvent extends MirrorEvent {
get mirror() {
return this.data.mirror;
}
}
MirrorDestroyEvent.type = 'mirror:destroy';
MirrorDestroyEvent.cancelable = true;
const onDragStart$5 = Symbol('onDragStart');
const onDragMove$3 = Symbol('onDragMove');
const onDragStop$5 = Symbol('onDragStop');
const onMirrorCreated = Symbol('onMirrorCreated');
const onMirrorMove = Symbol('onMirrorMove');
const onScroll = Symbol('onScroll');
const getAppendableContainer = Symbol('getAppendableContainer');
const defaultOptions$3 = {
constrainDimensions: false,
xAxis: true,
yAxis: true,
cursorOffsetX: null,
cursorOffsetY: null,
thresholdX: null,
thresholdY: null
};
class Mirror extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.options = {
...defaultOptions$3,
...this.getOptions()
};
this.scrollOffset = {
x: 0,
y: 0
};
this.initialScrollOffset = {
x: window.scrollX,
y: window.scrollY
};
this[onDragStart$5] = this[onDragStart$5].bind(this);
this[onDragMove$3] = this[onDragMove$3].bind(this);
this[onDragStop$5] = this[onDragStop$5].bind(this);
this[onMirrorCreated] = this[onMirrorCreated].bind(this);
this[onMirrorMove] = this[onMirrorMove].bind(this);
this[onScroll] = this[onScroll].bind(this);
}
attach() {
this.draggable.on('drag:start', this[onDragStart$5]).on('drag:move', this[onDragMove$3]).on('drag:stop', this[onDragStop$5]).on('mirror:created', this[onMirrorCreated]).on('mirror:move', this[onMirrorMove]);
}
detach() {
this.draggable.off('drag:start', this[onDragStart$5]).off('drag:move', this[onDragMove$3]).off('drag:stop', this[onDragStop$5]).off('mirror:created', this[onMirrorCreated]).off('mirror:move', this[onMirrorMove]);
}
getOptions() {
return this.draggable.options.mirror || {};
}
[onDragStart$5](dragEvent) {
if (dragEvent.canceled()) {
return;
}
if ('ontouchstart' in window) {
document.addEventListener('scroll', this[onScroll], true);
}
this.initialScrollOffset = {
x: window.scrollX,
y: window.scrollY
};
const {
source,
originalSource,
sourceContainer,
sensorEvent
} = dragEvent;
this.lastMirrorMovedClient = {
x: sensorEvent.clientX,
y: sensorEvent.clientY
};
const mirrorCreateEvent = new MirrorCreateEvent({
source,
originalSource,
sourceContainer,
sensorEvent,
dragEvent
});
this.draggable.trigger(mirrorCreateEvent);
if (isNativeDragEvent(sensorEvent) || mirrorCreateEvent.canceled()) {
return;
}
const appendableContainer = this[getAppendableContainer](source) || sourceContainer;
this.mirror = source.cloneNode(true);
const mirrorCreatedEvent = new MirrorCreatedEvent({
source,
originalSource,
sourceContainer,
sensorEvent,
dragEvent,
mirror: this.mirror
});
const mirrorAttachedEvent = new MirrorAttachedEvent({
source,
originalSource,
sourceContainer,
sensorEvent,
dragEvent,
mirror: this.mirror
});
this.draggable.trigger(mirrorCreatedEvent);
appendableContainer.appendChild(this.mirror);
this.draggable.trigger(mirrorAttachedEvent);
}
[onDragMove$3](dragEvent) {
if (!this.mirror || dragEvent.canceled()) {
return;
}
const {
source,
originalSource,
sourceContainer,
sensorEvent
} = dragEvent;
let passedThreshX = true;
let passedThreshY = true;
if (this.options.thresholdX || this.options.thresholdY) {
const {
x: lastX,
y: lastY
} = this.lastMirrorMovedClient;
if (Math.abs(lastX - sensorEvent.clientX) < this.options.thresholdX) {
passedThreshX = false;
} else {
this.lastMirrorMovedClient.x = sensorEvent.clientX;
}
if (Math.abs(lastY - sensorEvent.clientY) < this.options.thresholdY) {
passedThreshY = false;
} else {
this.lastMirrorMovedClient.y = sensorEvent.clientY;
}
if (!passedThreshX && !passedThreshY) {
return;
}
}
const mirrorMoveEvent = new MirrorMoveEvent({
source,
originalSource,
sourceContainer,
sensorEvent,
dragEvent,
mirror: this.mirror,
passedThreshX,
passedThreshY
});
this.draggable.trigger(mirrorMoveEvent);
}
[onDragStop$5](dragEvent) {
if ('ontouchstart' in window) {
document.removeEventListener('scroll', this[onScroll], true);
}
this.initialScrollOffset = {
x: 0,
y: 0
};
this.scrollOffset = {
x: 0,
y: 0
};
if (!this.mirror) {
return;
}
const {
source,
sourceContainer,
sensorEvent
} = dragEvent;
const mirrorDestroyEvent = new MirrorDestroyEvent({
source,
mirror: this.mirror,
sourceContainer,
sensorEvent,
dragEvent
});
this.draggable.trigger(mirrorDestroyEvent);
if (!mirrorDestroyEvent.canceled()) {
this.mirror.remove();
}
}
[onScroll]() {
this.scrollOffset = {
x: window.scrollX - this.initialScrollOffset.x,
y: window.scrollY - this.initialScrollOffset.y
};
}
[onMirrorCreated]({
mirror,
source,
sensorEvent
}) {
const mirrorClasses = this.draggable.getClassNamesFor('mirror');
const setState = ({
mirrorOffset,
initialX,
initialY,
...args
}) => {
this.mirrorOffset = mirrorOffset;
this.initialX = initialX;
this.initialY = initialY;
this.lastMovedX = initialX;
this.lastMovedY = initialY;
return {
mirrorOffset,
initialX,
initialY,
...args
};
};
mirror.style.display = 'none';
const initialState = {
mirror,
source,
sensorEvent,
mirrorClasses,
scrollOffset: this.scrollOffset,
options: this.options,
passedThreshX: true,
passedThreshY: true
};
return Promise.resolve(initialState)
.then(computeMirrorDimensions).then(calculateMirrorOffset).then(resetMirror).then(addMirrorClasses).then(positionMirror({
initial: true
})).then(removeMirrorID).then(setState);
}
[onMirrorMove](mirrorEvent) {
if (mirrorEvent.canceled()) {
return null;
}
const setState = ({
lastMovedX,
lastMovedY,
...args
}) => {
this.lastMovedX = lastMovedX;
this.lastMovedY = lastMovedY;
return {
lastMovedX,
lastMovedY,
...args
};
};
const triggerMoved = args => {
const mirrorMovedEvent = new MirrorMovedEvent({
source: mirrorEvent.source,
originalSource: mirrorEvent.originalSource,
sourceContainer: mirrorEvent.sourceContainer,
sensorEvent: mirrorEvent.sensorEvent,
dragEvent: mirrorEvent.dragEvent,
mirror: this.mirror,
passedThreshX: mirrorEvent.passedThreshX,
passedThreshY: mirrorEvent.passedThreshY
});
this.draggable.trigger(mirrorMovedEvent);
return args;
};
const initialState = {
mirror: mirrorEvent.mirror,
sensorEvent: mirrorEvent.sensorEvent,
mirrorOffset: this.mirrorOffset,
options: this.options,
initialX: this.initialX,
initialY: this.initialY,
scrollOffset: this.scrollOffset,
passedThreshX: mirrorEvent.passedThreshX,
passedThreshY: mirrorEvent.passedThreshY,
lastMovedX: this.lastMovedX,
lastMovedY: this.lastMovedY
};
return Promise.resolve(initialState).then(positionMirror({
raf: true
})).then(setState).then(triggerMoved);
}
[getAppendableContainer](source) {
const appendTo = this.options.appendTo;
if (typeof appendTo === 'string') {
return document.querySelector(appendTo);
} else if (appendTo instanceof HTMLElement) {
return appendTo;
} else if (typeof appendTo === 'function') {
return appendTo(source);
} else {
return source.parentNode;
}
}
}
function computeMirrorDimensions({
source,
...args
}) {
return withPromise(resolve => {
const sourceRect = source.getBoundingClientRect();
resolve({
source,
sourceRect,
...args
});
});
}
function calculateMirrorOffset({
sensorEvent,
sourceRect,
options,
...args
}) {
return withPromise(resolve => {
const top = options.cursorOffsetY === null ? sensorEvent.clientY - sourceRect.top : options.cursorOffsetY;
const left = options.cursorOffsetX === null ? sensorEvent.clientX - sourceRect.left : options.cursorOffsetX;
const mirrorOffset = {
top,
left
};
resolve({
sensorEvent,
sourceRect,
mirrorOffset,
options,
...args
});
});
}
function resetMirror({
mirror,
source,
options,
...args
}) {
return withPromise(resolve => {
let offsetHeight;
let offsetWidth;
if (options.constrainDimensions) {
const computedSourceStyles = getComputedStyle(source);
offsetHeight = computedSourceStyles.getPropertyValue('height');
offsetWidth = computedSourceStyles.getPropertyValue('width');
}
mirror.style.display = null;
mirror.style.position = 'fixed';
mirror.style.pointerEvents = 'none';
mirror.style.top = 0;
mirror.style.left = 0;
mirror.style.margin = 0;
if (options.constrainDimensions) {
mirror.style.height = offsetHeight;
mirror.style.width = offsetWidth;
}
resolve({
mirror,
source,
options,
...args
});
});
}
function addMirrorClasses({
mirror,
mirrorClasses,
...args
}) {
return withPromise(resolve => {
mirror.classList.add(...mirrorClasses);
resolve({
mirror,
mirrorClasses,
...args
});
});
}
function removeMirrorID({
mirror,
...args
}) {
return withPromise(resolve => {
mirror.removeAttribute('id');
delete mirror.id;
resolve({
mirror,
...args
});
});
}
function positionMirror({
withFrame = false,
initial = false
} = {}) {
return ({
mirror,
sensorEvent,
mirrorOffset,
initialY,
initialX,
scrollOffset,
options,
passedThreshX,
passedThreshY,
lastMovedX,
lastMovedY,
...args
}) => {
return withPromise(resolve => {
const result = {
mirror,
sensorEvent,
mirrorOffset,
options,
...args
};
if (mirrorOffset) {
const x = passedThreshX ? Math.round((sensorEvent.clientX - mirrorOffset.left - scrollOffset.x) / (options.thresholdX || 1)) * (options.thresholdX || 1) : Math.round(lastMovedX);
const y = passedThreshY ? Math.round((sensorEvent.clientY - mirrorOffset.top - scrollOffset.y) / (options.thresholdY || 1)) * (options.thresholdY || 1) : Math.round(lastMovedY);
if (options.xAxis && options.yAxis || initial) {
mirror.style.transform = `translate3d(${x}px, ${y}px, 0)`;
} else if (options.xAxis && !options.yAxis) {
mirror.style.transform = `translate3d(${x}px, ${initialY}px, 0)`;
} else if (options.yAxis && !options.xAxis) {
mirror.style.transform = `translate3d(${initialX}px, ${y}px, 0)`;
}
if (initial) {
result.initialX = x;
result.initialY = y;
}
result.lastMovedX = x;
result.lastMovedY = y;
}
resolve(result);
}, {
frame: withFrame
});
};
}
function withPromise(callback, {
raf = false
} = {}) {
return new Promise((resolve, reject) => {
if (raf) {
requestAnimationFrame(() => {
callback(resolve, reject);
});
} else {
callback(resolve, reject);
}
});
}
function isNativeDragEvent(sensorEvent) {
return /^drag/.test(sensorEvent.originalEvent.type);
}
const onDragStart$4 = Symbol('onDragStart');
const onDragMove$2 = Symbol('onDragMove');
const onDragStop$4 = Symbol('onDragStop');
const scroll = Symbol('scroll');
const defaultOptions$2 = {
speed: 6,
sensitivity: 50,
scrollableElements: []
};
class Scrollable extends AbstractPlugin {
constructor(draggable) {
super(draggable);
this.options = {
...defaultOptions$2,
...this.getOptions()
};
this.currentMousePosition = null;
this.scrollAnimationFrame = null;
this.scrollableElement = null;
this.findScrollableElementFrame = null;
this[onDragStart$4] = this[onDragStart$4].bind(this);
this[onDragMove$2] = this[onDragMove$2].bind(this);
this[onDragStop$4] = this[onDragStop$4].bind(this);
this[scroll] = this[scroll].bind(this);
}
attach() {
this.draggable.on('drag:start', this[onDragStart$4]).on('drag:move', this[onDragMove$2]).on('drag:stop', this[onDragStop$4]);
}
detach() {
this.draggable.off('drag:start', this[onDragStart$4]).off('drag:move', this[onDragMove$2]).off('drag:stop', this[onDragStop$4]);
}
getOptions() {
return this.draggable.options.scrollable || {};
}
getScrollableElement(target) {
if (this.hasDefinedScrollableElements()) {
return closest(target, this.options.scrollableElements) || document.documentElement;
} else {
return closestScrollableElement(target);
}
}
hasDefinedScrollableElements() {
return Boolean(this.options.scrollableElements.length !== 0);
}
[onDragStart$4](dragEvent) {
this.findScrollableElementFrame = requestAnimationFrame(() => {
this.scrollableElement = this.getScrollableElement(dragEvent.source);
});
}
[onDragMove$2](dragEvent) {
this.findScrollableElementFrame = requestAnimationFrame(() => {
this.scrollableElement = this.getScrollableElement(dragEvent.sensorEvent.target);
});
if (!this.scrollableElement) {
return;
}
const sensorEvent = dragEvent.sensorEvent;
const scrollOffset = {
x: 0,
y: 0
};
if ('ontouchstart' in window) {
scrollOffset.y = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
scrollOffset.x = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
}
this.currentMousePosition = {
clientX: sensorEvent.clientX - scrollOffset.x,
clientY: sensorEvent.clientY - scrollOffset.y
};
this.scrollAnimationFrame = requestAnimationFrame(this[scroll]);
}
[onDragStop$4]() {
cancelAnimationFrame(this.scrollAnimationFrame);
cancelAnimationFrame(this.findScrollableElementFrame);
this.scrollableElement = null;
this.scrollAnimationFrame = null;
this.findScrollableElementFrame = null;
this.currentMousePosition = null;
}
[scroll]() {
if (!this.scrollableElement || !this.currentMousePosition) {
return;
}
cancelAnimationFrame(this.scrollAnimationFrame);
const {
speed,
sensitivity
} = this.options;
const rect = this.scrollableElement.getBoundingClientRect();
const bottomCutOff = rect.bottom > window.innerHeight;
const topCutOff = rect.top < 0;
const cutOff = topCutOff || bottomCutOff;
const documentScrollingElement = getDocumentScrollingElement();
const scrollableElement = this.scrollableElement;
const clientX = this.currentMousePosition.clientX;
const clientY = this.currentMousePosition.clientY;
if (scrollableElement !== document.body && scrollableElement !== document.documentElement && !cutOff) {
const {
offsetHeight,
offsetWidth
} = scrollableElement;
if (rect.top + offsetHeight - clientY < sensitivity) {
scrollableElement.scrollTop += speed;
} else if (clientY - rect.top < sensitivity) {
scrollableElement.scrollTop -= speed;
}
if (rect.left + offsetWidth - clientX < sensitivity) {
scrollableElement.scrollLeft += speed;
} else if (clientX - rect.left < sensitivity) {
scrollableElement.scrollLeft -= speed;
}
} else {
const {
innerHeight,
innerWidth
} = window;
if (clientY < sensitivity) {
documentScrollingElement.scrollTop -= speed;
} else if (innerHeight - clientY < sensitivity) {
documentScrollingElement.scrollTop += speed;
}
if (clientX < sensitivity) {
documentScrollingElement.scrollLeft -= speed;
} else if (innerWidth - clientX < sensitivity) {
documentScrollingElement.scrollLeft += speed;
}
}
this.scrollAnimationFrame = requestAnimationFrame(this[scroll]);
}
}
function hasOverflow(element) {
const overflowRegex = /(auto|scroll)/;
const computedStyles = getComputedStyle(element, null);
const overflow = computedStyles.getPropertyValue('overflow') + computedStyles.getPropertyValue('overflow-y') + computedStyles.getPropertyValue('overflow-x');
return overflowRegex.test(overflow);
}
function isStaticallyPositioned(element) {
const position = getComputedStyle(element).getPropertyValue('position');
return position === 'static';
}
function closestScrollableElement(element) {
if (!element) {
return getDocumentScrollingElement();
}
const position = getComputedStyle(element).getPropertyValue('position');
const excludeStaticParents = position === 'absolute';
const scrollableElement = closest(element, parent => {
if (excludeStaticParents && isStaticallyPositioned(parent)) {
return false;
}
return hasOverflow(parent);
});
if (position === 'fixed' || !scrollableElement) {
return getDocumentScrollingElement();
} else {
return scrollableElement;
}
}
function getDocumentScrollingElement() {
return document.scrollingElement || document.documentElement;
}
class Emitter {
constructor() {
this.callbacks = {};
}
on(type, ...callbacks) {
if (!this.callbacks[type]) {
this.callbacks[type] = [];
}
this.callbacks[type].push(...callbacks);
return this;
}
off(type, callback) {
if (!this.callbacks[type]) {
return null;
}
const copy = this.callbacks[type].slice(0);
for (let i = 0; i < copy.length; i++) {
if (callback === copy[i]) {
this.callbacks[type].splice(i, 1);
}
}
return this;
}
trigger(event) {
if (!this.callbacks[event.type]) {
return null;
}
const callbacks = [...this.callbacks[event.type]];
const caughtErrors = [];
for (let i = callbacks.length - 1; i >= 0; i--) {
const callback = callbacks[i];
try {
callback(event);
} catch (error) {
caughtErrors.push(error);
}
}
if (caughtErrors.length) {
console.error(`Draggable caught errors while triggering '${event.type}'`, caughtErrors);
}
return this;
}
}
class DraggableEvent extends AbstractEvent {
get draggable() {
return this.data.draggable;
}
}
DraggableEvent.type = 'draggable';
class DraggableInitializedEvent extends DraggableEvent {}
DraggableInitializedEvent.type = 'draggable:initialize';
class DraggableDestroyEvent extends DraggableEvent {}
DraggableDestroyEvent.type = 'draggable:destroy';
const onDragStart$3 = Symbol('onDragStart');
const onDragMove$1 = Symbol('onDragMove');
const onDragStop$3 = Symbol('onDragStop');
const onDragPressure = Symbol('onDragPressure');
const dragStop = Symbol('dragStop');
const defaultAnnouncements$3 = {
'drag:start': event => `Picked up ${event.source.textContent.trim() || event.source.id || 'draggable element'}`,
'drag:stop': event => `Released ${event.source.textContent.trim() || event.source.id || 'draggable element'}`
};
const defaultClasses$1 = {
'container:dragging': 'draggable-container--is-dragging',
'source:dragging': 'draggable-source--is-dragging',
'source:placed': 'draggable-source--placed',
'container:placed': 'draggable-container--placed',
'body:dragging': 'draggable--is-dragging',
'draggable:over': 'draggable--over',
'container:over': 'draggable-container--over',
'source:original': 'draggable--original',
mirror: 'draggable-mirror'
};
const defaultOptions$1 = {
draggable: '.draggable-source',
handle: null,
delay: {},
distance: 0,
placedTimeout: 800,
plugins: [],
sensors: [],
exclude: {
plugins: [],
sensors: []
}
};
class Draggable {
constructor(containers = [document.body], options = {}) {
if (containers instanceof NodeList || containers instanceof Array) {
this.containers = [...containers];
} else if (containers instanceof HTMLElement) {
this.containers = [containers];
} else {
throw new Error('Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`');
}
this.options = {
...defaultOptions$1,
...options,
classes: {
...defaultClasses$1,
...(options.classes || {})
},
announcements: {
...defaultAnnouncements$3,
...(options.announcements || {})
},
exclude: {
plugins: options.exclude && options.exclude.plugins || [],
sensors: options.exclude && options.exclude.sensors || []
}
};
this.emitter = new Emitter();
this.dragging = false;
this.plugins = [];
this.sensors = [];
this[onDragStart$3] = this[onDragStart$3].bind(this);
this[onDragMove$1] = this[onDragMove$1].bind(this);
this[onDragStop$3] = this[onDragStop$3].bind(this);
this[onDragPressure] = this[onDragPressure].bind(this);
this[dragStop] = this[dragStop].bind(this);
document.addEventListener('drag:start', this[onDragStart$3], true);
document.addEventListener('drag:move', this[onDragMove$1], true);
document.addEventListener('drag:stop', this[onDragStop$3], true);
document.addEventListener('drag:pressure', this[onDragPressure], true);
const defaultPlugins = Object.values(Draggable.Plugins).filter(Plugin => !this.options.exclude.plugins.includes(Plugin));
const defaultSensors = Object.values(Draggable.Sensors).filter(sensor => !this.options.exclude.sensors.includes(sensor));
this.addPlugin(...[...defaultPlugins, ...this.options.plugins]);
this.addSensor(...[...defaultSensors, ...this.options.sensors]);
const draggableInitializedEvent = new DraggableInitializedEvent({
draggable: this
});
this.on('mirror:created', ({
mirror
}) => this.mirror = mirror);
this.on('mirror:destroy', () => this.mirror = null);
this.trigger(draggableInitializedEvent);
}
destroy() {
document.removeEventListener('drag:start', this[onDragStart$3], true);
document.removeEventListener('drag:move', this[onDragMove$1], true);
document.removeEventListener('drag:stop', this[onDragStop$3], true);
document.removeEventListener('drag:pressure', this[onDragPressure], true);
const draggableDestroyEvent = new DraggableDestroyEvent({
draggable: this
});
this.trigger(draggableDestroyEvent);
this.removePlugin(...this.plugins.map(plugin => plugin.constructor));
this.removeSensor(...this.sensors.map(sensor => sensor.constructor));
}
addPlugin(...plugins) {
const activePlugins = plugins.map(Plugin => new Plugin(this));
activePlugins.forEach(plugin => plugin.attach());
this.plugins = [...this.plugins, ...activePlugins];
return this;
}
removePlugin(...plugins) {
const removedPlugins = this.plugins.filter(plugin => plugins.includes(plugin.constructor));
removedPlugins.forEach(plugin => plugin.detach());
this.plugins = this.plugins.filter(plugin => !plugins.includes(plugin.constructor));
return this;
}
addSensor(...sensors) {
const activeSensors = sensors.map(Sensor => new Sensor(this.containers, this.options));
activeSensors.forEach(sensor => sensor.attach());
this.sensors = [...this.sensors, ...activeSensors];
return this;
}
removeSensor(...sensors) {
const removedSensors = this.sensors.filter(sensor => sensors.includes(sensor.constructor));
removedSensors.forEach(sensor => sensor.detach());
this.sensors = this.sensors.filter(sensor => !sensors.includes(sensor.constructor));
return this;
}
addContainer(...containers) {
this.containers = [...this.containers, ...containers];
this.sensors.forEach(sensor => sensor.addContainer(...containers));
return this;
}
removeContainer(...containers) {
this.containers = this.containers.filter(container => !containers.includes(container));
this.sensors.forEach(sensor => sensor.removeContainer(...containers));
return this;
}
on(type, ...callbacks) {
this.emitter.on(type, ...callbacks);
return this;
}
off(type, callback) {
this.emitter.off(type, callback);
return this;
}
trigger(event) {
this.emitter.trigger(event);
return this;
}
getClassNameFor(name) {
return this.getClassNamesFor(name)[0];
}
getClassNamesFor(name) {
const classNames = this.options.classes[name];
if (classNames instanceof Array) {
return classNames;
} else if (typeof classNames === 'string' || classNames instanceof String) {
return [classNames];
} else {
return [];
}
}
isDragging() {
return Boolean(this.dragging);
}
getDraggableElements() {
return this.containers.reduce((current, container) => {
return [...current, ...this.getDraggableElementsForContainer(container)];
}, []);
}
getDraggableElementsForContainer(container) {
const allDraggableElements = container.querySelectorAll(this.options.draggable);
return [...allDraggableElements].filter(childElement => {
return childElement !== this.originalSource && childElement !== this.mirror;
});
}
cancel() {
this[dragStop]();
}
[onDragStart$3](event) {
const sensorEvent = getSensorEvent(event);
const {
target,
container,
originalSource
} = sensorEvent;
if (!this.containers.includes(container)) {
return;
}
if (this.options.handle && target && !closest(target, this.options.handle)) {
sensorEvent.cancel();
return;
}
this.originalSource = originalSource;
this.sourceContainer = container;
if (this.lastPlacedSource && this.lastPlacedContainer) {
clearTimeout(this.placedTimeoutID);
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
}
this.source = this.originalSource.cloneNode(true);
this.originalSource.parentNode.insertBefore(this.source, this.originalSource);
this.originalSource.style.display = 'none';
const dragStartEvent = new DragStartEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent
});
this.trigger(dragStartEvent);
this.dragging = !dragStartEvent.canceled();
if (dragStartEvent.canceled()) {
this.source.remove();
this.originalSource.style.display = null;
return;
}
this.originalSource.classList.add(...this.getClassNamesFor('source:original'));
this.source.classList.add(...this.getClassNamesFor('source:dragging'));
this.sourceContainer.classList.add(...this.getClassNamesFor('container:dragging'));
document.body.classList.add(...this.getClassNamesFor('body:dragging'));
applyUserSelect(document.body, 'none');
requestAnimationFrame(() => {
const oldSensorEvent = getSensorEvent(event);
const newSensorEvent = oldSensorEvent.clone({
target: this.source
});
this[onDragMove$1]({
...event,
detail: newSensorEvent
});
});
}
[onDragMove$1](event) {
if (!this.dragging) {
return;
}
const sensorEvent = getSensorEvent(event);
const {
container
} = sensorEvent;
let target = sensorEvent.target;
const dragMoveEvent = new DragMoveEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent
});
this.trigger(dragMoveEvent);
if (dragMoveEvent.canceled()) {
sensorEvent.cancel();
}
target = closest(target, this.options.draggable);
const withinCorrectContainer = closest(sensorEvent.target, this.containers);
const overContainer = sensorEvent.overContainer || withinCorrectContainer;
const isLeavingContainer = this.currentOverContainer && overContainer !== this.currentOverContainer;
const isLeavingDraggable = this.currentOver && target !== this.currentOver;
const isOverContainer = overContainer && this.currentOverContainer !== overContainer;
const isOverDraggable = withinCorrectContainer && target && this.currentOver !== target;
if (isLeavingDraggable) {
const dragOutEvent = new DragOutEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent,
over: this.currentOver,
overContainer: this.currentOverContainer
});
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
this.currentOver = null;
this.trigger(dragOutEvent);
}
if (isLeavingContainer) {
const dragOutContainerEvent = new DragOutContainerEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent,
overContainer: this.currentOverContainer
});
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
this.currentOverContainer = null;
this.trigger(dragOutContainerEvent);
}
if (isOverContainer) {
overContainer.classList.add(...this.getClassNamesFor('container:over'));
const dragOverContainerEvent = new DragOverContainerEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent,
overContainer
});
this.currentOverContainer = overContainer;
this.trigger(dragOverContainerEvent);
}
if (isOverDraggable) {
target.classList.add(...this.getClassNamesFor('draggable:over'));
const dragOverEvent = new DragOverEvent({
source: this.source,
originalSource: this.originalSource,
sourceContainer: container,
sensorEvent,
overContainer,
over: target
});
this.currentOver = target;
this.trigger(dragOverEvent);
}
}
[dragStop](event) {
if (!this.dragging) {
return;
}
this.dragging = false;
const dragStopEvent = new DragStopEvent({
source: this.source,
originalSource: this.originalSource,
sensorEvent: event ? event.sensorEvent : null,
sourceContainer: this.sourceContainer
});
this.trigger(dragStopEvent);
if (!dragStopEvent.canceled()) this.source.parentNode.insertBefore(this.originalSource, this.source);
this.source.remove();
this.originalSource.style.display = '';
this.source.classList.remove(...this.getClassNamesFor('source:dragging'));
this.originalSource.classList.remove(...this.getClassNamesFor('source:original'));
this.originalSource.classList.add(...this.getClassNamesFor('source:placed'));
this.sourceContainer.classList.add(...this.getClassNamesFor('container:placed'));
this.sourceContainer.classList.remove(...this.getClassNamesFor('container:dragging'));
document.body.classList.remove(...this.getClassNamesFor('body:dragging'));
applyUserSelect(document.body, '');
if (this.currentOver) {
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
}
if (this.currentOverContainer) {
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
}
this.lastPlacedSource = this.originalSource;
this.lastPlacedContainer = this.sourceContainer;
this.placedTimeoutID = setTimeout(() => {
if (this.lastPlacedSource) {
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
}
if (this.lastPlacedContainer) {
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
}
this.lastPlacedSource = null;
this.lastPlacedContainer = null;
}, this.options.placedTimeout);
const dragStoppedEvent = new DragStoppedEvent({
source: this.source,
originalSource: this.originalSource,
sensorEvent: event ? event.sensorEvent : null,
sourceContainer: this.sourceContainer
});
this.trigger(dragStoppedEvent);
this.source = null;
this.originalSource = null;
this.currentOverContainer = null;
this.currentOver = null;
this.sourceContainer = null;
}
[onDragStop$3](event) {
this[dragStop](event);
}
[onDragPressure](event) {
if (!this.dragging) {
return;
}
const sensorEvent = getSensorEvent(event);
const source = this.source || closest(sensorEvent.originalEvent.target, this.options.draggable);
const dragPressureEvent = new DragPressureEvent({
sensorEvent,
source,
pressure: sensorEvent.pressure
});
this.trigger(dragPressureEvent);
}
}
Draggable.Plugins = {
Announcement,
Focusable,
Mirror,
Scrollable
};
Draggable.Sensors = {
MouseSensor,
TouchSensor
};
function getSensorEvent(event) {
return event.detail;
}
function applyUserSelect(element, value) {
element.style.webkitUserSelect = value;
element.style.mozUserSelect = value;
element.style.msUserSelect = value;
element.style.oUserSelect = value;
element.style.userSelect = value;
}
class DroppableEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get dragEvent() {
return this.data.dragEvent;
}
}
DroppableEvent.type = 'droppable';
class DroppableStartEvent extends DroppableEvent {
get dropzone() {
return this.data.dropzone;
}
}
DroppableStartEvent.type = 'droppable:start';
DroppableStartEvent.cancelable = true;
class DroppableDroppedEvent extends DroppableEvent {
get dropzone() {
return this.data.dropzone;
}
}
DroppableDroppedEvent.type = 'droppable:dropped';
DroppableDroppedEvent.cancelable = true;
class DroppableReturnedEvent extends DroppableEvent {
get dropzone() {
return this.data.dropzone;
}
}
DroppableReturnedEvent.type = 'droppable:returned';
DroppableReturnedEvent.cancelable = true;
class DroppableStopEvent extends DroppableEvent {
get dropzone() {
return this.data.dropzone;
}
}
DroppableStopEvent.type = 'droppable:stop';
DroppableStopEvent.cancelable = true;
const onDragStart$2 = Symbol('onDragStart');
const onDragMove = Symbol('onDragMove');
const onDragStop$2 = Symbol('onDragStop');
const dropInDropzone = Symbol('dropInDropZone');
const returnToOriginalDropzone = Symbol('returnToOriginalDropzone');
const closestDropzone = Symbol('closestDropzone');
const getDropzones = Symbol('getDropzones');
function onDroppableDroppedDefaultAnnouncement({
dragEvent,
dropzone
}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'draggable element';
const dropzoneText = dropzone.textContent.trim() || dropzone.id || 'droppable element';
return `Dropped ${sourceText} into ${dropzoneText}`;
}
function onDroppableReturnedDefaultAnnouncement({
dragEvent,
dropzone
}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'draggable element';
const dropzoneText = dropzone.textContent.trim() || dropzone.id || 'droppable element';
return `Returned ${sourceText} from ${dropzoneText}`;
}
const defaultAnnouncements$2 = {
'droppable:dropped': onDroppableDroppedDefaultAnnouncement,
'droppable:returned': onDroppableReturnedDefaultAnnouncement
};
const defaultClasses = {
'droppable:active': 'draggable-dropzone--active',
'droppable:occupied': 'draggable-dropzone--occupied'
};
const defaultOptions = {
dropzone: '.draggable-droppable'
};
class Droppable extends Draggable {
constructor(containers = [], options = {}) {
super(containers, {
...defaultOptions,
...options,
classes: {
...defaultClasses,
...(options.classes || {})
},
announcements: {
...defaultAnnouncements$2,
...(options.announcements || {})
}
});
this.dropzones = null;
this.lastDropzone = null;
this.initialDropzone = null;
this[onDragStart$2] = this[onDragStart$2].bind(this);
this[onDragMove] = this[onDragMove].bind(this);
this[onDragStop$2] = this[onDragStop$2].bind(this);
this.on('drag:start', this[onDragStart$2]).on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop$2]);
}
destroy() {
super.destroy();
this.off('drag:start', this[onDragStart$2]).off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop$2]);
}
[onDragStart$2](event) {
if (event.canceled()) {
return;
}
this.dropzones = [...this[getDropzones]()];
const dropzone = closest(event.sensorEvent.target, this.options.dropzone);
if (!dropzone) {
event.cancel();
return;
}
const droppableStartEvent = new DroppableStartEvent({
dragEvent: event,
dropzone
});
this.trigger(droppableStartEvent);
if (droppableStartEvent.canceled()) {
event.cancel();
return;
}
this.initialDropzone = dropzone;
for (const dropzoneElement of this.dropzones) {
if (dropzoneElement.classList.contains(this.getClassNameFor('droppable:occupied'))) {
continue;
}
dropzoneElement.classList.add(...this.getClassNamesFor('droppable:active'));
}
}
[onDragMove](event) {
if (event.canceled()) {
return;
}
const dropzone = this[closestDropzone](event.sensorEvent.target);
const overEmptyDropzone = dropzone && !dropzone.classList.contains(this.getClassNameFor('droppable:occupied'));
if (overEmptyDropzone && this[dropInDropzone](event, dropzone)) {
this.lastDropzone = dropzone;
} else if ((!dropzone || dropzone === this.initialDropzone) && this.lastDropzone) {
this[returnToOriginalDropzone](event);
this.lastDropzone = null;
}
}
[onDragStop$2](event) {
const droppableStopEvent = new DroppableStopEvent({
dragEvent: event,
dropzone: this.lastDropzone || this.initialDropzone
});
this.trigger(droppableStopEvent);
const occupiedClasses = this.getClassNamesFor('droppable:occupied');
for (const dropzone of this.dropzones) {
dropzone.classList.remove(...this.getClassNamesFor('droppable:active'));
}
if (this.lastDropzone && this.lastDropzone !== this.initialDropzone) {
this.initialDropzone.classList.remove(...occupiedClasses);
}
this.dropzones = null;
this.lastDropzone = null;
this.initialDropzone = null;
}
[dropInDropzone](event, dropzone) {
const droppableDroppedEvent = new DroppableDroppedEvent({
dragEvent: event,
dropzone
});
this.trigger(droppableDroppedEvent);
if (droppableDroppedEvent.canceled()) {
return false;
}
const occupiedClasses = this.getClassNamesFor('droppable:occupied');
if (this.lastDropzone) {
this.lastDropzone.classList.remove(...occupiedClasses);
}
dropzone.appendChild(event.source);
dropzone.classList.add(...occupiedClasses);
return true;
}
[returnToOriginalDropzone](event) {
const droppableReturnedEvent = new DroppableReturnedEvent({
dragEvent: event,
dropzone: this.lastDropzone
});
this.trigger(droppableReturnedEvent);
if (droppableReturnedEvent.canceled()) {
return;
}
this.initialDropzone.appendChild(event.source);
this.lastDropzone.classList.remove(...this.getClassNamesFor('droppable:occupied'));
}
[closestDropzone](target) {
if (!this.dropzones) {
return null;
}
return closest(target, this.dropzones);
}
[getDropzones]() {
const dropzone = this.options.dropzone;
if (typeof dropzone === 'string') {
return document.querySelectorAll(dropzone);
} else if (dropzone instanceof NodeList || dropzone instanceof Array) {
return dropzone;
} else if (typeof dropzone === 'function') {
return dropzone();
} else {
return [];
}
}
}
class SwappableEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get dragEvent() {
return this.data.dragEvent;
}
}
SwappableEvent.type = 'swappable';
class SwappableStartEvent extends SwappableEvent {}
SwappableStartEvent.type = 'swappable:start';
SwappableStartEvent.cancelable = true;
class SwappableSwapEvent extends SwappableEvent {
get over() {
return this.data.over;
}
get overContainer() {
return this.data.overContainer;
}
}
SwappableSwapEvent.type = 'swappable:swap';
SwappableSwapEvent.cancelable = true;
class SwappableSwappedEvent extends SwappableEvent {
get swappedElement() {
return this.data.swappedElement;
}
}
SwappableSwappedEvent.type = 'swappable:swapped';
class SwappableStopEvent extends SwappableEvent {}
SwappableStopEvent.type = 'swappable:stop';
const onDragStart$1 = Symbol('onDragStart');
const onDragOver$1 = Symbol('onDragOver');
const onDragStop$1 = Symbol('onDragStop');
function onSwappableSwappedDefaultAnnouncement({
dragEvent,
swappedElement
}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'swappable element';
const overText = swappedElement.textContent.trim() || swappedElement.id || 'swappable element';
return `Swapped ${sourceText} with ${overText}`;
}
const defaultAnnouncements$1 = {
'swappabled:swapped': onSwappableSwappedDefaultAnnouncement
};
class Swappable extends Draggable {
constructor(containers = [], options = {}) {
super(containers, {
...options,
announcements: {
...defaultAnnouncements$1,
...(options.announcements || {})
}
});
this.lastOver = null;
this[onDragStart$1] = this[onDragStart$1].bind(this);
this[onDragOver$1] = this[onDragOver$1].bind(this);
this[onDragStop$1] = this[onDragStop$1].bind(this);
this.on('drag:start', this[onDragStart$1]).on('drag:over', this[onDragOver$1]).on('drag:stop', this[onDragStop$1]);
}
destroy() {
super.destroy();
this.off('drag:start', this._onDragStart).off('drag:over', this._onDragOver).off('drag:stop', this._onDragStop);
}
[onDragStart$1](event) {
const swappableStartEvent = new SwappableStartEvent({
dragEvent: event
});
this.trigger(swappableStartEvent);
if (swappableStartEvent.canceled()) {
event.cancel();
}
}
[onDragOver$1](event) {
if (event.over === event.originalSource || event.over === event.source || event.canceled()) {
return;
}
const swappableSwapEvent = new SwappableSwapEvent({
dragEvent: event,
over: event.over,
overContainer: event.overContainer
});
this.trigger(swappableSwapEvent);
if (swappableSwapEvent.canceled()) {
return;
}
if (this.lastOver && this.lastOver !== event.over) {
swap(this.lastOver, event.source);
}
if (this.lastOver === event.over) {
this.lastOver = null;
} else {
this.lastOver = event.over;
}
swap(event.source, event.over);
const swappableSwappedEvent = new SwappableSwappedEvent({
dragEvent: event,
swappedElement: event.over
});
this.trigger(swappableSwappedEvent);
}
[onDragStop$1](event) {
const swappableStopEvent = new SwappableStopEvent({
dragEvent: event
});
this.trigger(swappableStopEvent);
this.lastOver = null;
}
}
function withTempElement(callback) {
const tmpElement = document.createElement('div');
callback(tmpElement);
tmpElement.remove();
}
function swap(source, over) {
const overParent = over.parentNode;
const sourceParent = source.parentNode;
withTempElement(tmpElement => {
sourceParent.insertBefore(tmpElement, source);
overParent.insertBefore(source, over);
sourceParent.insertBefore(over, tmpElement);
});
}
class SortableEvent extends AbstractEvent {
constructor(data) {
super(data);
this.data = data;
}
get dragEvent() {
return this.data.dragEvent;
}
}
SortableEvent.type = 'sortable';
class SortableStartEvent extends SortableEvent {
get startIndex() {
return this.data.startIndex;
}
get startContainer() {
return this.data.startContainer;
}
}
SortableStartEvent.type = 'sortable:start';
SortableStartEvent.cancelable = true;
class SortableSortEvent extends SortableEvent {
get currentIndex() {
return this.data.currentIndex;
}
get over() {
return this.data.over;
}
get overContainer() {
return this.data.dragEvent.overContainer;
}
}
SortableSortEvent.type = 'sortable:sort';
SortableSortEvent.cancelable = true;
class SortableSortedEvent extends SortableEvent {
get oldIndex() {
return this.data.oldIndex;
}
get newIndex() {
return this.data.newIndex;
}
get oldContainer() {
return this.data.oldContainer;
}
get newContainer() {
return this.data.newContainer;
}
}
SortableSortedEvent.type = 'sortable:sorted';
class SortableStopEvent extends SortableEvent {
get oldIndex() {
return this.data.oldIndex;
}
get newIndex() {
return this.data.newIndex;
}
get oldContainer() {
return this.data.oldContainer;
}
get newContainer() {
return this.data.newContainer;
}
}
SortableStopEvent.type = 'sortable:stop';
const onDragStart = Symbol('onDragStart');
const onDragOverContainer = Symbol('onDragOverContainer');
const onDragOver = Symbol('onDragOver');
const onDragStop = Symbol('onDragStop');
function onSortableSortedDefaultAnnouncement({
dragEvent
}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'sortable element';
if (dragEvent.over) {
const overText = dragEvent.over.textContent.trim() || dragEvent.over.id || 'sortable element';
const isFollowing = dragEvent.source.compareDocumentPosition(dragEvent.over) & Node.DOCUMENT_POSITION_FOLLOWING;
if (isFollowing) {
return `Placed ${sourceText} after ${overText}`;
} else {
return `Placed ${sourceText} before ${overText}`;
}
} else {
return `Placed ${sourceText} into a different container`;
}
}
const defaultAnnouncements = {
'sortable:sorted': onSortableSortedDefaultAnnouncement
};
class Sortable extends Draggable {
constructor(containers = [], options = {}) {
super(containers, {
...options,
announcements: {
...defaultAnnouncements,
...(options.announcements || {})
}
});
this.startIndex = null;
this.startContainer = null;
this[onDragStart] = this[onDragStart].bind(this);
this[onDragOverContainer] = this[onDragOverContainer].bind(this);
this[onDragOver] = this[onDragOver].bind(this);
this[onDragStop] = this[onDragStop].bind(this);
this.on('drag:start', this[onDragStart]).on('drag:over:container', this[onDragOverContainer]).on('drag:over', this[onDragOver]).on('drag:stop', this[onDragStop]);
}
destroy() {
super.destroy();
this.off('drag:start', this[onDragStart]).off('drag:over:container', this[onDragOverContainer]).off('drag:over', this[onDragOver]).off('drag:stop', this[onDragStop]);
}
index(element) {
return this.getSortableElementsForContainer(element.parentNode).indexOf(element);
}
getSortableElementsForContainer(container) {
const allSortableElements = container.querySelectorAll(this.options.draggable);
return [...allSortableElements].filter(childElement => {
return childElement !== this.originalSource && childElement !== this.mirror && childElement.parentNode === container;
});
}
[onDragStart](event) {
this.startContainer = event.source.parentNode;
this.startIndex = this.index(event.source);
const sortableStartEvent = new SortableStartEvent({
dragEvent: event,
startIndex: this.startIndex,
startContainer: this.startContainer
});
this.trigger(sortableStartEvent);
if (sortableStartEvent.canceled()) {
event.cancel();
}
}
[onDragOverContainer](event) {
if (event.canceled()) {
return;
}
const {
source,
over,
overContainer
} = event;
const oldIndex = this.index(source);
const sortableSortEvent = new SortableSortEvent({
dragEvent: event,
currentIndex: oldIndex,
source,
over
});
this.trigger(sortableSortEvent);
if (sortableSortEvent.canceled()) {
return;
}
const children = this.getSortableElementsForContainer(overContainer);
const moves = move({
source,
over,
overContainer,
children
});
if (!moves) {
return;
}
const {
oldContainer,
newContainer
} = moves;
const newIndex = this.index(event.source);
const sortableSortedEvent = new SortableSortedEvent({
dragEvent: event,
oldIndex,
newIndex,
oldContainer,
newContainer
});
this.trigger(sortableSortedEvent);
}
[onDragOver](event) {
if (event.over === event.originalSource || event.over === event.source) {
return;
}
const {
source,
over,
overContainer
} = event;
const oldIndex = this.index(source);
const sortableSortEvent = new SortableSortEvent({
dragEvent: event,
currentIndex: oldIndex,
source,
over
});
this.trigger(sortableSortEvent);
if (sortableSortEvent.canceled()) {
return;
}
const children = this.getDraggableElementsForContainer(overContainer);
const moves = move({
source,
over,
overContainer,
children
});
if (!moves) {
return;
}
const {
oldContainer,
newContainer
} = moves;
const newIndex = this.index(source);
const sortableSortedEvent = new SortableSortedEvent({
dragEvent: event,
oldIndex,
newIndex,
oldContainer,
newContainer
});
this.trigger(sortableSortedEvent);
}
[onDragStop](event) {
const sortableStopEvent = new SortableStopEvent({
dragEvent: event,
oldIndex: this.startIndex,
newIndex: this.index(event.source),
oldContainer: this.startContainer,
newContainer: event.source.parentNode
});
this.trigger(sortableStopEvent);
this.startIndex = null;
this.startContainer = null;
}
}
function index(element) {
return Array.prototype.indexOf.call(element.parentNode.children, element);
}
function move({
source,
over,
overContainer,
children
}) {
const emptyOverContainer = !children.length;
const differentContainer = source.parentNode !== overContainer;
const sameContainer = over && source.parentNode === over.parentNode;
if (emptyOverContainer) {
return moveInsideEmptyContainer(source, overContainer);
} else if (sameContainer) {
return moveWithinContainer(source, over);
} else if (differentContainer) {
return moveOutsideContainer(source, over, overContainer);
} else {
return null;
}
}
function moveInsideEmptyContainer(source, overContainer) {
const oldContainer = source.parentNode;
overContainer.appendChild(source);
return {
oldContainer,
newContainer: overContainer
};
}
function moveWithinContainer(source, over) {
const oldIndex = index(source);
const newIndex = index(over);
if (oldIndex < newIndex) {
source.parentNode.insertBefore(source, over.nextElementSibling);
} else {
source.parentNode.insertBefore(source, over);
}
return {
oldContainer: source.parentNode,
newContainer: source.parentNode
};
}
function moveOutsideContainer(source, over, overContainer) {
const oldContainer = source.parentNode;
if (over) {
over.parentNode.insertBefore(source, over);
} else {
overContainer.appendChild(source);
}
return {
oldContainer,
newContainer: source.parentNode
};
}
exports.BaseEvent = AbstractEvent;
exports.BasePlugin = AbstractPlugin;
exports.Draggable = Draggable;
exports.Droppable = Droppable;
exports.Plugins = index$1;
exports.Sensors = index$2;
exports.Sortable = Sortable;
exports.Swappable = Swappable;
}));