mirror of
https://github.com/Shopify/draggable.git
synced 2025-12-08 20:15:56 +00:00
setup prettier and fix all files
This commit is contained in:
parent
9ceef05571
commit
34d1bc3cbf
15
.eslintrc.js
15
.eslintrc.js
@ -1,6 +1,8 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'plugin:shopify/esnext',
|
||||
'plugin:shopify/jest',
|
||||
'plugin:shopify/prettier',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
@ -9,16 +11,7 @@ module.exports = {
|
||||
'import/no-unresolved': 'off',
|
||||
'import/no-extraneous-dependencies': 'off',
|
||||
'class-methods-use-this': 'off',
|
||||
},
|
||||
globals: {
|
||||
jest: false,
|
||||
afterAll: false,
|
||||
afterEach: false,
|
||||
beforeAll: false,
|
||||
beforeEach: false,
|
||||
describe: false,
|
||||
test: false,
|
||||
xtest: false,
|
||||
expect: false,
|
||||
'line-comment-position': 0,
|
||||
'lines-around-comment': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
4
.prettierrc
Normal file
4
.prettierrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"singleQuote": true
|
||||
}
|
||||
@ -1,8 +1,10 @@
|
||||
export const defaultTouchEventOptions = {
|
||||
touches: [{
|
||||
pageX: 0,
|
||||
pageY: 0,
|
||||
}],
|
||||
touches: [
|
||||
{
|
||||
pageX: 0,
|
||||
pageY: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const DRAG_DELAY = 0;
|
||||
|
||||
@ -2,6 +2,7 @@ export function createSandbox(content) {
|
||||
const sandbox = document.createElement('div');
|
||||
sandbox.innerHTML = content;
|
||||
document.body.appendChild(sandbox);
|
||||
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import {withElementFromPoint} from './environment';
|
||||
export function triggerEvent(element, type, data = {}) {
|
||||
const event = document.createEvent('Event');
|
||||
event.initEvent(type, true, true);
|
||||
|
||||
for (const key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
event[key] = data[key];
|
||||
|
||||
@ -11,15 +11,19 @@ function toHaveOrder(actualOrder, expectedOrder) {
|
||||
const expectation = pass ? 'not to be' : 'to be';
|
||||
let message = `Expected order ${expectation}:\n`;
|
||||
|
||||
message += expectedOrder.map((element) => {
|
||||
return `${element.textContent.trim()}`;
|
||||
}).join('\n');
|
||||
message += expectedOrder
|
||||
.map((element) => {
|
||||
return `${element.textContent.trim()}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
message += '\n \nInstead received:\n';
|
||||
|
||||
message += actualOrder.map((element) => {
|
||||
return `${element.textContent.trim()}`;
|
||||
}).join('\n');
|
||||
message += actualOrder
|
||||
.map((element) => {
|
||||
return `${element.textContent.trim()}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
return message;
|
||||
},
|
||||
|
||||
@ -12,19 +12,19 @@ import {
|
||||
|
||||
describe('DragEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragEvent', () => {
|
||||
it('should be instance of DragEvent', () => {
|
||||
const event = new DragEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `event`', () => {
|
||||
it('should initialize with `type` of `event`', () => {
|
||||
const event = new DragEvent();
|
||||
|
||||
expect(event.type).toBe('drag');
|
||||
});
|
||||
|
||||
test('should initialize with source', () => {
|
||||
it('should initialize with source', () => {
|
||||
const event = new DragEvent({
|
||||
source: 'expected source',
|
||||
});
|
||||
@ -32,7 +32,7 @@ describe('DragEvent', () => {
|
||||
expect(event.source).toBe('expected source');
|
||||
});
|
||||
|
||||
test('should initialize with mirror', () => {
|
||||
it('should initialize with mirror', () => {
|
||||
const event = new DragEvent({
|
||||
mirror: 'expected mirror',
|
||||
});
|
||||
@ -40,7 +40,7 @@ describe('DragEvent', () => {
|
||||
expect(event.mirror).toBe('expected mirror');
|
||||
});
|
||||
|
||||
test('should initialize with sourceContainer', () => {
|
||||
it('should initialize with sourceContainer', () => {
|
||||
const event = new DragEvent({
|
||||
sourceContainer: 'expected sourceContainer',
|
||||
});
|
||||
@ -48,7 +48,7 @@ describe('DragEvent', () => {
|
||||
expect(event.sourceContainer).toBe('expected sourceContainer');
|
||||
});
|
||||
|
||||
test('should initialize with sensorEvent', () => {
|
||||
it('should initialize with sensorEvent', () => {
|
||||
const event = new DragEvent({
|
||||
sensorEvent: 'expected sensorEvent',
|
||||
});
|
||||
@ -56,7 +56,7 @@ describe('DragEvent', () => {
|
||||
expect(event.sensorEvent).toBe('expected sensorEvent');
|
||||
});
|
||||
|
||||
test('should initialize with originalEvent', () => {
|
||||
it('should initialize with originalEvent', () => {
|
||||
const event = new DragEvent({
|
||||
sensorEvent: {
|
||||
originalEvent: 'expected originalEvent',
|
||||
@ -68,15 +68,15 @@ describe('DragEvent', () => {
|
||||
});
|
||||
|
||||
describe('#originalEvent', () => {
|
||||
test('should return null when initialized without sensorEvent', () => {
|
||||
it('should return null when initialized without sensorEvent', () => {
|
||||
const event = new DragEvent({});
|
||||
|
||||
expect(event.originalEvent).toBe(null);
|
||||
expect(event.originalEvent).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#hasMirror', () => {
|
||||
test('should return true when event has mirror', () => {
|
||||
it('should return true when event has mirror', () => {
|
||||
const event = new DragEvent({
|
||||
mirror: true,
|
||||
});
|
||||
@ -84,7 +84,7 @@ describe('DragEvent', () => {
|
||||
expect(event.hasMirror()).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false when event does not have mirror', () => {
|
||||
it('should return false when event does not have mirror', () => {
|
||||
const event = new DragEvent({});
|
||||
|
||||
expect(event.hasMirror()).toBe(false);
|
||||
@ -94,13 +94,13 @@ describe('DragEvent', () => {
|
||||
|
||||
describe('DragStartEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragStartEvent', () => {
|
||||
it('should be instance of DragStartEvent', () => {
|
||||
const event = new DragStartEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragStartEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:start`', () => {
|
||||
it('should initialize with `type` of `drag:start`', () => {
|
||||
const event = new DragStartEvent();
|
||||
|
||||
expect(event.type).toBe('drag:start');
|
||||
@ -110,13 +110,13 @@ describe('DragStartEvent', () => {
|
||||
|
||||
describe('DragMoveEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragMoveEvent', () => {
|
||||
it('should be instance of DragMoveEvent', () => {
|
||||
const event = new DragMoveEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragMoveEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:move`', () => {
|
||||
it('should initialize with `type` of `drag:move`', () => {
|
||||
const event = new DragMoveEvent();
|
||||
|
||||
expect(event.type).toBe('drag:move');
|
||||
@ -126,19 +126,19 @@ describe('DragMoveEvent', () => {
|
||||
|
||||
describe('DragOutContainerEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragOutContainerEvent', () => {
|
||||
it('should be instance of DragOutContainerEvent', () => {
|
||||
const event = new DragOutContainerEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragOutContainerEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:out:container`', () => {
|
||||
it('should initialize with `type` of `drag:out:container`', () => {
|
||||
const event = new DragOutContainerEvent();
|
||||
|
||||
expect(event.type).toBe('drag:out:container');
|
||||
});
|
||||
|
||||
test('should initialize with overContainer', () => {
|
||||
it('should initialize with overContainer', () => {
|
||||
const event = new DragOutContainerEvent({
|
||||
overContainer: 'expected overContainer',
|
||||
});
|
||||
@ -150,19 +150,19 @@ describe('DragOutContainerEvent', () => {
|
||||
|
||||
describe('DragOutEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragOutEvent', () => {
|
||||
it('should be instance of DragOutEvent', () => {
|
||||
const event = new DragOutEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragOutEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:out`', () => {
|
||||
it('should initialize with `type` of `drag:out`', () => {
|
||||
const event = new DragOutEvent();
|
||||
|
||||
expect(event.type).toBe('drag:out');
|
||||
});
|
||||
|
||||
test('should initialize with overContainer', () => {
|
||||
it('should initialize with overContainer', () => {
|
||||
const event = new DragOutEvent({
|
||||
overContainer: 'expected overContainer',
|
||||
});
|
||||
@ -170,7 +170,7 @@ describe('DragOutEvent', () => {
|
||||
expect(event.overContainer).toBe('expected overContainer');
|
||||
});
|
||||
|
||||
test('should initialize with over', () => {
|
||||
it('should initialize with over', () => {
|
||||
const event = new DragOutEvent({
|
||||
over: 'expected over',
|
||||
});
|
||||
@ -182,19 +182,19 @@ describe('DragOutEvent', () => {
|
||||
|
||||
describe('DragOverContainerEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragOverContainerEvent', () => {
|
||||
it('should be instance of DragOverContainerEvent', () => {
|
||||
const event = new DragOverContainerEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragOverContainerEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:over:container`', () => {
|
||||
it('should initialize with `type` of `drag:over:container`', () => {
|
||||
const event = new DragOverContainerEvent();
|
||||
|
||||
expect(event.type).toBe('drag:over:container');
|
||||
});
|
||||
|
||||
test('should initialize with overContainer', () => {
|
||||
it('should initialize with overContainer', () => {
|
||||
const event = new DragOverContainerEvent({
|
||||
overContainer: 'expected overContainer',
|
||||
});
|
||||
@ -206,19 +206,19 @@ describe('DragOverContainerEvent', () => {
|
||||
|
||||
describe('DragOverEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragOverEvent', () => {
|
||||
it('should be instance of DragOverEvent', () => {
|
||||
const event = new DragOverEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragOverEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:over`', () => {
|
||||
it('should initialize with `type` of `drag:over`', () => {
|
||||
const event = new DragOverEvent();
|
||||
|
||||
expect(event.type).toBe('drag:over');
|
||||
});
|
||||
|
||||
test('should initialize with overContainer', () => {
|
||||
it('should initialize with overContainer', () => {
|
||||
const event = new DragOverEvent({
|
||||
overContainer: 'expected overContainer',
|
||||
});
|
||||
@ -226,7 +226,7 @@ describe('DragOverEvent', () => {
|
||||
expect(event.overContainer).toBe('expected overContainer');
|
||||
});
|
||||
|
||||
test('should initialize with over', () => {
|
||||
it('should initialize with over', () => {
|
||||
const event = new DragOverEvent({
|
||||
over: 'expected over',
|
||||
});
|
||||
@ -238,19 +238,19 @@ describe('DragOverEvent', () => {
|
||||
|
||||
describe('DragPressureEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragPressureEvent', () => {
|
||||
it('should be instance of DragPressureEvent', () => {
|
||||
const event = new DragPressureEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragPressureEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:pressure`', () => {
|
||||
it('should initialize with `type` of `drag:pressure`', () => {
|
||||
const event = new DragPressureEvent();
|
||||
|
||||
expect(event.type).toBe('drag:pressure');
|
||||
});
|
||||
|
||||
test('should initialize with pressure', () => {
|
||||
it('should initialize with pressure', () => {
|
||||
const event = new DragPressureEvent({
|
||||
pressure: 'expected pressure',
|
||||
});
|
||||
@ -262,13 +262,13 @@ describe('DragPressureEvent', () => {
|
||||
|
||||
describe('DragStopEvent', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should be instance of DragStopEvent', () => {
|
||||
it('should be instance of DragStopEvent', () => {
|
||||
const event = new DragStopEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(DragStopEvent);
|
||||
});
|
||||
|
||||
test('should initialize with `type` of `drag:stop`', () => {
|
||||
it('should initialize with `type` of `drag:stop`', () => {
|
||||
const event = new DragStopEvent();
|
||||
|
||||
expect(event.type).toBe('drag:stop');
|
||||
|
||||
@ -1,18 +1,8 @@
|
||||
import {closest} from 'shared/utils';
|
||||
|
||||
import {Accessibility, Mirror, Scrollable, Announcement} from './Plugins';
|
||||
|
||||
import Emitter from './Emitter';
|
||||
|
||||
import {
|
||||
MouseSensor,
|
||||
TouchSensor,
|
||||
} from './Sensors';
|
||||
|
||||
import {
|
||||
DraggableInitializedEvent,
|
||||
DraggableDestroyEvent,
|
||||
} from './DraggableEvent';
|
||||
import {MouseSensor, TouchSensor} from './Sensors';
|
||||
import {DraggableInitializedEvent, DraggableDestroyEvent} from './DraggableEvent';
|
||||
|
||||
import {
|
||||
DragStartEvent,
|
||||
@ -76,7 +66,6 @@ export const defaultOptions = {
|
||||
* @module Draggable
|
||||
*/
|
||||
export default class Draggable {
|
||||
|
||||
/**
|
||||
* Default plugins draggable uses
|
||||
* @static
|
||||
@ -96,7 +85,6 @@ export default class Draggable {
|
||||
* @param {Object} options - Options for draggable
|
||||
*/
|
||||
constructor(containers = [document.body], options = {}) {
|
||||
|
||||
/**
|
||||
* Draggable containers
|
||||
* @property containers
|
||||
@ -199,8 +187,10 @@ export default class Draggable {
|
||||
*/
|
||||
addPlugin(...plugins) {
|
||||
const activePlugins = plugins.map((Plugin) => new Plugin(this));
|
||||
|
||||
activePlugins.forEach((plugin) => plugin.attach());
|
||||
this.plugins = [...this.plugins, ...activePlugins];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -213,8 +203,10 @@ export default class Draggable {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@ -226,8 +218,10 @@ export default class Draggable {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@ -240,8 +234,10 @@ export default class Draggable {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@ -484,10 +480,10 @@ export default class Draggable {
|
||||
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);
|
||||
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({
|
||||
|
||||
@ -58,6 +58,7 @@ export default class Emitter {
|
||||
|
||||
for (let i = callbacks.length - 1; i >= 0; i--) {
|
||||
const callback = callbacks[i];
|
||||
|
||||
try {
|
||||
callback(event);
|
||||
} catch (error) {
|
||||
|
||||
@ -11,7 +11,7 @@ describe('Emitter', () => {
|
||||
});
|
||||
|
||||
describe('#on', () => {
|
||||
test('registers a callback by event type', () => {
|
||||
it('registers a callback by event type', () => {
|
||||
const callback = jest.fn();
|
||||
|
||||
emitter.on('event', callback);
|
||||
@ -19,7 +19,7 @@ describe('Emitter', () => {
|
||||
expect(emitter.callbacks.event).toContain(callback);
|
||||
});
|
||||
|
||||
test('registers multiple callbacks by event type', () => {
|
||||
it('registers multiple callbacks by event type', () => {
|
||||
const callbacks = [jest.fn(), jest.fn()];
|
||||
|
||||
emitter.on('event', ...callbacks);
|
||||
@ -30,7 +30,7 @@ describe('Emitter', () => {
|
||||
});
|
||||
|
||||
describe('#off', () => {
|
||||
test('removes a callback by event type', () => {
|
||||
it('removes a callback by event type', () => {
|
||||
const callback = jest.fn();
|
||||
|
||||
emitter.on('event', callback);
|
||||
@ -44,7 +44,7 @@ describe('Emitter', () => {
|
||||
});
|
||||
|
||||
describe('#trigger', () => {
|
||||
test('triggers callbacks on event with test event', () => {
|
||||
it('triggers callbacks on event with test event', () => {
|
||||
const testEvent = new TestEvent({});
|
||||
const callback = jest.fn();
|
||||
|
||||
@ -55,11 +55,13 @@ describe('Emitter', () => {
|
||||
expect(callback).toHaveBeenCalledWith(testEvent);
|
||||
});
|
||||
|
||||
test('catches errors from listeners and re-throws at the end of the trigger phase', () => {
|
||||
it('catches errors from listeners and re-throws at the end of the trigger phase', () => {
|
||||
const testEvent = new TestEvent({});
|
||||
const callbacks = [
|
||||
jest.fn(),
|
||||
() => { throw new Error('Error'); },
|
||||
() => {
|
||||
throw new Error('Error');
|
||||
},
|
||||
jest.fn(),
|
||||
];
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ import AbstractEvent from 'shared/AbstractEvent';
|
||||
* @extends AbstractEvent
|
||||
*/
|
||||
export class MirrorEvent extends AbstractEvent {
|
||||
|
||||
/**
|
||||
* Draggables source element
|
||||
* @property source
|
||||
|
||||
@ -11,7 +11,6 @@ const TABINDEX = 'tabindex';
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Accessibility extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Accessibility constructor.
|
||||
* @constructs Accessibility
|
||||
|
||||
@ -27,7 +27,6 @@ export const defaultOptions = {
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Announcement extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Announcement constructor.
|
||||
* @constructs Announcement
|
||||
@ -61,16 +60,14 @@ export default class Announcement extends AbstractPlugin {
|
||||
* Attaches listeners to draggable
|
||||
*/
|
||||
attach() {
|
||||
this.draggable
|
||||
.on('draggable:initialize', this[onInitialize]);
|
||||
this.draggable.on('draggable:initialize', this[onInitialize]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches listeners from draggable
|
||||
*/
|
||||
detach() {
|
||||
this.draggable
|
||||
.off('draggable:destroy', this[onDestroy]);
|
||||
this.draggable.off('draggable:destroy', this[onDestroy]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,11 +85,11 @@ export default class Announcement extends AbstractPlugin {
|
||||
[announceEvent](event) {
|
||||
const message = this.options[event.type];
|
||||
|
||||
if (message && (typeof message === 'string')) {
|
||||
if (message && typeof message === 'string') {
|
||||
this[announceMessage](message);
|
||||
}
|
||||
|
||||
if (message && (typeof message === 'function')) {
|
||||
if (message && typeof message === 'function') {
|
||||
this[announceMessage](message(event));
|
||||
}
|
||||
}
|
||||
@ -144,8 +141,10 @@ const liveRegion = createRegion();
|
||||
*/
|
||||
function announce(message, {expire}) {
|
||||
const element = document.createElement('div');
|
||||
|
||||
element.innerHTML = message;
|
||||
liveRegion.appendChild(element);
|
||||
|
||||
return setTimeout(() => {
|
||||
liveRegion.removeChild(element);
|
||||
}, expire);
|
||||
|
||||
@ -31,7 +31,6 @@ export const defaultOptions = {
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Mirror extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Mirror constructor.
|
||||
* @constructs Mirror
|
||||
@ -163,15 +162,17 @@ export default class Mirror extends AbstractPlugin {
|
||||
options: this.options,
|
||||
};
|
||||
|
||||
return Promise.resolve(initialState)
|
||||
// Fix reflow here
|
||||
.then(computeMirrorDimensions)
|
||||
.then(calculateMirrorOffset)
|
||||
.then(resetMirror)
|
||||
.then(addMirrorClasses)
|
||||
.then(positionMirror({initial: true}))
|
||||
.then(removeMirrorID)
|
||||
.then(setState);
|
||||
return (
|
||||
Promise.resolve(initialState)
|
||||
// Fix reflow here
|
||||
.then(computeMirrorDimensions)
|
||||
.then(calculateMirrorOffset)
|
||||
.then(resetMirror)
|
||||
.then(addMirrorClasses)
|
||||
.then(positionMirror({initial: true}))
|
||||
.then(removeMirrorID)
|
||||
.then(setState)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,8 +192,7 @@ export default class Mirror extends AbstractPlugin {
|
||||
scrollOffset: this.scrollOffset,
|
||||
};
|
||||
|
||||
return Promise.resolve(initialState)
|
||||
.then(positionMirror({raf: true}));
|
||||
return Promise.resolve(initialState).then(positionMirror({raf: true}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,8 +222,8 @@ function computeMirrorDimensions({source, ...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 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};
|
||||
|
||||
@ -310,35 +310,38 @@ function removeMirrorID({mirror, ...args}) {
|
||||
*/
|
||||
function positionMirror({withFrame = false, initial = false} = {}) {
|
||||
return ({mirror, sensorEvent, mirrorOffset, initialY, initialX, scrollOffset, options, ...args}) => {
|
||||
return withPromise((resolve) => {
|
||||
const result = {
|
||||
mirror,
|
||||
sensorEvent,
|
||||
mirrorOffset,
|
||||
options,
|
||||
...args,
|
||||
};
|
||||
return withPromise(
|
||||
(resolve) => {
|
||||
const result = {
|
||||
mirror,
|
||||
sensorEvent,
|
||||
mirrorOffset,
|
||||
options,
|
||||
...args,
|
||||
};
|
||||
|
||||
if (mirrorOffset) {
|
||||
const x = sensorEvent.clientX - mirrorOffset.left - scrollOffset.x;
|
||||
const y = sensorEvent.clientY - mirrorOffset.top - scrollOffset.y;
|
||||
if (mirrorOffset) {
|
||||
const x = sensorEvent.clientX - mirrorOffset.left - scrollOffset.x;
|
||||
const y = sensorEvent.clientY - mirrorOffset.top - scrollOffset.y;
|
||||
|
||||
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 ((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;
|
||||
}
|
||||
}
|
||||
|
||||
if (initial) {
|
||||
result.initialX = x;
|
||||
result.initialY = y;
|
||||
}
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
}, {frame: withFrame});
|
||||
resolve(result);
|
||||
},
|
||||
{frame: withFrame},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,6 @@ export const defaultOptions = {
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Scrollable extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Scrollable constructor.
|
||||
* @constructs Scrollable
|
||||
@ -224,12 +223,20 @@ export default class Scrollable extends AbstractPlugin {
|
||||
bottom = rect.bottom;
|
||||
}
|
||||
|
||||
let offsetY = (Math.abs(bottom - this.currentMousePosition.clientY) <= this.options.sensitivity) - (Math.abs(top - this.currentMousePosition.clientY) <= this.options.sensitivity);
|
||||
let offsetX = (Math.abs(right - this.currentMousePosition.clientX) <= this.options.sensitivity) - (Math.abs(left - this.currentMousePosition.clientX) <= this.options.sensitivity);
|
||||
let offsetY =
|
||||
(Math.abs(bottom - this.currentMousePosition.clientY) <= this.options.sensitivity) -
|
||||
(Math.abs(top - this.currentMousePosition.clientY) <= this.options.sensitivity);
|
||||
let offsetX =
|
||||
(Math.abs(right - this.currentMousePosition.clientX) <= this.options.sensitivity) -
|
||||
(Math.abs(left - this.currentMousePosition.clientX) <= this.options.sensitivity);
|
||||
|
||||
if (!offsetX && !offsetY) {
|
||||
offsetX = (windowWidth - this.currentMousePosition.clientX <= this.options.sensitivity) - (this.currentMousePosition.clientX <= this.options.sensitivity);
|
||||
offsetY = (windowHeight - this.currentMousePosition.clientY <= this.options.sensitivity) - (this.currentMousePosition.clientY <= this.options.sensitivity);
|
||||
offsetX =
|
||||
(windowWidth - this.currentMousePosition.clientX <= this.options.sensitivity) -
|
||||
(this.currentMousePosition.clientX <= this.options.sensitivity);
|
||||
offsetY =
|
||||
(windowHeight - this.currentMousePosition.clientY <= this.options.sensitivity) -
|
||||
(this.currentMousePosition.clientY <= this.options.sensitivity);
|
||||
}
|
||||
|
||||
this.scrollableElement.scrollTop += offsetY * this.options.speed;
|
||||
@ -249,9 +256,10 @@ 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');
|
||||
const overflow =
|
||||
computedStyles.getPropertyValue('overflow') +
|
||||
computedStyles.getPropertyValue('overflow-y') +
|
||||
computedStyles.getPropertyValue('overflow-x');
|
||||
|
||||
return overflowRegex.test(overflow);
|
||||
}
|
||||
|
||||
@ -1,18 +1,4 @@
|
||||
export {
|
||||
default as Mirror,
|
||||
defaultOptions as defaultMirrorOptions,
|
||||
} from './Mirror';
|
||||
|
||||
export {
|
||||
default as Announcement,
|
||||
defaultOptions as defaultAnnouncementOptions,
|
||||
} from './Announcement';
|
||||
|
||||
export {
|
||||
default as Scrollable,
|
||||
defaultOptions as defaultScrollableOptions,
|
||||
} from './Scrollable';
|
||||
|
||||
export {
|
||||
default as Accessibility,
|
||||
} from './Accessibility';
|
||||
export {default as Mirror, defaultOptions as defaultMirrorOptions} from './Mirror';
|
||||
export {default as Announcement, defaultOptions as defaultAnnouncementOptions} from './Announcement';
|
||||
export {default as Scrollable, defaultOptions as defaultScrollableOptions} from './Scrollable';
|
||||
export {default as Accessibility} from './Accessibility';
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
import {closest} from 'shared/utils';
|
||||
|
||||
import Sensor from '../Sensor';
|
||||
|
||||
import {
|
||||
DragStartSensorEvent,
|
||||
DragMoveSensorEvent,
|
||||
DragStopSensorEvent,
|
||||
} from '../SensorEvent';
|
||||
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
|
||||
|
||||
const onMouseDown = Symbol('onMouseDown');
|
||||
const onMouseUp = Symbol('onMouseUp');
|
||||
@ -23,7 +17,6 @@ const reset = Symbol('reset');
|
||||
* @extends Sensor
|
||||
*/
|
||||
export default class DragSensor extends Sensor {
|
||||
|
||||
/**
|
||||
* DragSensor constructor.
|
||||
* @constructs DragSensor
|
||||
@ -177,7 +170,8 @@ export default class DragSensor extends Sensor {
|
||||
* @private
|
||||
* @param {Event} event - Drop event
|
||||
*/
|
||||
[onDrop](event) { // eslint-disable-line class-methods-use-this
|
||||
[onDrop](event) {
|
||||
// eslint-disable-line class-methods-use-this
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
@ -188,7 +182,7 @@ export default class DragSensor extends Sensor {
|
||||
*/
|
||||
[onMouseDown](event) {
|
||||
// Firefox bug for inputs within draggables https://bugzilla.mozilla.org/show_bug.cgi?id=739071
|
||||
if ((event.target && (event.target.form || event.target.contenteditable))) {
|
||||
if (event.target && (event.target.form || event.target.contenteditable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -39,23 +39,20 @@ describe('DragSensor', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('mousedown handler adds draggable attribute', () => {
|
||||
expect(draggableElement.draggable)
|
||||
.toBeUndefined();
|
||||
it('mousedown handler adds draggable attribute', () => {
|
||||
expect(draggableElement.draggable).toBeUndefined();
|
||||
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
|
||||
expect(draggableElement.draggable)
|
||||
.toBe(true);
|
||||
expect(draggableElement.draggable).toBe(true);
|
||||
|
||||
releaseMouse(draggableElement);
|
||||
|
||||
expect(draggableElement.draggable)
|
||||
.toBe(false);
|
||||
expect(draggableElement.draggable).toBe(false);
|
||||
});
|
||||
|
||||
test('triggers `drag:start` sensor event on dragstart', () => {
|
||||
it('triggers `drag:start` sensor event on dragstart', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -65,11 +62,10 @@ describe('DragSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('cancels `drag:start` event when canceling sensor event', () => {
|
||||
it('cancels `drag:start` event when canceling sensor event', () => {
|
||||
sandbox.addEventListener('drag:start', (event) => {
|
||||
event.detail.cancel();
|
||||
});
|
||||
@ -83,11 +79,10 @@ describe('DragSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveCanceledSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event releasing mouse before timeout', () => {
|
||||
it('does not trigger `drag:start` event releasing mouse before timeout', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -103,22 +98,16 @@ describe('DragSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('triggers `drag:move` event while moving the mouse', () => {
|
||||
it('triggers `drag:move` event while moving the mouse', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -129,11 +118,10 @@ describe('DragSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:move');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
|
||||
});
|
||||
|
||||
test('triggers `drag:stop` event when releasing mouse', () => {
|
||||
it('triggers `drag:stop` event when releasing mouse', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -144,11 +132,10 @@ describe('DragSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event when clicking on none draggable element', () => {
|
||||
it('does not trigger `drag:start` event when clicking on none draggable element', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(document.body);
|
||||
waitForDragDelay();
|
||||
@ -156,8 +143,6 @@ describe('DragSensor', () => {
|
||||
waitForDragDelay();
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
import Sensor from '../Sensor';
|
||||
|
||||
import {
|
||||
DragStartSensorEvent,
|
||||
DragMoveSensorEvent,
|
||||
DragStopSensorEvent,
|
||||
DragPressureSensorEvent,
|
||||
} from '../SensorEvent';
|
||||
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent, DragPressureSensorEvent} from '../SensorEvent';
|
||||
|
||||
const onMouseForceWillBegin = Symbol('onMouseForceWillBegin');
|
||||
const onMouseForceDown = Symbol('onMouseForceDown');
|
||||
@ -22,7 +16,6 @@ const onMouseForceGlobalChange = Symbol('onMouseForceGlobalChange');
|
||||
* @extends Sensor
|
||||
*/
|
||||
export default class ForceTouchSensor extends Sensor {
|
||||
|
||||
/**
|
||||
* ForceTouchSensor constructor.
|
||||
* @constructs ForceTouchSensor
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import {closest} from 'shared/utils';
|
||||
import Sensor from '../Sensor';
|
||||
|
||||
import {
|
||||
DragStartSensorEvent,
|
||||
DragMoveSensorEvent,
|
||||
DragStopSensorEvent,
|
||||
} from '../SensorEvent';
|
||||
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
|
||||
|
||||
const onContextMenuWhileDragging = Symbol('onContextMenuWhileDragging');
|
||||
const onMouseDown = Symbol('onMouseDown');
|
||||
@ -19,7 +14,6 @@ const onMouseUp = Symbol('onMouseUp');
|
||||
* @extends Sensor
|
||||
*/
|
||||
export default class MouseSensor extends Sensor {
|
||||
|
||||
/**
|
||||
* MouseSensor constructor.
|
||||
* @constructs MouseSensor
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
createSandbox,
|
||||
triggerEvent,
|
||||
waitForDragDelay,
|
||||
DRAG_DELAY,
|
||||
clickMouse,
|
||||
moveMouse,
|
||||
releaseMouse,
|
||||
} from 'helper';
|
||||
import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, clickMouse, moveMouse, releaseMouse} from 'helper';
|
||||
|
||||
import MouseSensor from '..';
|
||||
|
||||
@ -35,18 +27,17 @@ describe('MouseSensor', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('triggers `drag:start` sensor event on mousedown', () => {
|
||||
it('triggers `drag:start` sensor event on mousedown', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('cancels `drag:start` event when canceling sensor event', () => {
|
||||
it('cancels `drag:start` event when canceling sensor event', () => {
|
||||
sandbox.addEventListener('drag:start', (event) => {
|
||||
event.detail.cancel();
|
||||
});
|
||||
@ -57,11 +48,10 @@ describe('MouseSensor', () => {
|
||||
releaseMouse(draggableElement);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveCanceledSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event releasing mouse before timeout', () => {
|
||||
it('does not trigger `drag:start` event releasing mouse before timeout', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -73,22 +63,16 @@ describe('MouseSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('triggers `drag:move` event while moving the mouse', () => {
|
||||
it('triggers `drag:move` event while moving the mouse', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -96,11 +80,10 @@ describe('MouseSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:move');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
|
||||
});
|
||||
|
||||
test('triggers `drag:stop` event when releasing mouse', () => {
|
||||
it('triggers `drag:stop` event when releasing mouse', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -108,11 +91,10 @@ describe('MouseSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event when right clicking or holding ctrl or meta key', () => {
|
||||
it('does not trigger `drag:start` event when right clicking or holding ctrl or meta key', () => {
|
||||
function dragFlowWithRightClick() {
|
||||
clickMouse(draggableElement, {button: 2});
|
||||
waitForDragDelay();
|
||||
@ -131,61 +113,45 @@ describe('MouseSensor', () => {
|
||||
releaseMouse(document.body);
|
||||
}
|
||||
|
||||
[
|
||||
dragFlowWithRightClick,
|
||||
dragFlowWithCtrlKey,
|
||||
dragFlowWithMetaKey,
|
||||
].forEach((dragFlow) => {
|
||||
expect(dragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
[dragFlowWithRightClick, dragFlowWithCtrlKey, dragFlowWithMetaKey].forEach((dragFlow) => {
|
||||
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event when clicking on none draggable element', () => {
|
||||
it('does not trigger `drag:start` event when clicking on none draggable element', () => {
|
||||
function dragFlow() {
|
||||
clickMouse(document.body);
|
||||
waitForDragDelay();
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('prevents context menu while dragging', () => {
|
||||
it('prevents context menu while dragging', () => {
|
||||
let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
|
||||
|
||||
expect(contextMenuEvent)
|
||||
.not
|
||||
.toHaveDefaultPrevented();
|
||||
expect(contextMenuEvent).not.toHaveDefaultPrevented();
|
||||
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
|
||||
|
||||
expect(contextMenuEvent)
|
||||
.toHaveDefaultPrevented();
|
||||
expect(contextMenuEvent).toHaveDefaultPrevented();
|
||||
|
||||
releaseMouse(draggableElement);
|
||||
});
|
||||
|
||||
test('prevents native drag when initiating drag flow', () => {
|
||||
it('prevents native drag when initiating drag flow', () => {
|
||||
let dragEvent = triggerEvent(draggableElement, 'dragstart');
|
||||
|
||||
expect(dragEvent)
|
||||
.not
|
||||
.toHaveDefaultPrevented();
|
||||
expect(dragEvent).not.toHaveDefaultPrevented();
|
||||
|
||||
clickMouse(draggableElement);
|
||||
waitForDragDelay();
|
||||
dragEvent = triggerEvent(draggableElement, 'dragstart');
|
||||
|
||||
expect(dragEvent)
|
||||
.toHaveDefaultPrevented();
|
||||
expect(dragEvent).toHaveDefaultPrevented();
|
||||
|
||||
releaseMouse(document.body);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* @module Sensor
|
||||
*/
|
||||
export default class Sensor {
|
||||
|
||||
/**
|
||||
* Sensor constructor.
|
||||
* @constructs Sensor
|
||||
@ -12,7 +11,6 @@ export default class Sensor {
|
||||
* @param {Object} options - Options
|
||||
*/
|
||||
constructor(containers = [], options = {}) {
|
||||
|
||||
/**
|
||||
* Current containers
|
||||
* @property containers
|
||||
@ -69,6 +67,7 @@ export default class Sensor {
|
||||
event.initEvent(sensorEvent.type, true, true);
|
||||
element.dispatchEvent(event);
|
||||
this.lastEvent = sensorEvent;
|
||||
|
||||
return sensorEvent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,14 +2,14 @@ import Sensor from '../Sensor';
|
||||
|
||||
describe('Sensor', () => {
|
||||
describe('#constructor', () => {
|
||||
test('should initialize with default containers and options', () => {
|
||||
it('should initialize with default containers and options', () => {
|
||||
const sensor = new Sensor();
|
||||
|
||||
expect(sensor.containers).toMatchObject([]);
|
||||
expect(sensor.options).toMatchObject({});
|
||||
});
|
||||
|
||||
test('should initialize with containers and options', () => {
|
||||
it('should initialize with containers and options', () => {
|
||||
const expectedContainers = ['expectedContainer'];
|
||||
const expectedOptions = {expectedOptions: true};
|
||||
const sensor = new Sensor(expectedContainers, expectedOptions);
|
||||
@ -20,9 +20,8 @@ describe('Sensor', () => {
|
||||
});
|
||||
|
||||
describe('#attach', () => {
|
||||
test('should return self', () => {
|
||||
it('should return self', () => {
|
||||
const sensor = new Sensor();
|
||||
|
||||
const returnValue = sensor.attach();
|
||||
|
||||
expect(returnValue).toBe(sensor);
|
||||
@ -30,9 +29,8 @@ describe('Sensor', () => {
|
||||
});
|
||||
|
||||
describe('#detach', () => {
|
||||
test('should return self', () => {
|
||||
it('should return self', () => {
|
||||
const sensor = new Sensor();
|
||||
|
||||
const returnValue = sensor.attach();
|
||||
|
||||
expect(returnValue).toBe(sensor);
|
||||
@ -40,7 +38,7 @@ describe('Sensor', () => {
|
||||
});
|
||||
|
||||
describe('#trigger', () => {
|
||||
test('should dispatch event on element', () => {
|
||||
it('should dispatch event on element', () => {
|
||||
const sensor = new Sensor();
|
||||
const element = document.createElement('div');
|
||||
const expectedEvent = {
|
||||
@ -50,9 +48,13 @@ describe('Sensor', () => {
|
||||
|
||||
let eventDispatched;
|
||||
|
||||
element.addEventListener('my:event', (event) => {
|
||||
eventDispatched = event;
|
||||
}, true);
|
||||
element.addEventListener(
|
||||
'my:event',
|
||||
(event) => {
|
||||
eventDispatched = event;
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
const returnValue = sensor.trigger(element, expectedEvent);
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ import AbstractEvent from 'shared/AbstractEvent';
|
||||
* @extends AbstractEvent
|
||||
*/
|
||||
export class SensorEvent extends AbstractEvent {
|
||||
|
||||
/**
|
||||
* Original browser event that triggered a sensor
|
||||
* @property originalEvent
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import {closest} from 'shared/utils';
|
||||
import Sensor from '../Sensor';
|
||||
|
||||
import {
|
||||
DragStartSensorEvent,
|
||||
DragMoveSensorEvent,
|
||||
DragStopSensorEvent,
|
||||
} from '../SensorEvent';
|
||||
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
|
||||
|
||||
const onTouchStart = Symbol('onTouchStart');
|
||||
const onTouchHold = Symbol('onTouchHold');
|
||||
@ -16,9 +11,11 @@ const onScroll = Symbol('onScroll');
|
||||
/**
|
||||
* Adds default document.ontouchmove. Workaround for preventing scrolling on touchmove
|
||||
*/
|
||||
document.ontouchmove = document.ontouchmove || function() {
|
||||
return true;
|
||||
};
|
||||
document.ontouchmove =
|
||||
document.ontouchmove ||
|
||||
function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* This sensor picks up native browser touch events and dictates drag operations
|
||||
@ -27,7 +24,6 @@ document.ontouchmove = document.ontouchmove || function() {
|
||||
* @extends Sensor
|
||||
*/
|
||||
export default class TouchSensor extends Sensor {
|
||||
|
||||
/**
|
||||
* TouchSensor constructor.
|
||||
* @constructs TouchSensor
|
||||
@ -118,7 +114,9 @@ export default class TouchSensor extends Sensor {
|
||||
*/
|
||||
[onTouchHold](event, container) {
|
||||
return () => {
|
||||
if (this.touchMoved) { return; }
|
||||
if (this.touchMoved) {
|
||||
return;
|
||||
}
|
||||
|
||||
const touch = event.touches[0] || event.changedTouches[0];
|
||||
const target = event.target;
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
createSandbox,
|
||||
triggerEvent,
|
||||
waitForDragDelay,
|
||||
DRAG_DELAY,
|
||||
touchStart,
|
||||
touchMove,
|
||||
touchRelease,
|
||||
} from 'helper';
|
||||
import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, touchStart, touchMove, touchRelease} from 'helper';
|
||||
|
||||
import TouchSensor from '..';
|
||||
|
||||
@ -35,18 +27,17 @@ describe('TouchSensor', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('triggers `drag:start` sensor event on touchstart', () => {
|
||||
it('triggers `drag:start` sensor event on touchstart', () => {
|
||||
function dragFlow() {
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
touchRelease(draggableElement);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('cancels `drag:start` event when canceling sensor event', () => {
|
||||
it('cancels `drag:start` event when canceling sensor event', () => {
|
||||
sandbox.addEventListener('drag:start', (event) => {
|
||||
event.detail.cancel();
|
||||
});
|
||||
@ -57,11 +48,10 @@ describe('TouchSensor', () => {
|
||||
touchRelease(draggableElement);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveCanceledSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event releasing finger before timeout', () => {
|
||||
it('does not trigger `drag:start` event releasing finger before timeout', () => {
|
||||
function dragFlow() {
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -73,22 +63,16 @@ describe('TouchSensor', () => {
|
||||
touchRelease(document.body);
|
||||
}
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(hastyDragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('triggers `drag:move` event while moving the finger', () => {
|
||||
it('triggers `drag:move` event while moving the finger', () => {
|
||||
function dragFlow() {
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -96,11 +80,10 @@ describe('TouchSensor', () => {
|
||||
touchRelease(draggableElement);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:move');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
|
||||
});
|
||||
|
||||
test('triggers `drag:stop` event when releasing the finger', () => {
|
||||
it('triggers `drag:stop` event when releasing the finger', () => {
|
||||
function dragFlow() {
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
@ -108,87 +91,72 @@ describe('TouchSensor', () => {
|
||||
touchRelease(draggableElement);
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.toHaveTriggeredSensorEvent('drag:stop');
|
||||
expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
|
||||
});
|
||||
|
||||
test('does not trigger `drag:start` event when holding finger on none draggable element', () => {
|
||||
it('does not trigger `drag:start` event when holding finger on none draggable element', () => {
|
||||
function dragFlow() {
|
||||
touchStart(document.body);
|
||||
waitForDragDelay();
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('cancels `drag:start` if browser starts scrolling instead', () => {
|
||||
it('cancels `drag:start` if browser starts scrolling instead', () => {
|
||||
function dragFlow() {
|
||||
touchStart(draggableElement);
|
||||
triggerEvent(document.body, 'scroll');
|
||||
waitForDragDelay();
|
||||
}
|
||||
|
||||
expect(dragFlow)
|
||||
.not
|
||||
.toHaveTriggeredSensorEvent('drag:start');
|
||||
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
|
||||
});
|
||||
|
||||
test('prevents context menu while dragging', () => {
|
||||
it('prevents context menu while dragging', () => {
|
||||
touchStart(draggableElement);
|
||||
let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
|
||||
waitForDragDelay();
|
||||
|
||||
expect(contextMenuEvent.defaultPrevented)
|
||||
.toBe(true);
|
||||
expect(contextMenuEvent.defaultPrevented).toBe(true);
|
||||
|
||||
expect(contextMenuEvent.stoppedPropagation)
|
||||
.toBe(true);
|
||||
expect(contextMenuEvent.stoppedPropagation).toBe(true);
|
||||
|
||||
touchRelease(draggableElement);
|
||||
contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
|
||||
|
||||
expect(contextMenuEvent.defaultPrevented)
|
||||
.toBe(false);
|
||||
expect(contextMenuEvent.defaultPrevented).toBe(false);
|
||||
|
||||
expect(contextMenuEvent.stoppedPropagation)
|
||||
.toBeUndefined();
|
||||
expect(contextMenuEvent.stoppedPropagation).toBeUndefined();
|
||||
});
|
||||
|
||||
test('prevents scroll on touchmove while dragging', () => {
|
||||
it('prevents scroll on touchmove while dragging', () => {
|
||||
let touchMoveEvent = touchMove(draggableElement);
|
||||
|
||||
expect(touchMoveEvent.defaultPrevented)
|
||||
.toBe(false);
|
||||
expect(touchMoveEvent.defaultPrevented).toBe(false);
|
||||
|
||||
expect(touchMoveEvent.stoppedPropagation)
|
||||
.toBeUndefined();
|
||||
expect(touchMoveEvent.stoppedPropagation).toBeUndefined();
|
||||
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
touchMoveEvent = touchMove(draggableElement);
|
||||
|
||||
expect(touchMoveEvent.defaultPrevented)
|
||||
.toBe(true);
|
||||
expect(touchMoveEvent.defaultPrevented).toBe(true);
|
||||
|
||||
expect(touchMoveEvent.stoppedPropagation)
|
||||
.toBe(true);
|
||||
expect(touchMoveEvent.stoppedPropagation).toBe(true);
|
||||
|
||||
touchRelease(draggableElement);
|
||||
});
|
||||
|
||||
test('prevents clicking on touchend after dragging', () => {
|
||||
it('prevents clicking on touchend after dragging', () => {
|
||||
let touchEndEvent = touchRelease(draggableElement);
|
||||
|
||||
expect(touchEndEvent.defaultPrevented)
|
||||
.toBe(false);
|
||||
expect(touchEndEvent.defaultPrevented).toBe(false);
|
||||
|
||||
touchStart(draggableElement);
|
||||
waitForDragDelay();
|
||||
touchEndEvent = touchRelease(draggableElement);
|
||||
|
||||
expect(touchEndEvent.defaultPrevented)
|
||||
.toBe(true);
|
||||
expect(touchEndEvent.defaultPrevented).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,35 +1,9 @@
|
||||
import {
|
||||
createSandbox,
|
||||
triggerEvent,
|
||||
TestPlugin,
|
||||
} from 'helper';
|
||||
|
||||
import Draggable, {
|
||||
defaultOptions,
|
||||
} from '../Draggable';
|
||||
|
||||
import {
|
||||
DragStartEvent,
|
||||
DragMoveEvent,
|
||||
DragStopEvent,
|
||||
} from '../DragEvent';
|
||||
|
||||
import {
|
||||
DraggableInitializedEvent,
|
||||
DraggableDestroyEvent,
|
||||
} from '../DraggableEvent';
|
||||
|
||||
import {
|
||||
Accessibility,
|
||||
Mirror,
|
||||
Scrollable,
|
||||
Announcement,
|
||||
} from '../Plugins';
|
||||
|
||||
import {
|
||||
MouseSensor,
|
||||
TouchSensor,
|
||||
} from '../Sensors';
|
||||
import {createSandbox, triggerEvent, TestPlugin} from 'helper';
|
||||
import Draggable, {defaultOptions} from '../Draggable';
|
||||
import {DragStartEvent, DragMoveEvent, DragStopEvent} from '../DragEvent';
|
||||
import {DraggableInitializedEvent, DraggableDestroyEvent} from '../DraggableEvent';
|
||||
import {Accessibility, Mirror, Scrollable, Announcement} from '../Plugins';
|
||||
import {MouseSensor, TouchSensor} from '../Sensors';
|
||||
|
||||
const sampleMarkup = `
|
||||
<ul>
|
||||
@ -54,7 +28,7 @@ describe('Draggable', () => {
|
||||
});
|
||||
|
||||
describe('.Plugins', () => {
|
||||
test('should be available statically', () => {
|
||||
it('should be available statically', () => {
|
||||
expect(Draggable.Plugins).toBeDefined();
|
||||
expect(Draggable.Plugins.Mirror).toEqual(Mirror);
|
||||
expect(Draggable.Plugins.Accessibility).toEqual(Accessibility);
|
||||
@ -63,7 +37,7 @@ describe('Draggable', () => {
|
||||
});
|
||||
|
||||
describe('#constructor', () => {
|
||||
test('should be an instance of Draggable', () => {
|
||||
it('should be an instance of Draggable', () => {
|
||||
const draggable = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
delay: 0,
|
||||
@ -72,32 +46,29 @@ describe('Draggable', () => {
|
||||
expect(draggable).toBeInstanceOf(Draggable);
|
||||
});
|
||||
|
||||
test('should initialize with default options', () => {
|
||||
it('should initialize with default options', () => {
|
||||
const newInstance = new Draggable(containers);
|
||||
|
||||
for (const key in defaultOptions) {
|
||||
if (defaultOptions.hasOwnProperty(key)) {
|
||||
expect(newInstance.options[key])
|
||||
.toBe(defaultOptions[key]);
|
||||
expect(newInstance.options[key]).toBe(defaultOptions[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('should set containers', () => {
|
||||
it('should set containers', () => {
|
||||
const newInstance = new Draggable(containers);
|
||||
|
||||
expect(newInstance.containers)
|
||||
.toMatchObject(Array.prototype.slice.call(containers));
|
||||
expect(newInstance.containers).toMatchObject(Array.prototype.slice.call(containers));
|
||||
});
|
||||
|
||||
test('should set single container if a list is not passed', () => {
|
||||
it('should set single container if a list is not passed', () => {
|
||||
const newInstance = new Draggable(containers[0]);
|
||||
|
||||
expect(newInstance.containers)
|
||||
.toMatchObject([containers[0]]);
|
||||
expect(newInstance.containers).toMatchObject([containers[0]]);
|
||||
});
|
||||
|
||||
test('should throw error if `containers` argument is wrong type', () => {
|
||||
it('should throw error if `containers` argument is wrong type', () => {
|
||||
expect(() => {
|
||||
return new Draggable({});
|
||||
}).toThrow();
|
||||
@ -107,72 +78,57 @@ describe('Draggable', () => {
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test('should attach default plugins', () => {
|
||||
it('should attach default plugins', () => {
|
||||
const newInstance = new Draggable();
|
||||
|
||||
expect(newInstance.plugins.length)
|
||||
.toBe(4);
|
||||
expect(newInstance.plugins).toHaveLength(4);
|
||||
|
||||
expect(newInstance.plugins[0])
|
||||
.toBeInstanceOf(Mirror);
|
||||
expect(newInstance.plugins[0]).toBeInstanceOf(Mirror);
|
||||
|
||||
expect(newInstance.plugins[1])
|
||||
.toBeInstanceOf(Accessibility);
|
||||
expect(newInstance.plugins[1]).toBeInstanceOf(Accessibility);
|
||||
|
||||
expect(newInstance.plugins[2])
|
||||
.toBeInstanceOf(Scrollable);
|
||||
expect(newInstance.plugins[2]).toBeInstanceOf(Scrollable);
|
||||
|
||||
expect(newInstance.plugins[3])
|
||||
.toBeInstanceOf(Announcement);
|
||||
expect(newInstance.plugins[3]).toBeInstanceOf(Announcement);
|
||||
});
|
||||
|
||||
test('should attach custom plugins', () => {
|
||||
it('should attach custom plugins', () => {
|
||||
const newInstance = new Draggable([], {
|
||||
plugins: [TestPlugin],
|
||||
});
|
||||
|
||||
expect(newInstance.plugins.length)
|
||||
.toBe(5);
|
||||
expect(newInstance.plugins).toHaveLength(5);
|
||||
|
||||
const customPlugin = newInstance.plugins[4];
|
||||
|
||||
expect(customPlugin.draggable).toBe(newInstance);
|
||||
|
||||
expect(customPlugin.attachFunction)
|
||||
.toHaveBeenCalled();
|
||||
expect(customPlugin.attachFunction).toHaveBeenCalled();
|
||||
|
||||
expect(customPlugin.detachFunction)
|
||||
.not
|
||||
.toHaveBeenCalled();
|
||||
expect(customPlugin.detachFunction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should attach sensors', () => {
|
||||
it('should attach sensors', () => {
|
||||
const newInstance = new Draggable([], {
|
||||
native: false,
|
||||
});
|
||||
|
||||
expect(newInstance.sensors.length)
|
||||
.toBe(2);
|
||||
expect(newInstance.sensors).toHaveLength(2);
|
||||
|
||||
expect(newInstance.sensors[0])
|
||||
.toBeInstanceOf(MouseSensor);
|
||||
expect(newInstance.sensors[0]).toBeInstanceOf(MouseSensor);
|
||||
|
||||
expect(newInstance.sensors[1])
|
||||
.toBeInstanceOf(TouchSensor);
|
||||
expect(newInstance.sensors[1]).toBeInstanceOf(TouchSensor);
|
||||
});
|
||||
|
||||
test('should trigger DraggableInitializedEvent on init', () => {
|
||||
it('should trigger DraggableInitializedEvent on init', () => {
|
||||
const spy = jest.spyOn(Draggable.prototype, 'trigger');
|
||||
const newInstance = new Draggable();
|
||||
|
||||
expect(spy.mock.calls.length)
|
||||
.toBe(1);
|
||||
expect(spy.mock.calls).toHaveLength(1);
|
||||
|
||||
expect(spy.mock.calls[0][0])
|
||||
.toBeInstanceOf(DraggableInitializedEvent);
|
||||
expect(spy.mock.calls[0][0]).toBeInstanceOf(DraggableInitializedEvent);
|
||||
|
||||
expect(spy.mock.calls[0][0].draggable)
|
||||
.toBe(newInstance);
|
||||
expect(spy.mock.calls[0][0].draggable).toBe(newInstance);
|
||||
|
||||
spy.mockReset();
|
||||
spy.mockRestore();
|
||||
@ -180,7 +136,7 @@ describe('Draggable', () => {
|
||||
});
|
||||
|
||||
describe('#destroy', () => {
|
||||
test('triggers `draggable:destroy` event on destroy', () => {
|
||||
it('triggers `draggable:destroy` event on destroy', () => {
|
||||
const newInstance = new Draggable();
|
||||
const callback = jest.fn();
|
||||
|
||||
@ -190,17 +146,14 @@ describe('Draggable', () => {
|
||||
|
||||
const call = callback.mock.calls[0][0];
|
||||
|
||||
expect(call.type)
|
||||
.toBe('draggable:destroy');
|
||||
expect(call.type).toBe('draggable:destroy');
|
||||
|
||||
expect(call)
|
||||
.toBeInstanceOf(DraggableDestroyEvent);
|
||||
expect(call).toBeInstanceOf(DraggableDestroyEvent);
|
||||
|
||||
expect(call.draggable)
|
||||
.toBe(newInstance);
|
||||
expect(call.draggable).toBe(newInstance);
|
||||
});
|
||||
|
||||
test('should call Plugin#detach once on each of provided plugins', () => {
|
||||
it('should call Plugin#detach once on each of provided plugins', () => {
|
||||
const plugins = [TestPlugin, TestPlugin, TestPlugin];
|
||||
const newInstance = new Draggable([], {
|
||||
plugins,
|
||||
@ -209,26 +162,20 @@ describe('Draggable', () => {
|
||||
|
||||
newInstance.destroy();
|
||||
|
||||
expect(expectedPlugins[4].detachFunction)
|
||||
.toHaveBeenCalled();
|
||||
expect(expectedPlugins[4].detachFunction).toHaveBeenCalled();
|
||||
|
||||
expect(expectedPlugins[4].detachFunction)
|
||||
.toHaveBeenCalledTimes(1);
|
||||
expect(expectedPlugins[4].detachFunction).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(expectedPlugins[5].detachFunction)
|
||||
.toHaveBeenCalled();
|
||||
expect(expectedPlugins[5].detachFunction).toHaveBeenCalled();
|
||||
|
||||
expect(expectedPlugins[5].detachFunction)
|
||||
.toHaveBeenCalledTimes(1);
|
||||
expect(expectedPlugins[5].detachFunction).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(expectedPlugins[6].detachFunction)
|
||||
.toHaveBeenCalled();
|
||||
expect(expectedPlugins[6].detachFunction).toHaveBeenCalled();
|
||||
|
||||
expect(expectedPlugins[6].detachFunction)
|
||||
.toHaveBeenCalledTimes(1);
|
||||
expect(expectedPlugins[6].detachFunction).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should remove all sensor event listeners', () => {
|
||||
it('should remove all sensor event listeners', () => {
|
||||
document.removeEventListener = jest.fn();
|
||||
|
||||
const newInstance = new Draggable();
|
||||
@ -247,73 +194,71 @@ describe('Draggable', () => {
|
||||
});
|
||||
|
||||
describe('#on', () => {
|
||||
test('should add an event handler to the list of callbacks', () => {
|
||||
it('should add an event handler to the list of callbacks', () => {
|
||||
const newInstance = new Draggable();
|
||||
function stubHandler() { /* do nothing */ }
|
||||
function stubHandler() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(false);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(false);
|
||||
|
||||
newInstance.on('my:event', stubHandler);
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(true);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(true);
|
||||
|
||||
expect(newInstance.emitter.callbacks['my:event'])
|
||||
.toMatchObject([stubHandler]);
|
||||
expect(newInstance.emitter.callbacks['my:event']).toMatchObject([stubHandler]);
|
||||
});
|
||||
|
||||
test('should return draggable instance', () => {
|
||||
it('should return draggable instance', () => {
|
||||
const newInstance = new Draggable();
|
||||
function stubHandler() { /* do nothing */ }
|
||||
function stubHandler() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(false);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(false);
|
||||
|
||||
const returnValue = newInstance.on('my:event', stubHandler);
|
||||
|
||||
expect(returnValue)
|
||||
.toBe(newInstance);
|
||||
expect(returnValue).toBe(newInstance);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#off', () => {
|
||||
test('should remove event handler from the list of callbacks', () => {
|
||||
it('should remove event handler from the list of callbacks', () => {
|
||||
const newInstance = new Draggable();
|
||||
function stubHandler() { /* do nothing */ }
|
||||
function stubHandler() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
newInstance.on('my:event', stubHandler);
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(true);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(true);
|
||||
|
||||
newInstance.off('my:event', stubHandler);
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(true);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(true);
|
||||
|
||||
expect(newInstance.emitter.callbacks['my:event'])
|
||||
.toMatchObject([]);
|
||||
expect(newInstance.emitter.callbacks['my:event']).toMatchObject([]);
|
||||
});
|
||||
|
||||
test('should return draggable instance', () => {
|
||||
it('should return draggable instance', () => {
|
||||
const newInstance = new Draggable();
|
||||
function stubHandler() { /* do nothing */ }
|
||||
function stubHandler() {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
newInstance.on('my:event', stubHandler);
|
||||
|
||||
expect('my:event' in newInstance.emitter.callbacks)
|
||||
.toBe(true);
|
||||
expect('my:event' in newInstance.emitter.callbacks).toBe(true);
|
||||
|
||||
const returnValue = newInstance.off('my:event', stubHandler);
|
||||
|
||||
expect(returnValue)
|
||||
.toBe(newInstance);
|
||||
expect(returnValue).toBe(newInstance);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#trigger', () => {
|
||||
test('should invoke bound event', () => {
|
||||
it('should invoke bound event', () => {
|
||||
const newInstance = new Draggable(containers);
|
||||
const handler = jest.fn();
|
||||
const expectedEvent = new Event('my:event');
|
||||
@ -322,19 +267,16 @@ describe('Draggable', () => {
|
||||
|
||||
newInstance.trigger(expectedEvent);
|
||||
|
||||
expect(handler.mock.calls.length)
|
||||
.toBe(1);
|
||||
expect(handler.mock.calls).toHaveLength(1);
|
||||
|
||||
expect(handler.mock.calls[0].length)
|
||||
.toBe(1);
|
||||
expect(handler.mock.calls[0]).toHaveLength(1);
|
||||
|
||||
expect(handler.mock.calls[0][0])
|
||||
.toBe(expectedEvent);
|
||||
expect(handler.mock.calls[0][0]).toBe(expectedEvent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getDraggableElementsForContainer', () => {
|
||||
test('returns draggable elements, excluding mirror and original source', () => {
|
||||
it('returns draggable elements, excluding mirror and original source', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -348,13 +290,13 @@ describe('Draggable', () => {
|
||||
|
||||
const containerChildren = newInstance.getDraggableElementsForContainer(draggableElement.parentNode);
|
||||
|
||||
expect(containerChildren.length).toEqual(2);
|
||||
expect(containerChildren).toHaveLength(2);
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup', {button: 0});
|
||||
});
|
||||
});
|
||||
|
||||
test('triggers `drag:start` drag event on mousedown', () => {
|
||||
it('triggers `drag:start` drag event on mousedown', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -371,16 +313,14 @@ describe('Draggable', () => {
|
||||
|
||||
const call = callback.mock.calls[0][0];
|
||||
|
||||
expect(call.type)
|
||||
.toBe('drag:start');
|
||||
expect(call.type).toBe('drag:start');
|
||||
|
||||
expect(call)
|
||||
.toBeInstanceOf(DragStartEvent);
|
||||
expect(call).toBeInstanceOf(DragStartEvent);
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup');
|
||||
});
|
||||
|
||||
test('should trigger `drag:start` drag event on dragstart', () => {
|
||||
it('should trigger `drag:start` drag event on dragstart', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -399,16 +339,14 @@ describe('Draggable', () => {
|
||||
|
||||
const call = callback.mock.calls[0][0];
|
||||
|
||||
expect(call.type)
|
||||
.toBe('drag:start');
|
||||
expect(call.type).toBe('drag:start');
|
||||
|
||||
expect(call)
|
||||
.toBeInstanceOf(DragStartEvent);
|
||||
expect(call).toBeInstanceOf(DragStartEvent);
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup');
|
||||
});
|
||||
|
||||
test('cleans up when `drag:start` event is canceled', () => {
|
||||
it('cleans up when `drag:start` event is canceled', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -437,7 +375,7 @@ describe('Draggable', () => {
|
||||
expect(originalSource.style.display).toEqual('');
|
||||
});
|
||||
|
||||
test('triggers `drag:move` drag event on mousedown', () => {
|
||||
it('triggers `drag:move` drag event on mousedown', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -460,22 +398,18 @@ describe('Draggable', () => {
|
||||
const call = callback.mock.calls[0][0];
|
||||
const sensorEvent = call.data.sensorEvent;
|
||||
|
||||
expect(call.type)
|
||||
.toBe('drag:move');
|
||||
expect(call.type).toBe('drag:move');
|
||||
|
||||
expect(call)
|
||||
.toBeInstanceOf(DragMoveEvent);
|
||||
expect(call).toBeInstanceOf(DragMoveEvent);
|
||||
|
||||
expect(sensorEvent.clientX)
|
||||
.toBe(expectedClientX);
|
||||
expect(sensorEvent.clientX).toBe(expectedClientX);
|
||||
|
||||
expect(sensorEvent.clientY)
|
||||
.toBe(expectedClientY);
|
||||
expect(sensorEvent.clientY).toBe(expectedClientY);
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup');
|
||||
});
|
||||
|
||||
test('triggers `drag:stop` drag event on mouseup', () => {
|
||||
it('triggers `drag:stop` drag event on mouseup', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -494,14 +428,12 @@ describe('Draggable', () => {
|
||||
|
||||
const call = callback.mock.calls[0][0];
|
||||
|
||||
expect(call.type)
|
||||
.toBe('drag:stop');
|
||||
expect(call.type).toBe('drag:stop');
|
||||
|
||||
expect(call)
|
||||
.toBeInstanceOf(DragStopEvent);
|
||||
expect(call).toBeInstanceOf(DragStopEvent);
|
||||
});
|
||||
|
||||
test('adds `source:dragging` classname to draggable element on mousedown', () => {
|
||||
it('adds `source:dragging` classname to draggable element on mousedown', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -513,13 +445,12 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(newInstance.source.classList)
|
||||
.toContain('draggable-source--is-dragging');
|
||||
expect(newInstance.source.classList).toContain('draggable-source--is-dragging');
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup');
|
||||
});
|
||||
|
||||
test('removes `source:dragging` classname from draggable element on mouseup', () => {
|
||||
it('removes `source:dragging` classname from draggable element on mouseup', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -533,17 +464,14 @@ describe('Draggable', () => {
|
||||
|
||||
const source = newInstance.source;
|
||||
|
||||
expect(source.classList)
|
||||
.toContain('draggable-source--is-dragging');
|
||||
expect(source.classList).toContain('draggable-source--is-dragging');
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup', {button: 0});
|
||||
|
||||
expect(source.classList)
|
||||
.not
|
||||
.toContain('draggable-source--is-dragging');
|
||||
expect(source.classList).not.toContain('draggable-source--is-dragging');
|
||||
});
|
||||
|
||||
test('removes `source:dragging` classname from draggable element on dragEvent.cancel()', () => {
|
||||
it('removes `source:dragging` classname from draggable element on dragEvent.cancel()', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -551,8 +479,7 @@ describe('Draggable', () => {
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
newInstance.on('drag:start', (event) => {
|
||||
expect(newInstance.source.classList)
|
||||
.toContain('draggable-source--is-dragging');
|
||||
expect(newInstance.source.classList).toContain('draggable-source--is-dragging');
|
||||
|
||||
event.cancel();
|
||||
});
|
||||
@ -564,15 +491,14 @@ describe('Draggable', () => {
|
||||
|
||||
const source = newInstance.source;
|
||||
|
||||
expect(source.classList)
|
||||
.not
|
||||
.toContain('draggable-source--is-dragging');
|
||||
expect(source.classList).not.toContain('draggable-source--is-dragging');
|
||||
});
|
||||
|
||||
test('adds `body:dragging` classname to body on mousedown', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('adds `body:dragging` classname to body on mousedown', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -581,16 +507,16 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(document.body.classList)
|
||||
.toContain('draggable--is-dragging');
|
||||
expect(document.body.classList).toContain('draggable--is-dragging');
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup');
|
||||
});
|
||||
|
||||
test('removes `body:dragging` classname from body on mouseup', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('removes `body:dragging` classname from body on mouseup', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -599,17 +525,14 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(document.body.classList)
|
||||
.toContain('draggable--is-dragging');
|
||||
expect(document.body.classList).toContain('draggable--is-dragging');
|
||||
|
||||
triggerEvent(document.body, 'mouseup', {button: 0});
|
||||
|
||||
expect(document.body.classList)
|
||||
.not
|
||||
.toContain('draggable--is-dragging');
|
||||
expect(document.body.classList).not.toContain('draggable--is-dragging');
|
||||
});
|
||||
|
||||
test('removes `body:dragging` classname from body on dragEvent.cancel()', () => {
|
||||
it('removes `body:dragging` classname from body on dragEvent.cancel()', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -617,8 +540,7 @@ describe('Draggable', () => {
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
newInstance.on('drag:start', (event) => {
|
||||
expect(document.body.classList)
|
||||
.toContain('draggable--is-dragging');
|
||||
expect(document.body.classList).toContain('draggable--is-dragging');
|
||||
|
||||
event.cancel();
|
||||
});
|
||||
@ -628,15 +550,14 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(document.body.classList)
|
||||
.not
|
||||
.toContain('draggable--is-dragging');
|
||||
expect(document.body.classList).not.toContain('draggable--is-dragging');
|
||||
});
|
||||
|
||||
test('adds `container:placed` classname to draggable container element on mouseup', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('adds `container:placed` classname to draggable container element on mouseup', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -647,14 +568,14 @@ describe('Draggable', () => {
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup', {button: 0});
|
||||
|
||||
expect(containers[0].classList)
|
||||
.toContain('draggable-container--placed');
|
||||
expect(containers[0].classList).toContain('draggable-container--placed');
|
||||
});
|
||||
|
||||
test('removes `container:placed` classname from draggable container element on mouseup after delay', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('removes `container:placed` classname from draggable container element on mouseup after delay', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -665,21 +586,19 @@ describe('Draggable', () => {
|
||||
|
||||
triggerEvent(document.body, 'mouseup', {button: 0});
|
||||
|
||||
expect(containers[0].classList)
|
||||
.toContain('draggable-container--placed');
|
||||
expect(containers[0].classList).toContain('draggable-container--placed');
|
||||
|
||||
// Wait for default draggable.options.placedTimeout delay
|
||||
jest.runTimersToTime(800);
|
||||
|
||||
expect(containers[0].classList)
|
||||
.not
|
||||
.toContain('draggable-container--placed');
|
||||
expect(containers[0].classList).not.toContain('draggable-container--placed');
|
||||
});
|
||||
|
||||
test('adds `container:dragging` classname to draggable container element on mousedown', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('adds `container:dragging` classname to draggable container element on mousedown', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -688,16 +607,16 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(containers[0].classList)
|
||||
.toContain('draggable-container--is-dragging');
|
||||
expect(containers[0].classList).toContain('draggable-container--is-dragging');
|
||||
|
||||
triggerEvent(draggableElement, 'mouseup', {button: 0});
|
||||
});
|
||||
|
||||
test('removes `container:dragging` classname from draggable container element on mouseup', () => {
|
||||
(() => new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
it('removes `container:dragging` classname from draggable container element on mouseup', () => {
|
||||
(() =>
|
||||
new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
}))();
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
document.elementFromPoint = () => draggableElement;
|
||||
|
||||
@ -706,25 +625,21 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(containers[0].classList)
|
||||
.toContain('draggable-container--is-dragging');
|
||||
expect(containers[0].classList).toContain('draggable-container--is-dragging');
|
||||
|
||||
triggerEvent(document.body, 'mouseup', {button: 0});
|
||||
|
||||
expect(containers[0].classList)
|
||||
.not
|
||||
.toContain('draggable-container--is-dragging');
|
||||
expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
|
||||
});
|
||||
|
||||
test('removes `container:dragging` classname from draggable container element on dragEvent.cancel()', () => {
|
||||
it('removes `container:dragging` classname from draggable container element on dragEvent.cancel()', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
const draggableElement = sandbox.querySelector('li');
|
||||
|
||||
newInstance.on('drag:start', (event) => {
|
||||
expect(containers[0].classList)
|
||||
.toContain('draggable-container--is-dragging');
|
||||
expect(containers[0].classList).toContain('draggable-container--is-dragging');
|
||||
|
||||
event.cancel();
|
||||
});
|
||||
@ -734,12 +649,10 @@ describe('Draggable', () => {
|
||||
// Wait for delay
|
||||
jest.runTimersToTime(100);
|
||||
|
||||
expect(containers[0].classList)
|
||||
.not
|
||||
.toContain('draggable-container--is-dragging');
|
||||
expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
|
||||
});
|
||||
|
||||
test('adds and removes `source:original` on start and stop', () => {
|
||||
it('adds and removes `source:original` on start and stop', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
@ -758,7 +671,7 @@ describe('Draggable', () => {
|
||||
expect(draggableElement.classList.contains(newInstance.getClassNameFor('source:original'))).toBeFalsy();
|
||||
});
|
||||
|
||||
test('`drag:out:container` event specifies leaving container', () => {
|
||||
it('`drag:out:container` event specifies leaving container', () => {
|
||||
const newInstance = new Draggable(containers, {
|
||||
draggable: 'li',
|
||||
});
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import {closest} from 'shared/utils';
|
||||
import Draggable from '../Draggable';
|
||||
|
||||
import {
|
||||
DroppableOverEvent,
|
||||
DroppableOutEvent,
|
||||
} from './DroppableEvent';
|
||||
import {DroppableOverEvent, DroppableOutEvent} from './DroppableEvent';
|
||||
|
||||
const onDragStart = Symbol('onDragStart');
|
||||
const onDragMove = Symbol('onDragMove');
|
||||
@ -65,7 +61,6 @@ const defaultOptions = {
|
||||
* @extends Draggable
|
||||
*/
|
||||
export default class Droppable extends Draggable {
|
||||
|
||||
/**
|
||||
* Droppable constructor.
|
||||
* @constructs Droppable
|
||||
@ -111,8 +106,7 @@ export default class Droppable extends Draggable {
|
||||
this[onDragMove] = this[onDragMove].bind(this);
|
||||
this[onDragStop] = this[onDragStop].bind(this);
|
||||
|
||||
this
|
||||
.on('drag:start', this[onDragStart])
|
||||
this.on('drag:start', this[onDragStart])
|
||||
.on('drag:move', this[onDragMove])
|
||||
.on('drag:stop', this[onDragStop]);
|
||||
}
|
||||
@ -123,8 +117,7 @@ export default class Droppable extends Draggable {
|
||||
destroy() {
|
||||
super.destroy();
|
||||
|
||||
this
|
||||
.off('drag:start', this[onDragStart])
|
||||
this.off('drag:start', this[onDragStart])
|
||||
.off('drag:move', this[onDragMove])
|
||||
.off('drag:stop', this[onDragStop]);
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import AbstractPlugin from 'shared/AbstractPlugin';
|
||||
import {closest} from 'shared/utils';
|
||||
|
||||
import {
|
||||
CollidableInEvent,
|
||||
CollidableOutEvent,
|
||||
} from './CollidableEvent';
|
||||
import {CollidableInEvent, CollidableOutEvent} from './CollidableEvent';
|
||||
|
||||
const onDragMove = Symbol('onDragMove');
|
||||
const onDragStop = Symbol('onDragStop');
|
||||
@ -17,7 +13,6 @@ const onRequestAnimationFrame = Symbol('onRequestAnimationFrame');
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Collidable extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Collidable constructor.
|
||||
* @constructs Collidable
|
||||
@ -56,18 +51,14 @@ export default class Collidable extends AbstractPlugin {
|
||||
* Attaches plugins event listeners
|
||||
*/
|
||||
attach() {
|
||||
this.draggable
|
||||
.on('drag:move', this[onDragMove])
|
||||
.on('drag:stop', this[onDragStop]);
|
||||
this.draggable.on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches plugins event listeners
|
||||
*/
|
||||
detach() {
|
||||
this.draggable
|
||||
.off('drag:move', this[onDragMove])
|
||||
.off('drag:stop', this[onDragStop]);
|
||||
this.draggable.off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +105,9 @@ export default class Collidable extends AbstractPlugin {
|
||||
collidingElement: this.lastCollidingElement,
|
||||
});
|
||||
|
||||
const enteringCollidable = Boolean(this.currentlyCollidingElement && this.lastCollidingElement !== this.currentlyCollidingElement);
|
||||
const enteringCollidable = Boolean(
|
||||
this.currentlyCollidingElement && this.lastCollidingElement !== this.currentlyCollidingElement,
|
||||
);
|
||||
const leavingCollidable = Boolean(!this.currentlyCollidingElement && this.lastCollidingElement);
|
||||
|
||||
if (enteringCollidable) {
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
import AbstractPlugin from 'shared/AbstractPlugin';
|
||||
|
||||
import {
|
||||
SnapInEvent,
|
||||
SnapOutEvent,
|
||||
} from './SnappableEvent';
|
||||
import {SnapInEvent, SnapOutEvent} from './SnappableEvent';
|
||||
|
||||
const onDragStart = Symbol('onDragStart');
|
||||
const onDragStop = Symbol('onDragStop');
|
||||
@ -17,7 +13,6 @@ const onDragOut = Symbol('onDragOut');
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class Snappable extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* Snappable constructor.
|
||||
* @constructs Snappable
|
||||
|
||||
@ -21,7 +21,6 @@ export const defaultOptions = {
|
||||
* @extends AbstractPlugin
|
||||
*/
|
||||
export default class SwapAnimation extends AbstractPlugin {
|
||||
|
||||
/**
|
||||
* SwapAnimation constructor.
|
||||
* @constructs SwapAnimation
|
||||
|
||||
@ -1,12 +1,3 @@
|
||||
export {
|
||||
default as Collidable,
|
||||
} from './Collidable';
|
||||
|
||||
export {
|
||||
default as Snappable,
|
||||
} from './Snappable';
|
||||
|
||||
export {
|
||||
default as SwapAnimation,
|
||||
defaultOptions as defaultSwapAnimationOptions,
|
||||
} from './SwapAnimation';
|
||||
export {default as Collidable} from './Collidable';
|
||||
export {default as Snappable} from './Snappable';
|
||||
export {default as SwapAnimation, defaultOptions as defaultSwapAnimationOptions} from './SwapAnimation';
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
import Draggable from '../Draggable';
|
||||
|
||||
import {
|
||||
SortableStartEvent,
|
||||
SortableSortEvent,
|
||||
SortableSortedEvent,
|
||||
SortableStopEvent,
|
||||
} from './SortableEvent';
|
||||
import {SortableStartEvent, SortableSortEvent, SortableSortedEvent, SortableStopEvent} from './SortableEvent';
|
||||
|
||||
const onDragStart = Symbol('onDragStart');
|
||||
const onDragOverContainer = Symbol('onDragOverContainer');
|
||||
@ -52,7 +46,6 @@ const defaultAnnouncements = {
|
||||
* @extends Draggable
|
||||
*/
|
||||
export default class Sortable extends Draggable {
|
||||
|
||||
/**
|
||||
* Sortable constructor.
|
||||
* @constructs Sortable
|
||||
@ -88,8 +81,7 @@ export default class Sortable extends Draggable {
|
||||
this[onDragOver] = this[onDragOver].bind(this);
|
||||
this[onDragStop] = this[onDragStop].bind(this);
|
||||
|
||||
this
|
||||
.on('drag:start', this[onDragStart])
|
||||
this.on('drag:start', this[onDragStart])
|
||||
.on('drag:over:container', this[onDragOverContainer])
|
||||
.on('drag:over', this[onDragOver])
|
||||
.on('drag:stop', this[onDragStop]);
|
||||
@ -101,8 +93,7 @@ export default class Sortable extends Draggable {
|
||||
destroy() {
|
||||
super.destroy();
|
||||
|
||||
this
|
||||
.off('drag:start', this[onDragStart])
|
||||
this.off('drag:start', this[onDragStart])
|
||||
.off('drag:over:container', this[onDragOverContainer])
|
||||
.off('drag:over', this[onDragOver])
|
||||
.off('drag:stop', this[onDragStop]);
|
||||
@ -260,7 +251,7 @@ function index(element) {
|
||||
|
||||
function move({source, over, overContainer, children}) {
|
||||
const emptyOverContainer = !children.length;
|
||||
const differentContainer = (source.parentNode !== overContainer);
|
||||
const differentContainer = source.parentNode !== overContainer;
|
||||
const sameContainer = over && !differentContainer;
|
||||
|
||||
if (emptyOverContainer) {
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
createSandbox,
|
||||
clickMouse,
|
||||
moveMouse,
|
||||
releaseMouse,
|
||||
waitForDragDelay,
|
||||
DRAG_DELAY,
|
||||
} from 'helper';
|
||||
|
||||
import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
|
||||
import Sortable from '..';
|
||||
|
||||
const sampleMarkup = `
|
||||
@ -69,7 +61,7 @@ describe('Sortable', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('triggers events', () => {
|
||||
it('triggers events', () => {
|
||||
const sortableStart = jest.fn();
|
||||
const sortableSort = jest.fn();
|
||||
const sortableSorted = jest.fn();
|
||||
@ -85,20 +77,16 @@ describe('Sortable', () => {
|
||||
moveMouse(secondItem);
|
||||
releaseMouse(sortable.source);
|
||||
|
||||
expect(sortableStart)
|
||||
.toHaveBeenCalled();
|
||||
expect(sortableStart).toHaveBeenCalled();
|
||||
|
||||
expect(sortableSort)
|
||||
.toHaveBeenCalled();
|
||||
expect(sortableSort).toHaveBeenCalled();
|
||||
|
||||
expect(sortableSorted)
|
||||
.toHaveBeenCalled();
|
||||
expect(sortableSorted).toHaveBeenCalled();
|
||||
|
||||
expect(sortableStop)
|
||||
.toHaveBeenCalled();
|
||||
expect(sortableStop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('prevents drag when canceling sortable start event', () => {
|
||||
it('prevents drag when canceling sortable start event', () => {
|
||||
sortable.on('sortable:start', (sortableEvent) => {
|
||||
sortableEvent.cancel();
|
||||
});
|
||||
@ -107,20 +95,17 @@ describe('Sortable', () => {
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
expect(sortable.isDragging())
|
||||
.toBe(false);
|
||||
expect(sortable.isDragging()).toBe(false);
|
||||
|
||||
releaseMouse(sortable.source);
|
||||
});
|
||||
|
||||
test('sorts two first elements', () => {
|
||||
it('sorts two first elements', () => {
|
||||
draggableElements = sandbox.querySelectorAll('li');
|
||||
|
||||
expect(draggableElements[0])
|
||||
.toBe(firstItem);
|
||||
expect(draggableElements[0]).toBe(firstItem);
|
||||
|
||||
expect(draggableElements[1])
|
||||
.toBe(secondItem);
|
||||
expect(draggableElements[1]).toBe(secondItem);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
@ -129,171 +114,105 @@ describe('Sortable', () => {
|
||||
|
||||
draggableElements = sandbox.querySelectorAll('li');
|
||||
|
||||
expect(draggableElements[0])
|
||||
.toBe(secondItem);
|
||||
expect(draggableElements[0]).toBe(secondItem);
|
||||
|
||||
expect(draggableElements[1])
|
||||
.toBe(firstItem);
|
||||
expect(draggableElements[1]).toBe(firstItem);
|
||||
});
|
||||
|
||||
test('sorts elements as you drag within a single container', () => {
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(containers[0]);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
it('sorts elements as you drag within a single container', () => {
|
||||
draggableElements = sortable.getDraggableElementsForContainer(containers[0]);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
secondItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
moveMouse(thirdItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
moveMouse(forthItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
]);
|
||||
|
||||
releaseMouse(sortable.source);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
firstItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem, firstItem]);
|
||||
});
|
||||
|
||||
test('sorts elements as you drag between multiple containers', () => {
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
it('sorts elements as you drag between multiple containers', () => {
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
moveMouse(fifthItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
|
||||
moveMouse(eighthItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
// original firstItem
|
||||
sortable.source,
|
||||
]);
|
||||
|
||||
releaseMouse(sortable.source);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
firstItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem, firstItem]);
|
||||
});
|
||||
|
||||
test('prevents sorting when sortable:sort event gets canceled', () => {
|
||||
it('prevents sorting when sortable:sort event gets canceled', () => {
|
||||
sortable.on('sortable:sort', (sortableEvent) => {
|
||||
sortableEvent.cancel();
|
||||
});
|
||||
@ -302,102 +221,70 @@ describe('Sortable', () => {
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
sortable.source,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([sortable.source, secondItem, thirdItem, forthItem]);
|
||||
|
||||
releaseMouse(sortable.source);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
});
|
||||
|
||||
test('sorts elements into empty container', () => {
|
||||
[fifthItem, sixthItem, seventhItem, eighthItem].forEach(
|
||||
(item) => {
|
||||
clickMouse(item);
|
||||
waitForDragDelay();
|
||||
moveMouse(firstItem);
|
||||
releaseMouse(sortable.source);
|
||||
},
|
||||
);
|
||||
it('sorts elements into empty container', () => {
|
||||
[fifthItem, sixthItem, seventhItem, eighthItem].forEach((item) => {
|
||||
clickMouse(item);
|
||||
waitForDragDelay();
|
||||
moveMouse(firstItem);
|
||||
releaseMouse(sortable.source);
|
||||
});
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([]);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
moveMouse(secondContainer);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
sortable.source,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([sortable.source]);
|
||||
|
||||
releaseMouse(sortable.source);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
draggableElements =
|
||||
sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
]);
|
||||
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([firstItem]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,11 +1,5 @@
|
||||
import Draggable from '../Draggable';
|
||||
|
||||
import {
|
||||
SwappableStartEvent,
|
||||
SwappableSwapEvent,
|
||||
SwappableSwappedEvent,
|
||||
SwappableStopEvent,
|
||||
} from './SwappableEvent';
|
||||
import {SwappableStartEvent, SwappableSwapEvent, SwappableSwappedEvent, SwappableStopEvent} from './SwappableEvent';
|
||||
|
||||
const onDragStart = Symbol('onDragStart');
|
||||
const onDragOver = Symbol('onDragOver');
|
||||
@ -39,7 +33,6 @@ const defaultAnnouncements = {
|
||||
* @extends Draggable
|
||||
*/
|
||||
export default class Swappable extends Draggable {
|
||||
|
||||
/**
|
||||
* Swappable constructor.
|
||||
* @constructs Swappable
|
||||
@ -66,8 +59,7 @@ export default class Swappable extends Draggable {
|
||||
this[onDragOver] = this[onDragOver].bind(this);
|
||||
this[onDragStop] = this[onDragStop].bind(this);
|
||||
|
||||
this
|
||||
.on('drag:start', this[onDragStart])
|
||||
this.on('drag:start', this[onDragStart])
|
||||
.on('drag:over', this[onDragOver])
|
||||
.on('drag:stop', this[onDragStop]);
|
||||
}
|
||||
@ -78,8 +70,7 @@ export default class Swappable extends Draggable {
|
||||
destroy() {
|
||||
super.destroy();
|
||||
|
||||
this
|
||||
.off('drag:start', this._onDragStart)
|
||||
this.off('drag:start', this._onDragStart)
|
||||
.off('drag:over', this._onDragOver)
|
||||
.off('drag:stop', this._onDragStop);
|
||||
}
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
createSandbox,
|
||||
clickMouse,
|
||||
moveMouse,
|
||||
releaseMouse,
|
||||
waitForDragDelay,
|
||||
DRAG_DELAY,
|
||||
} from 'helper';
|
||||
|
||||
import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
|
||||
import Swappable from '..';
|
||||
|
||||
const sampleMarkup = `
|
||||
@ -69,7 +61,7 @@ describe('Swappable', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('triggers events', () => {
|
||||
it('triggers events', () => {
|
||||
const swappableStart = jest.fn();
|
||||
const swappableSwap = jest.fn();
|
||||
const swappableSwapped = jest.fn();
|
||||
@ -85,20 +77,16 @@ describe('Swappable', () => {
|
||||
moveMouse(secondItem);
|
||||
releaseMouse(swappable.source);
|
||||
|
||||
expect(swappableStart)
|
||||
.toHaveBeenCalled();
|
||||
expect(swappableStart).toHaveBeenCalled();
|
||||
|
||||
expect(swappableSwap)
|
||||
.toHaveBeenCalled();
|
||||
expect(swappableSwap).toHaveBeenCalled();
|
||||
|
||||
expect(swappableSwapped)
|
||||
.toHaveBeenCalled();
|
||||
expect(swappableSwapped).toHaveBeenCalled();
|
||||
|
||||
expect(swappableStop)
|
||||
.toHaveBeenCalled();
|
||||
expect(swappableStop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('prevents drag when canceling sortable start event', () => {
|
||||
it('prevents drag when canceling sortable start event', () => {
|
||||
swappable.on('swappable:start', (swappableEvent) => {
|
||||
swappableEvent.cancel();
|
||||
});
|
||||
@ -107,20 +95,17 @@ describe('Swappable', () => {
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
expect(swappable.isDragging())
|
||||
.toBe(false);
|
||||
expect(swappable.isDragging()).toBe(false);
|
||||
|
||||
releaseMouse(swappable.source);
|
||||
});
|
||||
|
||||
test('swaps two first elements', () => {
|
||||
it('swaps two first elements', () => {
|
||||
draggableElements = sandbox.querySelectorAll('li');
|
||||
|
||||
expect(draggableElements[0])
|
||||
.toBe(firstItem);
|
||||
expect(draggableElements[0]).toBe(firstItem);
|
||||
|
||||
expect(draggableElements[1])
|
||||
.toBe(secondItem);
|
||||
expect(draggableElements[1]).toBe(secondItem);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
@ -129,171 +114,103 @@ describe('Swappable', () => {
|
||||
|
||||
draggableElements = sandbox.querySelectorAll('li');
|
||||
|
||||
expect(draggableElements[0])
|
||||
.toBe(secondItem);
|
||||
expect(draggableElements[0]).toBe(secondItem);
|
||||
|
||||
expect(draggableElements[1])
|
||||
.toBe(firstItem);
|
||||
expect(draggableElements[1]).toBe(firstItem);
|
||||
});
|
||||
|
||||
test('swaps elements as you drag within a single container', () => {
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(containers[0]);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
it('swaps elements as you drag within a single container', () => {
|
||||
draggableElements = swappable.getDraggableElementsForContainer(containers[0]);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
secondItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
secondItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
moveMouse(thirdItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
thirdItem,
|
||||
secondItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
thirdItem,
|
||||
secondItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
forthItem,
|
||||
]);
|
||||
|
||||
moveMouse(forthItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
forthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
forthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
]);
|
||||
|
||||
releaseMouse(swappable.source);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
forthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
firstItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([forthItem, secondItem, thirdItem, firstItem]);
|
||||
});
|
||||
|
||||
test('sorts elements as you drag between multiple containers', () => {
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
it('sorts elements as you drag between multiple containers', () => {
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
|
||||
|
||||
clickMouse(firstItem);
|
||||
waitForDragDelay();
|
||||
moveMouse(fifthItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([fifthItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
eighthItem,
|
||||
]);
|
||||
|
||||
moveMouse(eighthItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
// original firstItem
|
||||
swappable.source,
|
||||
]);
|
||||
|
||||
releaseMouse(swappable.source);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
eighthItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
fifthItem,
|
||||
sixthItem,
|
||||
seventhItem,
|
||||
firstItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
|
||||
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, firstItem]);
|
||||
});
|
||||
|
||||
test('prevents sorting when sortable:sort event gets canceled', () => {
|
||||
it('prevents sorting when sortable:sort event gets canceled', () => {
|
||||
swappable.on('swappable:swap', (swappableEvent) => {
|
||||
swappableEvent.cancel();
|
||||
});
|
||||
@ -302,26 +219,12 @@ describe('Swappable', () => {
|
||||
waitForDragDelay();
|
||||
moveMouse(secondItem);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
swappable.source,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([swappable.source, secondItem, thirdItem, forthItem]);
|
||||
|
||||
releaseMouse(swappable.source);
|
||||
|
||||
draggableElements =
|
||||
swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements)
|
||||
.toHaveOrder([
|
||||
firstItem,
|
||||
secondItem,
|
||||
thirdItem,
|
||||
forthItem,
|
||||
]);
|
||||
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
|
||||
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
|
||||
});
|
||||
});
|
||||
|
||||
26
src/index.js
26
src/index.js
@ -4,25 +4,9 @@ import AbstractPlugin from 'shared/AbstractPlugin';
|
||||
import * as Sensors from './Draggable/Sensors';
|
||||
import * as Plugins from './Plugins';
|
||||
|
||||
export {
|
||||
default as Draggable,
|
||||
} from './Draggable';
|
||||
export {default as Draggable} from './Draggable';
|
||||
export {default as Droppable} from './Droppable';
|
||||
export {default as Swappable} from './Swappable';
|
||||
export {default as Sortable} from './Sortable';
|
||||
|
||||
export {
|
||||
default as Droppable,
|
||||
} from './Droppable';
|
||||
|
||||
export {
|
||||
default as Swappable,
|
||||
} from './Swappable';
|
||||
|
||||
export {
|
||||
default as Sortable,
|
||||
} from './Sortable';
|
||||
|
||||
export {
|
||||
AbstractEvent as BaseEvent,
|
||||
AbstractPlugin as BasePlugin,
|
||||
Sensors,
|
||||
Plugins,
|
||||
};
|
||||
export {AbstractEvent as BaseEvent, AbstractPlugin as BasePlugin, Sensors, Plugins};
|
||||
|
||||
@ -9,25 +9,9 @@ import AbstractPlugin from 'shared/AbstractPlugin';
|
||||
import * as Sensors from './Draggable/Sensors';
|
||||
import * as Plugins from './Plugins';
|
||||
|
||||
export {
|
||||
default as Draggable,
|
||||
} from './Draggable';
|
||||
export {default as Draggable} from './Draggable';
|
||||
export {default as Droppable} from './Droppable';
|
||||
export {default as Swappable} from './Swappable';
|
||||
export {default as Sortable} from './Sortable';
|
||||
|
||||
export {
|
||||
default as Droppable,
|
||||
} from './Droppable';
|
||||
|
||||
export {
|
||||
default as Swappable,
|
||||
} from './Swappable';
|
||||
|
||||
export {
|
||||
default as Sortable,
|
||||
} from './Sortable';
|
||||
|
||||
export {
|
||||
AbstractEvent as BaseEvent,
|
||||
AbstractPlugin as BasePlugin,
|
||||
Sensors,
|
||||
Plugins,
|
||||
};
|
||||
export {AbstractEvent as BaseEvent, AbstractPlugin as BasePlugin, Sensors, Plugins};
|
||||
|
||||
@ -9,7 +9,6 @@ const canceled = Symbol('canceled');
|
||||
* @module AbstractEvent
|
||||
*/
|
||||
export default class AbstractEvent {
|
||||
|
||||
/**
|
||||
* Event type
|
||||
* @static
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
import AbstractEvent from '../AbstractEvent';
|
||||
|
||||
describe('AbstractEvent', () => {
|
||||
test('should be of type AbstractEvent', () => {
|
||||
it('should be of type AbstractEvent', () => {
|
||||
const event = new AbstractEvent();
|
||||
|
||||
expect(event).toBeInstanceOf(AbstractEvent);
|
||||
});
|
||||
|
||||
test('should initialize with correct type', () => {
|
||||
it('should initialize with correct type', () => {
|
||||
const event = new AbstractEvent();
|
||||
|
||||
expect(event.type).toBe('event');
|
||||
});
|
||||
|
||||
test('should initialize in uncancelable state', () => {
|
||||
it('should initialize in uncancelable state', () => {
|
||||
const event = new AbstractEvent();
|
||||
|
||||
expect(event.cancelable).toBe(false);
|
||||
});
|
||||
|
||||
test('should initialize in uncancelled state', () => {
|
||||
it('should initialize in uncancelled state', () => {
|
||||
const event = new AbstractEvent();
|
||||
|
||||
expect(event.canceled()).toBe(false);
|
||||
});
|
||||
|
||||
test('should initialize with data', () => {
|
||||
it('should initialize with data', () => {
|
||||
const event = new AbstractEvent({
|
||||
foo: 'bar',
|
||||
});
|
||||
@ -35,7 +35,7 @@ describe('AbstractEvent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('should cancel event', () => {
|
||||
it('should cancel event', () => {
|
||||
const event = new AbstractEvent();
|
||||
|
||||
expect(event.canceled()).toBe(false);
|
||||
|
||||
@ -5,14 +5,12 @@
|
||||
* @module AbstractPlugin
|
||||
*/
|
||||
export default class AbstractPlugin {
|
||||
|
||||
/**
|
||||
* AbstractPlugin constructor.
|
||||
* @constructs AbstractPlugin
|
||||
* @param {Draggable} draggable - Draggable instance
|
||||
*/
|
||||
constructor(draggable) {
|
||||
|
||||
/**
|
||||
* Draggable instance
|
||||
* @property draggable
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
const matchFunction = Element.prototype.matches ||
|
||||
Element.prototype.webkitMatchesSelector ||
|
||||
Element.prototype.mozMatchesSelector ||
|
||||
Element.prototype.msMatchesSelector;
|
||||
const matchFunction =
|
||||
Element.prototype.matches ||
|
||||
Element.prototype.webkitMatchesSelector ||
|
||||
Element.prototype.mozMatchesSelector ||
|
||||
Element.prototype.msMatchesSelector;
|
||||
|
||||
/**
|
||||
* Get the closest parent element of a given element that matches the given
|
||||
@ -47,9 +48,11 @@ export default function closest(element, value) {
|
||||
|
||||
do {
|
||||
current = current.correspondingUseElement || current.correspondingElement || current;
|
||||
|
||||
if (conditionFn(current)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current = current.parentNode;
|
||||
} while (current && current !== document.body && current !== document);
|
||||
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
import {
|
||||
createSandbox,
|
||||
} from 'helper';
|
||||
|
||||
import {createSandbox} from 'helper';
|
||||
import closest from '../closest';
|
||||
|
||||
const sampleMarkup = `
|
||||
@ -25,52 +22,43 @@ describe('utils', () => {
|
||||
sandbox.parentNode.removeChild(sandbox);
|
||||
});
|
||||
|
||||
test('should return null when no element specified', () => {
|
||||
expect(closest()).toBe(null);
|
||||
it('should return null when no element specified', () => {
|
||||
expect(closest()).toBeNull();
|
||||
});
|
||||
|
||||
test('should return null when string selector does not match', () => {
|
||||
it('should return null when string selector does not match', () => {
|
||||
const element = sandbox.querySelector('.leaf');
|
||||
|
||||
expect(closest(element, 'will-not-match')).toBe(null);
|
||||
expect(closest(element, 'will-not-match')).toBeNull();
|
||||
});
|
||||
|
||||
test('should return null when function selector does not match', () => {
|
||||
it('should return null when function selector does not match', () => {
|
||||
const element = sandbox.querySelector('.leaf');
|
||||
function selector() { return false; }
|
||||
function selector() {
|
||||
return false;
|
||||
}
|
||||
|
||||
expect(closest(element, selector)).toBe(null);
|
||||
expect(closest(element, selector)).toBeNull();
|
||||
});
|
||||
|
||||
test('should return null when selector targets child element', () => {
|
||||
it('should return null when selector targets child element', () => {
|
||||
const element = sandbox.querySelector('.twig');
|
||||
|
||||
expect(closest(element, '.leaf')).toBe(null);
|
||||
expect(closest(element, '.leaf')).toBeNull();
|
||||
});
|
||||
|
||||
test('should match element via callback', () => {
|
||||
it('should match element via callback', () => {
|
||||
const element = sandbox.querySelector('.leaf');
|
||||
|
||||
function callback(currentElement) {
|
||||
return currentElement
|
||||
.classList
|
||||
.contains('leaf');
|
||||
return currentElement.classList.contains('leaf');
|
||||
}
|
||||
|
||||
expect(closest(element, callback)).toBe(element);
|
||||
});
|
||||
|
||||
[
|
||||
'.twig',
|
||||
'ul',
|
||||
'.branch',
|
||||
'section',
|
||||
'.tree',
|
||||
'div',
|
||||
'body',
|
||||
'document',
|
||||
].forEach((expectedMatchingSelector) => {
|
||||
test(`should return matched element when selector targets parent element matching selector ${expectedMatchingSelector}`, () => {
|
||||
['.twig', 'ul', '.branch', 'section', '.tree', 'div', 'body', 'document'].forEach((expectedMatchingSelector) => {
|
||||
it(`should return matched element when selector targets parent element matching selector ${expectedMatchingSelector}`, () => {
|
||||
const element = sandbox.querySelector('.leaf');
|
||||
const expected = sandbox.querySelector(expectedMatchingSelector);
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import closest from './closest';
|
||||
|
||||
export {
|
||||
closest,
|
||||
};
|
||||
export {closest};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user