setup prettier and fix all files

This commit is contained in:
beefchimi 2018-03-19 21:28:19 -04:00
parent 9ceef05571
commit 34d1bc3cbf
44 changed files with 659 additions and 1153 deletions

View File

@ -1,6 +1,8 @@
module.exports = { module.exports = {
extends: [ extends: [
'plugin:shopify/esnext', 'plugin:shopify/esnext',
'plugin:shopify/jest',
'plugin:shopify/prettier',
], ],
env: { env: {
browser: true, browser: true,
@ -9,16 +11,7 @@ module.exports = {
'import/no-unresolved': 'off', 'import/no-unresolved': 'off',
'import/no-extraneous-dependencies': 'off', 'import/no-extraneous-dependencies': 'off',
'class-methods-use-this': 'off', 'class-methods-use-this': 'off',
}, 'line-comment-position': 0,
globals: { 'lines-around-comment': 'off',
jest: false,
afterAll: false,
afterEach: false,
beforeAll: false,
beforeEach: false,
describe: false,
test: false,
xtest: false,
expect: false,
}, },
}; };

4
.prettierrc Normal file
View File

@ -0,0 +1,4 @@
{
"printWidth": 120,
"singleQuote": true
}

View File

@ -1,8 +1,10 @@
export const defaultTouchEventOptions = { export const defaultTouchEventOptions = {
touches: [{ touches: [
{
pageX: 0, pageX: 0,
pageY: 0, pageY: 0,
}], },
],
}; };
export const DRAG_DELAY = 0; export const DRAG_DELAY = 0;

View File

@ -2,6 +2,7 @@ export function createSandbox(content) {
const sandbox = document.createElement('div'); const sandbox = document.createElement('div');
sandbox.innerHTML = content; sandbox.innerHTML = content;
document.body.appendChild(sandbox); document.body.appendChild(sandbox);
return sandbox; return sandbox;
} }

View File

@ -3,6 +3,7 @@ import {withElementFromPoint} from './environment';
export function triggerEvent(element, type, data = {}) { export function triggerEvent(element, type, data = {}) {
const event = document.createEvent('Event'); const event = document.createEvent('Event');
event.initEvent(type, true, true); event.initEvent(type, true, true);
for (const key in data) { for (const key in data) {
if (data.hasOwnProperty(key)) { if (data.hasOwnProperty(key)) {
event[key] = data[key]; event[key] = data[key];

View File

@ -11,15 +11,19 @@ function toHaveOrder(actualOrder, expectedOrder) {
const expectation = pass ? 'not to be' : 'to be'; const expectation = pass ? 'not to be' : 'to be';
let message = `Expected order ${expectation}:\n`; let message = `Expected order ${expectation}:\n`;
message += expectedOrder.map((element) => { message += expectedOrder
.map((element) => {
return `${element.textContent.trim()}`; return `${element.textContent.trim()}`;
}).join('\n'); })
.join('\n');
message += '\n \nInstead received:\n'; message += '\n \nInstead received:\n';
message += actualOrder.map((element) => { message += actualOrder
.map((element) => {
return `${element.textContent.trim()}`; return `${element.textContent.trim()}`;
}).join('\n'); })
.join('\n');
return message; return message;
}, },

View File

@ -12,19 +12,19 @@ import {
describe('DragEvent', () => { describe('DragEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragEvent', () => { it('should be instance of DragEvent', () => {
const event = new DragEvent(); const event = new DragEvent();
expect(event).toBeInstanceOf(DragEvent); expect(event).toBeInstanceOf(DragEvent);
}); });
test('should initialize with `type` of `event`', () => { it('should initialize with `type` of `event`', () => {
const event = new DragEvent(); const event = new DragEvent();
expect(event.type).toBe('drag'); expect(event.type).toBe('drag');
}); });
test('should initialize with source', () => { it('should initialize with source', () => {
const event = new DragEvent({ const event = new DragEvent({
source: 'expected source', source: 'expected source',
}); });
@ -32,7 +32,7 @@ describe('DragEvent', () => {
expect(event.source).toBe('expected source'); expect(event.source).toBe('expected source');
}); });
test('should initialize with mirror', () => { it('should initialize with mirror', () => {
const event = new DragEvent({ const event = new DragEvent({
mirror: 'expected mirror', mirror: 'expected mirror',
}); });
@ -40,7 +40,7 @@ describe('DragEvent', () => {
expect(event.mirror).toBe('expected mirror'); expect(event.mirror).toBe('expected mirror');
}); });
test('should initialize with sourceContainer', () => { it('should initialize with sourceContainer', () => {
const event = new DragEvent({ const event = new DragEvent({
sourceContainer: 'expected sourceContainer', sourceContainer: 'expected sourceContainer',
}); });
@ -48,7 +48,7 @@ describe('DragEvent', () => {
expect(event.sourceContainer).toBe('expected sourceContainer'); expect(event.sourceContainer).toBe('expected sourceContainer');
}); });
test('should initialize with sensorEvent', () => { it('should initialize with sensorEvent', () => {
const event = new DragEvent({ const event = new DragEvent({
sensorEvent: 'expected sensorEvent', sensorEvent: 'expected sensorEvent',
}); });
@ -56,7 +56,7 @@ describe('DragEvent', () => {
expect(event.sensorEvent).toBe('expected sensorEvent'); expect(event.sensorEvent).toBe('expected sensorEvent');
}); });
test('should initialize with originalEvent', () => { it('should initialize with originalEvent', () => {
const event = new DragEvent({ const event = new DragEvent({
sensorEvent: { sensorEvent: {
originalEvent: 'expected originalEvent', originalEvent: 'expected originalEvent',
@ -68,15 +68,15 @@ describe('DragEvent', () => {
}); });
describe('#originalEvent', () => { describe('#originalEvent', () => {
test('should return null when initialized without sensorEvent', () => { it('should return null when initialized without sensorEvent', () => {
const event = new DragEvent({}); const event = new DragEvent({});
expect(event.originalEvent).toBe(null); expect(event.originalEvent).toBeNull();
}); });
}); });
describe('#hasMirror', () => { describe('#hasMirror', () => {
test('should return true when event has mirror', () => { it('should return true when event has mirror', () => {
const event = new DragEvent({ const event = new DragEvent({
mirror: true, mirror: true,
}); });
@ -84,7 +84,7 @@ describe('DragEvent', () => {
expect(event.hasMirror()).toBe(true); 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({}); const event = new DragEvent({});
expect(event.hasMirror()).toBe(false); expect(event.hasMirror()).toBe(false);
@ -94,13 +94,13 @@ describe('DragEvent', () => {
describe('DragStartEvent', () => { describe('DragStartEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragStartEvent', () => { it('should be instance of DragStartEvent', () => {
const event = new DragStartEvent(); const event = new DragStartEvent();
expect(event).toBeInstanceOf(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(); const event = new DragStartEvent();
expect(event.type).toBe('drag:start'); expect(event.type).toBe('drag:start');
@ -110,13 +110,13 @@ describe('DragStartEvent', () => {
describe('DragMoveEvent', () => { describe('DragMoveEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragMoveEvent', () => { it('should be instance of DragMoveEvent', () => {
const event = new DragMoveEvent(); const event = new DragMoveEvent();
expect(event).toBeInstanceOf(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(); const event = new DragMoveEvent();
expect(event.type).toBe('drag:move'); expect(event.type).toBe('drag:move');
@ -126,19 +126,19 @@ describe('DragMoveEvent', () => {
describe('DragOutContainerEvent', () => { describe('DragOutContainerEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragOutContainerEvent', () => { it('should be instance of DragOutContainerEvent', () => {
const event = new DragOutContainerEvent(); const event = new DragOutContainerEvent();
expect(event).toBeInstanceOf(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(); const event = new DragOutContainerEvent();
expect(event.type).toBe('drag:out:container'); expect(event.type).toBe('drag:out:container');
}); });
test('should initialize with overContainer', () => { it('should initialize with overContainer', () => {
const event = new DragOutContainerEvent({ const event = new DragOutContainerEvent({
overContainer: 'expected overContainer', overContainer: 'expected overContainer',
}); });
@ -150,19 +150,19 @@ describe('DragOutContainerEvent', () => {
describe('DragOutEvent', () => { describe('DragOutEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragOutEvent', () => { it('should be instance of DragOutEvent', () => {
const event = new DragOutEvent(); const event = new DragOutEvent();
expect(event).toBeInstanceOf(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(); const event = new DragOutEvent();
expect(event.type).toBe('drag:out'); expect(event.type).toBe('drag:out');
}); });
test('should initialize with overContainer', () => { it('should initialize with overContainer', () => {
const event = new DragOutEvent({ const event = new DragOutEvent({
overContainer: 'expected overContainer', overContainer: 'expected overContainer',
}); });
@ -170,7 +170,7 @@ describe('DragOutEvent', () => {
expect(event.overContainer).toBe('expected overContainer'); expect(event.overContainer).toBe('expected overContainer');
}); });
test('should initialize with over', () => { it('should initialize with over', () => {
const event = new DragOutEvent({ const event = new DragOutEvent({
over: 'expected over', over: 'expected over',
}); });
@ -182,19 +182,19 @@ describe('DragOutEvent', () => {
describe('DragOverContainerEvent', () => { describe('DragOverContainerEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragOverContainerEvent', () => { it('should be instance of DragOverContainerEvent', () => {
const event = new DragOverContainerEvent(); const event = new DragOverContainerEvent();
expect(event).toBeInstanceOf(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(); const event = new DragOverContainerEvent();
expect(event.type).toBe('drag:over:container'); expect(event.type).toBe('drag:over:container');
}); });
test('should initialize with overContainer', () => { it('should initialize with overContainer', () => {
const event = new DragOverContainerEvent({ const event = new DragOverContainerEvent({
overContainer: 'expected overContainer', overContainer: 'expected overContainer',
}); });
@ -206,19 +206,19 @@ describe('DragOverContainerEvent', () => {
describe('DragOverEvent', () => { describe('DragOverEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragOverEvent', () => { it('should be instance of DragOverEvent', () => {
const event = new DragOverEvent(); const event = new DragOverEvent();
expect(event).toBeInstanceOf(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(); const event = new DragOverEvent();
expect(event.type).toBe('drag:over'); expect(event.type).toBe('drag:over');
}); });
test('should initialize with overContainer', () => { it('should initialize with overContainer', () => {
const event = new DragOverEvent({ const event = new DragOverEvent({
overContainer: 'expected overContainer', overContainer: 'expected overContainer',
}); });
@ -226,7 +226,7 @@ describe('DragOverEvent', () => {
expect(event.overContainer).toBe('expected overContainer'); expect(event.overContainer).toBe('expected overContainer');
}); });
test('should initialize with over', () => { it('should initialize with over', () => {
const event = new DragOverEvent({ const event = new DragOverEvent({
over: 'expected over', over: 'expected over',
}); });
@ -238,19 +238,19 @@ describe('DragOverEvent', () => {
describe('DragPressureEvent', () => { describe('DragPressureEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragPressureEvent', () => { it('should be instance of DragPressureEvent', () => {
const event = new DragPressureEvent(); const event = new DragPressureEvent();
expect(event).toBeInstanceOf(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(); const event = new DragPressureEvent();
expect(event.type).toBe('drag:pressure'); expect(event.type).toBe('drag:pressure');
}); });
test('should initialize with pressure', () => { it('should initialize with pressure', () => {
const event = new DragPressureEvent({ const event = new DragPressureEvent({
pressure: 'expected pressure', pressure: 'expected pressure',
}); });
@ -262,13 +262,13 @@ describe('DragPressureEvent', () => {
describe('DragStopEvent', () => { describe('DragStopEvent', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should be instance of DragStopEvent', () => { it('should be instance of DragStopEvent', () => {
const event = new DragStopEvent(); const event = new DragStopEvent();
expect(event).toBeInstanceOf(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(); const event = new DragStopEvent();
expect(event.type).toBe('drag:stop'); expect(event.type).toBe('drag:stop');

View File

@ -1,18 +1,8 @@
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import {Accessibility, Mirror, Scrollable, Announcement} from './Plugins'; import {Accessibility, Mirror, Scrollable, Announcement} from './Plugins';
import Emitter from './Emitter'; import Emitter from './Emitter';
import {MouseSensor, TouchSensor} from './Sensors';
import { import {DraggableInitializedEvent, DraggableDestroyEvent} from './DraggableEvent';
MouseSensor,
TouchSensor,
} from './Sensors';
import {
DraggableInitializedEvent,
DraggableDestroyEvent,
} from './DraggableEvent';
import { import {
DragStartEvent, DragStartEvent,
@ -76,7 +66,6 @@ export const defaultOptions = {
* @module Draggable * @module Draggable
*/ */
export default class Draggable { export default class Draggable {
/** /**
* Default plugins draggable uses * Default plugins draggable uses
* @static * @static
@ -96,7 +85,6 @@ export default class Draggable {
* @param {Object} options - Options for draggable * @param {Object} options - Options for draggable
*/ */
constructor(containers = [document.body], options = {}) { constructor(containers = [document.body], options = {}) {
/** /**
* Draggable containers * Draggable containers
* @property containers * @property containers
@ -199,8 +187,10 @@ export default class Draggable {
*/ */
addPlugin(...plugins) { addPlugin(...plugins) {
const activePlugins = plugins.map((Plugin) => new Plugin(this)); const activePlugins = plugins.map((Plugin) => new Plugin(this));
activePlugins.forEach((plugin) => plugin.attach()); activePlugins.forEach((plugin) => plugin.attach());
this.plugins = [...this.plugins, ...activePlugins]; this.plugins = [...this.plugins, ...activePlugins];
return this; return this;
} }
@ -213,8 +203,10 @@ export default class Draggable {
*/ */
removePlugin(...plugins) { removePlugin(...plugins) {
const removedPlugins = this.plugins.filter((plugin) => plugins.includes(plugin.constructor)); const removedPlugins = this.plugins.filter((plugin) => plugins.includes(plugin.constructor));
removedPlugins.forEach((plugin) => plugin.detach()); removedPlugins.forEach((plugin) => plugin.detach());
this.plugins = this.plugins.filter((plugin) => !plugins.includes(plugin.constructor)); this.plugins = this.plugins.filter((plugin) => !plugins.includes(plugin.constructor));
return this; return this;
} }
@ -226,8 +218,10 @@ export default class Draggable {
*/ */
addSensor(...sensors) { addSensor(...sensors) {
const activeSensors = sensors.map((Sensor) => new Sensor(this.containers, this.options)); const activeSensors = sensors.map((Sensor) => new Sensor(this.containers, this.options));
activeSensors.forEach((sensor) => sensor.attach()); activeSensors.forEach((sensor) => sensor.attach());
this.sensors = [...this.sensors, ...activeSensors]; this.sensors = [...this.sensors, ...activeSensors];
return this; return this;
} }
@ -240,8 +234,10 @@ export default class Draggable {
*/ */
removeSensor(...sensors) { removeSensor(...sensors) {
const removedSensors = this.sensors.filter((sensor) => sensors.includes(sensor.constructor)); const removedSensors = this.sensors.filter((sensor) => sensors.includes(sensor.constructor));
removedSensors.forEach((sensor) => sensor.detach()); removedSensors.forEach((sensor) => sensor.detach());
this.sensors = this.sensors.filter((sensor) => !sensors.includes(sensor.constructor)); this.sensors = this.sensors.filter((sensor) => !sensors.includes(sensor.constructor));
return this; return this;
} }
@ -484,10 +480,10 @@ export default class Draggable {
target = closest(target, this.options.draggable); target = closest(target, this.options.draggable);
const withinCorrectContainer = closest(sensorEvent.target, this.containers); const withinCorrectContainer = closest(sensorEvent.target, this.containers);
const overContainer = sensorEvent.overContainer || withinCorrectContainer; const overContainer = sensorEvent.overContainer || withinCorrectContainer;
const isLeavingContainer = this.currentOverContainer && (overContainer !== this.currentOverContainer); const isLeavingContainer = this.currentOverContainer && overContainer !== this.currentOverContainer;
const isLeavingDraggable = this.currentOver && (target !== this.currentOver); const isLeavingDraggable = this.currentOver && target !== this.currentOver;
const isOverContainer = overContainer && (this.currentOverContainer !== overContainer); const isOverContainer = overContainer && this.currentOverContainer !== overContainer;
const isOverDraggable = withinCorrectContainer && target && (this.currentOver !== target); const isOverDraggable = withinCorrectContainer && target && this.currentOver !== target;
if (isLeavingDraggable) { if (isLeavingDraggable) {
const dragOutEvent = new DragOutEvent({ const dragOutEvent = new DragOutEvent({

View File

@ -58,6 +58,7 @@ export default class Emitter {
for (let i = callbacks.length - 1; i >= 0; i--) { for (let i = callbacks.length - 1; i >= 0; i--) {
const callback = callbacks[i]; const callback = callbacks[i];
try { try {
callback(event); callback(event);
} catch (error) { } catch (error) {

View File

@ -11,7 +11,7 @@ describe('Emitter', () => {
}); });
describe('#on', () => { describe('#on', () => {
test('registers a callback by event type', () => { it('registers a callback by event type', () => {
const callback = jest.fn(); const callback = jest.fn();
emitter.on('event', callback); emitter.on('event', callback);
@ -19,7 +19,7 @@ describe('Emitter', () => {
expect(emitter.callbacks.event).toContain(callback); 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()]; const callbacks = [jest.fn(), jest.fn()];
emitter.on('event', ...callbacks); emitter.on('event', ...callbacks);
@ -30,7 +30,7 @@ describe('Emitter', () => {
}); });
describe('#off', () => { describe('#off', () => {
test('removes a callback by event type', () => { it('removes a callback by event type', () => {
const callback = jest.fn(); const callback = jest.fn();
emitter.on('event', callback); emitter.on('event', callback);
@ -44,7 +44,7 @@ describe('Emitter', () => {
}); });
describe('#trigger', () => { describe('#trigger', () => {
test('triggers callbacks on event with test event', () => { it('triggers callbacks on event with test event', () => {
const testEvent = new TestEvent({}); const testEvent = new TestEvent({});
const callback = jest.fn(); const callback = jest.fn();
@ -55,11 +55,13 @@ describe('Emitter', () => {
expect(callback).toHaveBeenCalledWith(testEvent); 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 testEvent = new TestEvent({});
const callbacks = [ const callbacks = [
jest.fn(), jest.fn(),
() => { throw new Error('Error'); }, () => {
throw new Error('Error');
},
jest.fn(), jest.fn(),
]; ];

View File

@ -7,7 +7,6 @@ import AbstractEvent from 'shared/AbstractEvent';
* @extends AbstractEvent * @extends AbstractEvent
*/ */
export class MirrorEvent extends AbstractEvent { export class MirrorEvent extends AbstractEvent {
/** /**
* Draggables source element * Draggables source element
* @property source * @property source

View File

@ -11,7 +11,6 @@ const TABINDEX = 'tabindex';
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Accessibility extends AbstractPlugin { export default class Accessibility extends AbstractPlugin {
/** /**
* Accessibility constructor. * Accessibility constructor.
* @constructs Accessibility * @constructs Accessibility

View File

@ -27,7 +27,6 @@ export const defaultOptions = {
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Announcement extends AbstractPlugin { export default class Announcement extends AbstractPlugin {
/** /**
* Announcement constructor. * Announcement constructor.
* @constructs Announcement * @constructs Announcement
@ -61,16 +60,14 @@ export default class Announcement extends AbstractPlugin {
* Attaches listeners to draggable * Attaches listeners to draggable
*/ */
attach() { attach() {
this.draggable this.draggable.on('draggable:initialize', this[onInitialize]);
.on('draggable:initialize', this[onInitialize]);
} }
/** /**
* Detaches listeners from draggable * Detaches listeners from draggable
*/ */
detach() { detach() {
this.draggable this.draggable.off('draggable:destroy', this[onDestroy]);
.off('draggable:destroy', this[onDestroy]);
} }
/** /**
@ -88,11 +85,11 @@ export default class Announcement extends AbstractPlugin {
[announceEvent](event) { [announceEvent](event) {
const message = this.options[event.type]; const message = this.options[event.type];
if (message && (typeof message === 'string')) { if (message && typeof message === 'string') {
this[announceMessage](message); this[announceMessage](message);
} }
if (message && (typeof message === 'function')) { if (message && typeof message === 'function') {
this[announceMessage](message(event)); this[announceMessage](message(event));
} }
} }
@ -144,8 +141,10 @@ const liveRegion = createRegion();
*/ */
function announce(message, {expire}) { function announce(message, {expire}) {
const element = document.createElement('div'); const element = document.createElement('div');
element.innerHTML = message; element.innerHTML = message;
liveRegion.appendChild(element); liveRegion.appendChild(element);
return setTimeout(() => { return setTimeout(() => {
liveRegion.removeChild(element); liveRegion.removeChild(element);
}, expire); }, expire);

View File

@ -31,7 +31,6 @@ export const defaultOptions = {
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Mirror extends AbstractPlugin { export default class Mirror extends AbstractPlugin {
/** /**
* Mirror constructor. * Mirror constructor.
* @constructs Mirror * @constructs Mirror
@ -163,7 +162,8 @@ export default class Mirror extends AbstractPlugin {
options: this.options, options: this.options,
}; };
return Promise.resolve(initialState) return (
Promise.resolve(initialState)
// Fix reflow here // Fix reflow here
.then(computeMirrorDimensions) .then(computeMirrorDimensions)
.then(calculateMirrorOffset) .then(calculateMirrorOffset)
@ -171,7 +171,8 @@ export default class Mirror extends AbstractPlugin {
.then(addMirrorClasses) .then(addMirrorClasses)
.then(positionMirror({initial: true})) .then(positionMirror({initial: true}))
.then(removeMirrorID) .then(removeMirrorID)
.then(setState); .then(setState)
);
} }
/** /**
@ -191,8 +192,7 @@ export default class Mirror extends AbstractPlugin {
scrollOffset: this.scrollOffset, scrollOffset: this.scrollOffset,
}; };
return Promise.resolve(initialState) return Promise.resolve(initialState).then(positionMirror({raf: true}));
.then(positionMirror({raf: true}));
} }
} }
@ -222,8 +222,8 @@ function computeMirrorDimensions({source, ...args}) {
*/ */
function calculateMirrorOffset({sensorEvent, sourceRect, options, ...args}) { function calculateMirrorOffset({sensorEvent, sourceRect, options, ...args}) {
return withPromise((resolve) => { return withPromise((resolve) => {
const top = options.cursorOffsetY === null ? (sensorEvent.clientY - sourceRect.top) : options.cursorOffsetY; const top = options.cursorOffsetY === null ? sensorEvent.clientY - sourceRect.top : options.cursorOffsetY;
const left = options.cursorOffsetX === null ? (sensorEvent.clientX - sourceRect.left) : options.cursorOffsetX; const left = options.cursorOffsetX === null ? sensorEvent.clientX - sourceRect.left : options.cursorOffsetX;
const mirrorOffset = {top, left}; const mirrorOffset = {top, left};
@ -310,7 +310,8 @@ function removeMirrorID({mirror, ...args}) {
*/ */
function positionMirror({withFrame = false, initial = false} = {}) { function positionMirror({withFrame = false, initial = false} = {}) {
return ({mirror, sensorEvent, mirrorOffset, initialY, initialX, scrollOffset, options, ...args}) => { return ({mirror, sensorEvent, mirrorOffset, initialY, initialX, scrollOffset, options, ...args}) => {
return withPromise((resolve) => { return withPromise(
(resolve) => {
const result = { const result = {
mirror, mirror,
sensorEvent, sensorEvent,
@ -338,7 +339,9 @@ function positionMirror({withFrame = false, initial = false} = {}) {
} }
resolve(result); resolve(result);
}, {frame: withFrame}); },
{frame: withFrame},
);
}; };
} }

View File

@ -27,7 +27,6 @@ export const defaultOptions = {
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Scrollable extends AbstractPlugin { export default class Scrollable extends AbstractPlugin {
/** /**
* Scrollable constructor. * Scrollable constructor.
* @constructs Scrollable * @constructs Scrollable
@ -224,12 +223,20 @@ export default class Scrollable extends AbstractPlugin {
bottom = rect.bottom; bottom = rect.bottom;
} }
let offsetY = (Math.abs(bottom - this.currentMousePosition.clientY) <= this.options.sensitivity) - (Math.abs(top - this.currentMousePosition.clientY) <= this.options.sensitivity); let offsetY =
let offsetX = (Math.abs(right - this.currentMousePosition.clientX) <= this.options.sensitivity) - (Math.abs(left - this.currentMousePosition.clientX) <= this.options.sensitivity); (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) { if (!offsetX && !offsetY) {
offsetX = (windowWidth - this.currentMousePosition.clientX <= this.options.sensitivity) - (this.currentMousePosition.clientX <= this.options.sensitivity); offsetX =
offsetY = (windowHeight - this.currentMousePosition.clientY <= this.options.sensitivity) - (this.currentMousePosition.clientY <= this.options.sensitivity); (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; this.scrollableElement.scrollTop += offsetY * this.options.speed;
@ -249,7 +256,8 @@ function hasOverflow(element) {
const overflowRegex = /(auto|scroll)/; const overflowRegex = /(auto|scroll)/;
const computedStyles = getComputedStyle(element, null); const computedStyles = getComputedStyle(element, null);
const overflow = computedStyles.getPropertyValue('overflow') + const overflow =
computedStyles.getPropertyValue('overflow') +
computedStyles.getPropertyValue('overflow-y') + computedStyles.getPropertyValue('overflow-y') +
computedStyles.getPropertyValue('overflow-x'); computedStyles.getPropertyValue('overflow-x');

View File

@ -1,18 +1,4 @@
export { export {default as Mirror, defaultOptions as defaultMirrorOptions} from './Mirror';
default as Mirror, export {default as Announcement, defaultOptions as defaultAnnouncementOptions} from './Announcement';
defaultOptions as defaultMirrorOptions, export {default as Scrollable, defaultOptions as defaultScrollableOptions} from './Scrollable';
} from './Mirror'; export {default as Accessibility} from './Accessibility';
export {
default as Announcement,
defaultOptions as defaultAnnouncementOptions,
} from './Announcement';
export {
default as Scrollable,
defaultOptions as defaultScrollableOptions,
} from './Scrollable';
export {
default as Accessibility,
} from './Accessibility';

View File

@ -1,12 +1,6 @@
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import Sensor from '../Sensor'; import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onMouseDown = Symbol('onMouseDown'); const onMouseDown = Symbol('onMouseDown');
const onMouseUp = Symbol('onMouseUp'); const onMouseUp = Symbol('onMouseUp');
@ -23,7 +17,6 @@ const reset = Symbol('reset');
* @extends Sensor * @extends Sensor
*/ */
export default class DragSensor extends Sensor { export default class DragSensor extends Sensor {
/** /**
* DragSensor constructor. * DragSensor constructor.
* @constructs DragSensor * @constructs DragSensor
@ -177,7 +170,8 @@ export default class DragSensor extends Sensor {
* @private * @private
* @param {Event} event - Drop event * @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(); event.preventDefault();
} }
@ -188,7 +182,7 @@ export default class DragSensor extends Sensor {
*/ */
[onMouseDown](event) { [onMouseDown](event) {
// Firefox bug for inputs within draggables https://bugzilla.mozilla.org/show_bug.cgi?id=739071 // 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; return;
} }

View File

@ -39,23 +39,20 @@ describe('DragSensor', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('mousedown handler adds draggable attribute', () => { it('mousedown handler adds draggable attribute', () => {
expect(draggableElement.draggable) expect(draggableElement.draggable).toBeUndefined();
.toBeUndefined();
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
expect(draggableElement.draggable) expect(draggableElement.draggable).toBe(true);
.toBe(true);
releaseMouse(draggableElement); releaseMouse(draggableElement);
expect(draggableElement.draggable) expect(draggableElement.draggable).toBe(false);
.toBe(false);
}); });
test('triggers `drag:start` sensor event on dragstart', () => { it('triggers `drag:start` sensor event on dragstart', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -65,11 +62,10 @@ describe('DragSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.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) => { sandbox.addEventListener('drag:start', (event) => {
event.detail.cancel(); event.detail.cancel();
}); });
@ -83,11 +79,10 @@ describe('DragSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
.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() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -103,22 +98,16 @@ describe('DragSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
.not
.toHaveTriggeredSensorEvent('drag:stop');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.toHaveTriggeredSensorEvent('drag:start');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.toHaveTriggeredSensorEvent('drag:stop');
}); });
test('triggers `drag:move` event while moving the mouse', () => { it('triggers `drag:move` event while moving the mouse', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -129,11 +118,10 @@ describe('DragSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
.toHaveTriggeredSensorEvent('drag:move');
}); });
test('triggers `drag:stop` event when releasing mouse', () => { it('triggers `drag:stop` event when releasing mouse', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -144,11 +132,10 @@ describe('DragSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.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() { function dragFlow() {
clickMouse(document.body); clickMouse(document.body);
waitForDragDelay(); waitForDragDelay();
@ -156,8 +143,6 @@ describe('DragSensor', () => {
waitForDragDelay(); waitForDragDelay();
} }
expect(dragFlow) expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
}); });
}); });

View File

@ -1,11 +1,5 @@
import Sensor from '../Sensor'; import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent, DragPressureSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
DragPressureSensorEvent,
} from '../SensorEvent';
const onMouseForceWillBegin = Symbol('onMouseForceWillBegin'); const onMouseForceWillBegin = Symbol('onMouseForceWillBegin');
const onMouseForceDown = Symbol('onMouseForceDown'); const onMouseForceDown = Symbol('onMouseForceDown');
@ -22,7 +16,6 @@ const onMouseForceGlobalChange = Symbol('onMouseForceGlobalChange');
* @extends Sensor * @extends Sensor
*/ */
export default class ForceTouchSensor extends Sensor { export default class ForceTouchSensor extends Sensor {
/** /**
* ForceTouchSensor constructor. * ForceTouchSensor constructor.
* @constructs ForceTouchSensor * @constructs ForceTouchSensor

View File

@ -1,11 +1,6 @@
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import Sensor from '../Sensor'; import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onContextMenuWhileDragging = Symbol('onContextMenuWhileDragging'); const onContextMenuWhileDragging = Symbol('onContextMenuWhileDragging');
const onMouseDown = Symbol('onMouseDown'); const onMouseDown = Symbol('onMouseDown');
@ -19,7 +14,6 @@ const onMouseUp = Symbol('onMouseUp');
* @extends Sensor * @extends Sensor
*/ */
export default class MouseSensor extends Sensor { export default class MouseSensor extends Sensor {
/** /**
* MouseSensor constructor. * MouseSensor constructor.
* @constructs MouseSensor * @constructs MouseSensor

View File

@ -1,12 +1,4 @@
import { import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, clickMouse, moveMouse, releaseMouse} from 'helper';
createSandbox,
triggerEvent,
waitForDragDelay,
DRAG_DELAY,
clickMouse,
moveMouse,
releaseMouse,
} from 'helper';
import MouseSensor from '..'; import MouseSensor from '..';
@ -35,18 +27,17 @@ describe('MouseSensor', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('triggers `drag:start` sensor event on mousedown', () => { it('triggers `drag:start` sensor event on mousedown', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.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) => { sandbox.addEventListener('drag:start', (event) => {
event.detail.cancel(); event.detail.cancel();
}); });
@ -57,11 +48,10 @@ describe('MouseSensor', () => {
releaseMouse(draggableElement); releaseMouse(draggableElement);
} }
expect(dragFlow) expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
.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() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -73,22 +63,16 @@ describe('MouseSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
.not
.toHaveTriggeredSensorEvent('drag:stop');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.toHaveTriggeredSensorEvent('drag:start');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.toHaveTriggeredSensorEvent('drag:stop');
}); });
test('triggers `drag:move` event while moving the mouse', () => { it('triggers `drag:move` event while moving the mouse', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -96,11 +80,10 @@ describe('MouseSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
.toHaveTriggeredSensorEvent('drag:move');
}); });
test('triggers `drag:stop` event when releasing mouse', () => { it('triggers `drag:stop` event when releasing mouse', () => {
function dragFlow() { function dragFlow() {
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -108,11 +91,10 @@ describe('MouseSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.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() { function dragFlowWithRightClick() {
clickMouse(draggableElement, {button: 2}); clickMouse(draggableElement, {button: 2});
waitForDragDelay(); waitForDragDelay();
@ -131,61 +113,45 @@ describe('MouseSensor', () => {
releaseMouse(document.body); releaseMouse(document.body);
} }
[ [dragFlowWithRightClick, dragFlowWithCtrlKey, dragFlowWithMetaKey].forEach((dragFlow) => {
dragFlowWithRightClick, expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
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() { function dragFlow() {
clickMouse(document.body); clickMouse(document.body);
waitForDragDelay(); waitForDragDelay();
} }
expect(dragFlow) expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
}); });
test('prevents context menu while dragging', () => { it('prevents context menu while dragging', () => {
let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu'); let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
expect(contextMenuEvent) expect(contextMenuEvent).not.toHaveDefaultPrevented();
.not
.toHaveDefaultPrevented();
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
contextMenuEvent = triggerEvent(draggableElement, 'contextmenu'); contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
expect(contextMenuEvent) expect(contextMenuEvent).toHaveDefaultPrevented();
.toHaveDefaultPrevented();
releaseMouse(draggableElement); releaseMouse(draggableElement);
}); });
test('prevents native drag when initiating drag flow', () => { it('prevents native drag when initiating drag flow', () => {
let dragEvent = triggerEvent(draggableElement, 'dragstart'); let dragEvent = triggerEvent(draggableElement, 'dragstart');
expect(dragEvent) expect(dragEvent).not.toHaveDefaultPrevented();
.not
.toHaveDefaultPrevented();
clickMouse(draggableElement); clickMouse(draggableElement);
waitForDragDelay(); waitForDragDelay();
dragEvent = triggerEvent(draggableElement, 'dragstart'); dragEvent = triggerEvent(draggableElement, 'dragstart');
expect(dragEvent) expect(dragEvent).toHaveDefaultPrevented();
.toHaveDefaultPrevented();
releaseMouse(document.body); releaseMouse(document.body);
}); });
}); });

View File

@ -4,7 +4,6 @@
* @module Sensor * @module Sensor
*/ */
export default class Sensor { export default class Sensor {
/** /**
* Sensor constructor. * Sensor constructor.
* @constructs Sensor * @constructs Sensor
@ -12,7 +11,6 @@ export default class Sensor {
* @param {Object} options - Options * @param {Object} options - Options
*/ */
constructor(containers = [], options = {}) { constructor(containers = [], options = {}) {
/** /**
* Current containers * Current containers
* @property containers * @property containers
@ -69,6 +67,7 @@ export default class Sensor {
event.initEvent(sensorEvent.type, true, true); event.initEvent(sensorEvent.type, true, true);
element.dispatchEvent(event); element.dispatchEvent(event);
this.lastEvent = sensorEvent; this.lastEvent = sensorEvent;
return sensorEvent; return sensorEvent;
} }
} }

View File

@ -2,14 +2,14 @@ import Sensor from '../Sensor';
describe('Sensor', () => { describe('Sensor', () => {
describe('#constructor', () => { describe('#constructor', () => {
test('should initialize with default containers and options', () => { it('should initialize with default containers and options', () => {
const sensor = new Sensor(); const sensor = new Sensor();
expect(sensor.containers).toMatchObject([]); expect(sensor.containers).toMatchObject([]);
expect(sensor.options).toMatchObject({}); expect(sensor.options).toMatchObject({});
}); });
test('should initialize with containers and options', () => { it('should initialize with containers and options', () => {
const expectedContainers = ['expectedContainer']; const expectedContainers = ['expectedContainer'];
const expectedOptions = {expectedOptions: true}; const expectedOptions = {expectedOptions: true};
const sensor = new Sensor(expectedContainers, expectedOptions); const sensor = new Sensor(expectedContainers, expectedOptions);
@ -20,9 +20,8 @@ describe('Sensor', () => {
}); });
describe('#attach', () => { describe('#attach', () => {
test('should return self', () => { it('should return self', () => {
const sensor = new Sensor(); const sensor = new Sensor();
const returnValue = sensor.attach(); const returnValue = sensor.attach();
expect(returnValue).toBe(sensor); expect(returnValue).toBe(sensor);
@ -30,9 +29,8 @@ describe('Sensor', () => {
}); });
describe('#detach', () => { describe('#detach', () => {
test('should return self', () => { it('should return self', () => {
const sensor = new Sensor(); const sensor = new Sensor();
const returnValue = sensor.attach(); const returnValue = sensor.attach();
expect(returnValue).toBe(sensor); expect(returnValue).toBe(sensor);
@ -40,7 +38,7 @@ describe('Sensor', () => {
}); });
describe('#trigger', () => { describe('#trigger', () => {
test('should dispatch event on element', () => { it('should dispatch event on element', () => {
const sensor = new Sensor(); const sensor = new Sensor();
const element = document.createElement('div'); const element = document.createElement('div');
const expectedEvent = { const expectedEvent = {
@ -50,9 +48,13 @@ describe('Sensor', () => {
let eventDispatched; let eventDispatched;
element.addEventListener('my:event', (event) => { element.addEventListener(
'my:event',
(event) => {
eventDispatched = event; eventDispatched = event;
}, true); },
true,
);
const returnValue = sensor.trigger(element, expectedEvent); const returnValue = sensor.trigger(element, expectedEvent);

View File

@ -7,7 +7,6 @@ import AbstractEvent from 'shared/AbstractEvent';
* @extends AbstractEvent * @extends AbstractEvent
*/ */
export class SensorEvent extends AbstractEvent { export class SensorEvent extends AbstractEvent {
/** /**
* Original browser event that triggered a sensor * Original browser event that triggered a sensor
* @property originalEvent * @property originalEvent

View File

@ -1,11 +1,6 @@
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import Sensor from '../Sensor'; import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onTouchStart = Symbol('onTouchStart'); const onTouchStart = Symbol('onTouchStart');
const onTouchHold = Symbol('onTouchHold'); const onTouchHold = Symbol('onTouchHold');
@ -16,7 +11,9 @@ const onScroll = Symbol('onScroll');
/** /**
* Adds default document.ontouchmove. Workaround for preventing scrolling on touchmove * Adds default document.ontouchmove. Workaround for preventing scrolling on touchmove
*/ */
document.ontouchmove = document.ontouchmove || function() { document.ontouchmove =
document.ontouchmove ||
function() {
return true; return true;
}; };
@ -27,7 +24,6 @@ document.ontouchmove = document.ontouchmove || function() {
* @extends Sensor * @extends Sensor
*/ */
export default class TouchSensor extends Sensor { export default class TouchSensor extends Sensor {
/** /**
* TouchSensor constructor. * TouchSensor constructor.
* @constructs TouchSensor * @constructs TouchSensor
@ -118,7 +114,9 @@ export default class TouchSensor extends Sensor {
*/ */
[onTouchHold](event, container) { [onTouchHold](event, container) {
return () => { return () => {
if (this.touchMoved) { return; } if (this.touchMoved) {
return;
}
const touch = event.touches[0] || event.changedTouches[0]; const touch = event.touches[0] || event.changedTouches[0];
const target = event.target; const target = event.target;

View File

@ -1,12 +1,4 @@
import { import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, touchStart, touchMove, touchRelease} from 'helper';
createSandbox,
triggerEvent,
waitForDragDelay,
DRAG_DELAY,
touchStart,
touchMove,
touchRelease,
} from 'helper';
import TouchSensor from '..'; import TouchSensor from '..';
@ -35,18 +27,17 @@ describe('TouchSensor', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('triggers `drag:start` sensor event on touchstart', () => { it('triggers `drag:start` sensor event on touchstart', () => {
function dragFlow() { function dragFlow() {
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
touchRelease(draggableElement); touchRelease(draggableElement);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.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) => { sandbox.addEventListener('drag:start', (event) => {
event.detail.cancel(); event.detail.cancel();
}); });
@ -57,11 +48,10 @@ describe('TouchSensor', () => {
touchRelease(draggableElement); touchRelease(draggableElement);
} }
expect(dragFlow) expect(dragFlow).toHaveCanceledSensorEvent('drag:start');
.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() { function dragFlow() {
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -73,22 +63,16 @@ describe('TouchSensor', () => {
touchRelease(document.body); touchRelease(document.body);
} }
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
expect(hastyDragFlow) expect(hastyDragFlow).not.toHaveTriggeredSensorEvent('drag:stop');
.not
.toHaveTriggeredSensorEvent('drag:stop');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:start');
.toHaveTriggeredSensorEvent('drag:start');
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.toHaveTriggeredSensorEvent('drag:stop');
}); });
test('triggers `drag:move` event while moving the finger', () => { it('triggers `drag:move` event while moving the finger', () => {
function dragFlow() { function dragFlow() {
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -96,11 +80,10 @@ describe('TouchSensor', () => {
touchRelease(draggableElement); touchRelease(draggableElement);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:move');
.toHaveTriggeredSensorEvent('drag:move');
}); });
test('triggers `drag:stop` event when releasing the finger', () => { it('triggers `drag:stop` event when releasing the finger', () => {
function dragFlow() { function dragFlow() {
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
@ -108,87 +91,72 @@ describe('TouchSensor', () => {
touchRelease(draggableElement); touchRelease(draggableElement);
} }
expect(dragFlow) expect(dragFlow).toHaveTriggeredSensorEvent('drag:stop');
.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() { function dragFlow() {
touchStart(document.body); touchStart(document.body);
waitForDragDelay(); waitForDragDelay();
} }
expect(dragFlow) expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
}); });
test('cancels `drag:start` if browser starts scrolling instead', () => { it('cancels `drag:start` if browser starts scrolling instead', () => {
function dragFlow() { function dragFlow() {
touchStart(draggableElement); touchStart(draggableElement);
triggerEvent(document.body, 'scroll'); triggerEvent(document.body, 'scroll');
waitForDragDelay(); waitForDragDelay();
} }
expect(dragFlow) expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
.not
.toHaveTriggeredSensorEvent('drag:start');
}); });
test('prevents context menu while dragging', () => { it('prevents context menu while dragging', () => {
touchStart(draggableElement); touchStart(draggableElement);
let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu'); let contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
waitForDragDelay(); waitForDragDelay();
expect(contextMenuEvent.defaultPrevented) expect(contextMenuEvent.defaultPrevented).toBe(true);
.toBe(true);
expect(contextMenuEvent.stoppedPropagation) expect(contextMenuEvent.stoppedPropagation).toBe(true);
.toBe(true);
touchRelease(draggableElement); touchRelease(draggableElement);
contextMenuEvent = triggerEvent(draggableElement, 'contextmenu'); contextMenuEvent = triggerEvent(draggableElement, 'contextmenu');
expect(contextMenuEvent.defaultPrevented) expect(contextMenuEvent.defaultPrevented).toBe(false);
.toBe(false);
expect(contextMenuEvent.stoppedPropagation) expect(contextMenuEvent.stoppedPropagation).toBeUndefined();
.toBeUndefined();
}); });
test('prevents scroll on touchmove while dragging', () => { it('prevents scroll on touchmove while dragging', () => {
let touchMoveEvent = touchMove(draggableElement); let touchMoveEvent = touchMove(draggableElement);
expect(touchMoveEvent.defaultPrevented) expect(touchMoveEvent.defaultPrevented).toBe(false);
.toBe(false);
expect(touchMoveEvent.stoppedPropagation) expect(touchMoveEvent.stoppedPropagation).toBeUndefined();
.toBeUndefined();
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
touchMoveEvent = touchMove(draggableElement); touchMoveEvent = touchMove(draggableElement);
expect(touchMoveEvent.defaultPrevented) expect(touchMoveEvent.defaultPrevented).toBe(true);
.toBe(true);
expect(touchMoveEvent.stoppedPropagation) expect(touchMoveEvent.stoppedPropagation).toBe(true);
.toBe(true);
touchRelease(draggableElement); touchRelease(draggableElement);
}); });
test('prevents clicking on touchend after dragging', () => { it('prevents clicking on touchend after dragging', () => {
let touchEndEvent = touchRelease(draggableElement); let touchEndEvent = touchRelease(draggableElement);
expect(touchEndEvent.defaultPrevented) expect(touchEndEvent.defaultPrevented).toBe(false);
.toBe(false);
touchStart(draggableElement); touchStart(draggableElement);
waitForDragDelay(); waitForDragDelay();
touchEndEvent = touchRelease(draggableElement); touchEndEvent = touchRelease(draggableElement);
expect(touchEndEvent.defaultPrevented) expect(touchEndEvent.defaultPrevented).toBe(true);
.toBe(true);
}); });
}); });

View File

@ -1,35 +1,9 @@
import { import {createSandbox, triggerEvent, TestPlugin} from 'helper';
createSandbox, import Draggable, {defaultOptions} from '../Draggable';
triggerEvent, import {DragStartEvent, DragMoveEvent, DragStopEvent} from '../DragEvent';
TestPlugin, import {DraggableInitializedEvent, DraggableDestroyEvent} from '../DraggableEvent';
} from 'helper'; import {Accessibility, Mirror, Scrollable, Announcement} from '../Plugins';
import {MouseSensor, TouchSensor} from '../Sensors';
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 = ` const sampleMarkup = `
<ul> <ul>
@ -54,7 +28,7 @@ describe('Draggable', () => {
}); });
describe('.Plugins', () => { describe('.Plugins', () => {
test('should be available statically', () => { it('should be available statically', () => {
expect(Draggable.Plugins).toBeDefined(); expect(Draggable.Plugins).toBeDefined();
expect(Draggable.Plugins.Mirror).toEqual(Mirror); expect(Draggable.Plugins.Mirror).toEqual(Mirror);
expect(Draggable.Plugins.Accessibility).toEqual(Accessibility); expect(Draggable.Plugins.Accessibility).toEqual(Accessibility);
@ -63,7 +37,7 @@ describe('Draggable', () => {
}); });
describe('#constructor', () => { describe('#constructor', () => {
test('should be an instance of Draggable', () => { it('should be an instance of Draggable', () => {
const draggable = new Draggable(containers, { const draggable = new Draggable(containers, {
draggable: 'li', draggable: 'li',
delay: 0, delay: 0,
@ -72,32 +46,29 @@ describe('Draggable', () => {
expect(draggable).toBeInstanceOf(Draggable); expect(draggable).toBeInstanceOf(Draggable);
}); });
test('should initialize with default options', () => { it('should initialize with default options', () => {
const newInstance = new Draggable(containers); const newInstance = new Draggable(containers);
for (const key in defaultOptions) { for (const key in defaultOptions) {
if (defaultOptions.hasOwnProperty(key)) { if (defaultOptions.hasOwnProperty(key)) {
expect(newInstance.options[key]) expect(newInstance.options[key]).toBe(defaultOptions[key]);
.toBe(defaultOptions[key]);
} }
} }
}); });
test('should set containers', () => { it('should set containers', () => {
const newInstance = new Draggable(containers); const newInstance = new Draggable(containers);
expect(newInstance.containers) expect(newInstance.containers).toMatchObject(Array.prototype.slice.call(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]); const newInstance = new Draggable(containers[0]);
expect(newInstance.containers) expect(newInstance.containers).toMatchObject([containers[0]]);
.toMatchObject([containers[0]]);
}); });
test('should throw error if `containers` argument is wrong type', () => { it('should throw error if `containers` argument is wrong type', () => {
expect(() => { expect(() => {
return new Draggable({}); return new Draggable({});
}).toThrow(); }).toThrow();
@ -107,72 +78,57 @@ describe('Draggable', () => {
}).toThrow(); }).toThrow();
}); });
test('should attach default plugins', () => { it('should attach default plugins', () => {
const newInstance = new Draggable(); const newInstance = new Draggable();
expect(newInstance.plugins.length) expect(newInstance.plugins).toHaveLength(4);
.toBe(4);
expect(newInstance.plugins[0]) expect(newInstance.plugins[0]).toBeInstanceOf(Mirror);
.toBeInstanceOf(Mirror);
expect(newInstance.plugins[1]) expect(newInstance.plugins[1]).toBeInstanceOf(Accessibility);
.toBeInstanceOf(Accessibility);
expect(newInstance.plugins[2]) expect(newInstance.plugins[2]).toBeInstanceOf(Scrollable);
.toBeInstanceOf(Scrollable);
expect(newInstance.plugins[3]) expect(newInstance.plugins[3]).toBeInstanceOf(Announcement);
.toBeInstanceOf(Announcement);
}); });
test('should attach custom plugins', () => { it('should attach custom plugins', () => {
const newInstance = new Draggable([], { const newInstance = new Draggable([], {
plugins: [TestPlugin], plugins: [TestPlugin],
}); });
expect(newInstance.plugins.length) expect(newInstance.plugins).toHaveLength(5);
.toBe(5);
const customPlugin = newInstance.plugins[4]; const customPlugin = newInstance.plugins[4];
expect(customPlugin.draggable).toBe(newInstance); expect(customPlugin.draggable).toBe(newInstance);
expect(customPlugin.attachFunction) expect(customPlugin.attachFunction).toHaveBeenCalled();
.toHaveBeenCalled();
expect(customPlugin.detachFunction) expect(customPlugin.detachFunction).not.toHaveBeenCalled();
.not
.toHaveBeenCalled();
}); });
test('should attach sensors', () => { it('should attach sensors', () => {
const newInstance = new Draggable([], { const newInstance = new Draggable([], {
native: false, native: false,
}); });
expect(newInstance.sensors.length) expect(newInstance.sensors).toHaveLength(2);
.toBe(2);
expect(newInstance.sensors[0]) expect(newInstance.sensors[0]).toBeInstanceOf(MouseSensor);
.toBeInstanceOf(MouseSensor);
expect(newInstance.sensors[1]) expect(newInstance.sensors[1]).toBeInstanceOf(TouchSensor);
.toBeInstanceOf(TouchSensor);
}); });
test('should trigger DraggableInitializedEvent on init', () => { it('should trigger DraggableInitializedEvent on init', () => {
const spy = jest.spyOn(Draggable.prototype, 'trigger'); const spy = jest.spyOn(Draggable.prototype, 'trigger');
const newInstance = new Draggable(); const newInstance = new Draggable();
expect(spy.mock.calls.length) expect(spy.mock.calls).toHaveLength(1);
.toBe(1);
expect(spy.mock.calls[0][0]) expect(spy.mock.calls[0][0]).toBeInstanceOf(DraggableInitializedEvent);
.toBeInstanceOf(DraggableInitializedEvent);
expect(spy.mock.calls[0][0].draggable) expect(spy.mock.calls[0][0].draggable).toBe(newInstance);
.toBe(newInstance);
spy.mockReset(); spy.mockReset();
spy.mockRestore(); spy.mockRestore();
@ -180,7 +136,7 @@ describe('Draggable', () => {
}); });
describe('#destroy', () => { describe('#destroy', () => {
test('triggers `draggable:destroy` event on destroy', () => { it('triggers `draggable:destroy` event on destroy', () => {
const newInstance = new Draggable(); const newInstance = new Draggable();
const callback = jest.fn(); const callback = jest.fn();
@ -190,17 +146,14 @@ describe('Draggable', () => {
const call = callback.mock.calls[0][0]; const call = callback.mock.calls[0][0];
expect(call.type) expect(call.type).toBe('draggable:destroy');
.toBe('draggable:destroy');
expect(call) expect(call).toBeInstanceOf(DraggableDestroyEvent);
.toBeInstanceOf(DraggableDestroyEvent);
expect(call.draggable) expect(call.draggable).toBe(newInstance);
.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 plugins = [TestPlugin, TestPlugin, TestPlugin];
const newInstance = new Draggable([], { const newInstance = new Draggable([], {
plugins, plugins,
@ -209,26 +162,20 @@ describe('Draggable', () => {
newInstance.destroy(); newInstance.destroy();
expect(expectedPlugins[4].detachFunction) expect(expectedPlugins[4].detachFunction).toHaveBeenCalled();
.toHaveBeenCalled();
expect(expectedPlugins[4].detachFunction) expect(expectedPlugins[4].detachFunction).toHaveBeenCalledTimes(1);
.toHaveBeenCalledTimes(1);
expect(expectedPlugins[5].detachFunction) expect(expectedPlugins[5].detachFunction).toHaveBeenCalled();
.toHaveBeenCalled();
expect(expectedPlugins[5].detachFunction) expect(expectedPlugins[5].detachFunction).toHaveBeenCalledTimes(1);
.toHaveBeenCalledTimes(1);
expect(expectedPlugins[6].detachFunction) expect(expectedPlugins[6].detachFunction).toHaveBeenCalled();
.toHaveBeenCalled();
expect(expectedPlugins[6].detachFunction) expect(expectedPlugins[6].detachFunction).toHaveBeenCalledTimes(1);
.toHaveBeenCalledTimes(1);
}); });
test('should remove all sensor event listeners', () => { it('should remove all sensor event listeners', () => {
document.removeEventListener = jest.fn(); document.removeEventListener = jest.fn();
const newInstance = new Draggable(); const newInstance = new Draggable();
@ -247,73 +194,71 @@ describe('Draggable', () => {
}); });
describe('#on', () => { 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(); const newInstance = new Draggable();
function stubHandler() { /* do nothing */ } function stubHandler() {
/* do nothing */
}
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(false);
.toBe(false);
newInstance.on('my:event', stubHandler); newInstance.on('my:event', stubHandler);
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(true);
.toBe(true);
expect(newInstance.emitter.callbacks['my:event']) expect(newInstance.emitter.callbacks['my:event']).toMatchObject([stubHandler]);
.toMatchObject([stubHandler]);
}); });
test('should return draggable instance', () => { it('should return draggable instance', () => {
const newInstance = new Draggable(); const newInstance = new Draggable();
function stubHandler() { /* do nothing */ } function stubHandler() {
/* do nothing */
}
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(false);
.toBe(false);
const returnValue = newInstance.on('my:event', stubHandler); const returnValue = newInstance.on('my:event', stubHandler);
expect(returnValue) expect(returnValue).toBe(newInstance);
.toBe(newInstance);
}); });
}); });
describe('#off', () => { 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(); const newInstance = new Draggable();
function stubHandler() { /* do nothing */ } function stubHandler() {
/* do nothing */
}
newInstance.on('my:event', stubHandler); newInstance.on('my:event', stubHandler);
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(true);
.toBe(true);
newInstance.off('my:event', stubHandler); newInstance.off('my:event', stubHandler);
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(true);
.toBe(true);
expect(newInstance.emitter.callbacks['my:event']) expect(newInstance.emitter.callbacks['my:event']).toMatchObject([]);
.toMatchObject([]);
}); });
test('should return draggable instance', () => { it('should return draggable instance', () => {
const newInstance = new Draggable(); const newInstance = new Draggable();
function stubHandler() { /* do nothing */ } function stubHandler() {
/* do nothing */
}
newInstance.on('my:event', stubHandler); newInstance.on('my:event', stubHandler);
expect('my:event' in newInstance.emitter.callbacks) expect('my:event' in newInstance.emitter.callbacks).toBe(true);
.toBe(true);
const returnValue = newInstance.off('my:event', stubHandler); const returnValue = newInstance.off('my:event', stubHandler);
expect(returnValue) expect(returnValue).toBe(newInstance);
.toBe(newInstance);
}); });
}); });
describe('#trigger', () => { describe('#trigger', () => {
test('should invoke bound event', () => { it('should invoke bound event', () => {
const newInstance = new Draggable(containers); const newInstance = new Draggable(containers);
const handler = jest.fn(); const handler = jest.fn();
const expectedEvent = new Event('my:event'); const expectedEvent = new Event('my:event');
@ -322,19 +267,16 @@ describe('Draggable', () => {
newInstance.trigger(expectedEvent); newInstance.trigger(expectedEvent);
expect(handler.mock.calls.length) expect(handler.mock.calls).toHaveLength(1);
.toBe(1);
expect(handler.mock.calls[0].length) expect(handler.mock.calls[0]).toHaveLength(1);
.toBe(1);
expect(handler.mock.calls[0][0]) expect(handler.mock.calls[0][0]).toBe(expectedEvent);
.toBe(expectedEvent);
}); });
}); });
describe('#getDraggableElementsForContainer', () => { 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -348,13 +290,13 @@ describe('Draggable', () => {
const containerChildren = newInstance.getDraggableElementsForContainer(draggableElement.parentNode); const containerChildren = newInstance.getDraggableElementsForContainer(draggableElement.parentNode);
expect(containerChildren.length).toEqual(2); expect(containerChildren).toHaveLength(2);
triggerEvent(draggableElement, 'mouseup', {button: 0}); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -371,16 +313,14 @@ describe('Draggable', () => {
const call = callback.mock.calls[0][0]; const call = callback.mock.calls[0][0];
expect(call.type) expect(call.type).toBe('drag:start');
.toBe('drag:start');
expect(call) expect(call).toBeInstanceOf(DragStartEvent);
.toBeInstanceOf(DragStartEvent);
triggerEvent(draggableElement, 'mouseup'); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -399,16 +339,14 @@ describe('Draggable', () => {
const call = callback.mock.calls[0][0]; const call = callback.mock.calls[0][0];
expect(call.type) expect(call.type).toBe('drag:start');
.toBe('drag:start');
expect(call) expect(call).toBeInstanceOf(DragStartEvent);
.toBeInstanceOf(DragStartEvent);
triggerEvent(draggableElement, 'mouseup'); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -437,7 +375,7 @@ describe('Draggable', () => {
expect(originalSource.style.display).toEqual(''); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -460,22 +398,18 @@ describe('Draggable', () => {
const call = callback.mock.calls[0][0]; const call = callback.mock.calls[0][0];
const sensorEvent = call.data.sensorEvent; const sensorEvent = call.data.sensorEvent;
expect(call.type) expect(call.type).toBe('drag:move');
.toBe('drag:move');
expect(call) expect(call).toBeInstanceOf(DragMoveEvent);
.toBeInstanceOf(DragMoveEvent);
expect(sensorEvent.clientX) expect(sensorEvent.clientX).toBe(expectedClientX);
.toBe(expectedClientX);
expect(sensorEvent.clientY) expect(sensorEvent.clientY).toBe(expectedClientY);
.toBe(expectedClientY);
triggerEvent(draggableElement, 'mouseup'); triggerEvent(draggableElement, 'mouseup');
}); });
test('triggers `drag:stop` drag event on mouseup', () => { it('triggers `drag:stop` drag event on mouseup', () => {
const newInstance = new Draggable(containers, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -494,14 +428,12 @@ describe('Draggable', () => {
const call = callback.mock.calls[0][0]; const call = callback.mock.calls[0][0];
expect(call.type) expect(call.type).toBe('drag:stop');
.toBe('drag:stop');
expect(call) expect(call).toBeInstanceOf(DragStopEvent);
.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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -513,13 +445,12 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(newInstance.source.classList) expect(newInstance.source.classList).toContain('draggable-source--is-dragging');
.toContain('draggable-source--is-dragging');
triggerEvent(draggableElement, 'mouseup'); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -533,17 +464,14 @@ describe('Draggable', () => {
const source = newInstance.source; const source = newInstance.source;
expect(source.classList) expect(source.classList).toContain('draggable-source--is-dragging');
.toContain('draggable-source--is-dragging');
triggerEvent(draggableElement, 'mouseup', {button: 0}); triggerEvent(draggableElement, 'mouseup', {button: 0});
expect(source.classList) expect(source.classList).not.toContain('draggable-source--is-dragging');
.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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -551,8 +479,7 @@ describe('Draggable', () => {
document.elementFromPoint = () => draggableElement; document.elementFromPoint = () => draggableElement;
newInstance.on('drag:start', (event) => { newInstance.on('drag:start', (event) => {
expect(newInstance.source.classList) expect(newInstance.source.classList).toContain('draggable-source--is-dragging');
.toContain('draggable-source--is-dragging');
event.cancel(); event.cancel();
}); });
@ -564,13 +491,12 @@ describe('Draggable', () => {
const source = newInstance.source; const source = newInstance.source;
expect(source.classList) expect(source.classList).not.toContain('draggable-source--is-dragging');
.not
.toContain('draggable-source--is-dragging');
}); });
test('adds `body:dragging` classname to body on mousedown', () => { it('adds `body:dragging` classname to body on mousedown', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -581,14 +507,14 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(document.body.classList) expect(document.body.classList).toContain('draggable--is-dragging');
.toContain('draggable--is-dragging');
triggerEvent(draggableElement, 'mouseup'); triggerEvent(draggableElement, 'mouseup');
}); });
test('removes `body:dragging` classname from body on mouseup', () => { it('removes `body:dragging` classname from body on mouseup', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -599,17 +525,14 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(document.body.classList) expect(document.body.classList).toContain('draggable--is-dragging');
.toContain('draggable--is-dragging');
triggerEvent(document.body, 'mouseup', {button: 0}); triggerEvent(document.body, 'mouseup', {button: 0});
expect(document.body.classList) expect(document.body.classList).not.toContain('draggable--is-dragging');
.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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -617,8 +540,7 @@ describe('Draggable', () => {
document.elementFromPoint = () => draggableElement; document.elementFromPoint = () => draggableElement;
newInstance.on('drag:start', (event) => { newInstance.on('drag:start', (event) => {
expect(document.body.classList) expect(document.body.classList).toContain('draggable--is-dragging');
.toContain('draggable--is-dragging');
event.cancel(); event.cancel();
}); });
@ -628,13 +550,12 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(document.body.classList) expect(document.body.classList).not.toContain('draggable--is-dragging');
.not
.toContain('draggable--is-dragging');
}); });
test('adds `container:placed` classname to draggable container element on mouseup', () => { it('adds `container:placed` classname to draggable container element on mouseup', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -647,12 +568,12 @@ describe('Draggable', () => {
triggerEvent(draggableElement, 'mouseup', {button: 0}); triggerEvent(draggableElement, 'mouseup', {button: 0});
expect(containers[0].classList) expect(containers[0].classList).toContain('draggable-container--placed');
.toContain('draggable-container--placed');
}); });
test('removes `container:placed` classname from draggable container element on mouseup after delay', () => { it('removes `container:placed` classname from draggable container element on mouseup after delay', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -665,19 +586,17 @@ describe('Draggable', () => {
triggerEvent(document.body, 'mouseup', {button: 0}); triggerEvent(document.body, 'mouseup', {button: 0});
expect(containers[0].classList) expect(containers[0].classList).toContain('draggable-container--placed');
.toContain('draggable-container--placed');
// Wait for default draggable.options.placedTimeout delay // Wait for default draggable.options.placedTimeout delay
jest.runTimersToTime(800); jest.runTimersToTime(800);
expect(containers[0].classList) expect(containers[0].classList).not.toContain('draggable-container--placed');
.not
.toContain('draggable-container--placed');
}); });
test('adds `container:dragging` classname to draggable container element on mousedown', () => { it('adds `container:dragging` classname to draggable container element on mousedown', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -688,14 +607,14 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(containers[0].classList) expect(containers[0].classList).toContain('draggable-container--is-dragging');
.toContain('draggable-container--is-dragging');
triggerEvent(draggableElement, 'mouseup', {button: 0}); triggerEvent(draggableElement, 'mouseup', {button: 0});
}); });
test('removes `container:dragging` classname from draggable container element on mouseup', () => { it('removes `container:dragging` classname from draggable container element on mouseup', () => {
(() => new Draggable(containers, { (() =>
new Draggable(containers, {
draggable: 'li', draggable: 'li',
}))(); }))();
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
@ -706,25 +625,21 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(containers[0].classList) expect(containers[0].classList).toContain('draggable-container--is-dragging');
.toContain('draggable-container--is-dragging');
triggerEvent(document.body, 'mouseup', {button: 0}); triggerEvent(document.body, 'mouseup', {button: 0});
expect(containers[0].classList) expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
.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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
const draggableElement = sandbox.querySelector('li'); const draggableElement = sandbox.querySelector('li');
newInstance.on('drag:start', (event) => { newInstance.on('drag:start', (event) => {
expect(containers[0].classList) expect(containers[0].classList).toContain('draggable-container--is-dragging');
.toContain('draggable-container--is-dragging');
event.cancel(); event.cancel();
}); });
@ -734,12 +649,10 @@ describe('Draggable', () => {
// Wait for delay // Wait for delay
jest.runTimersToTime(100); jest.runTimersToTime(100);
expect(containers[0].classList) expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
.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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });
@ -758,7 +671,7 @@ describe('Draggable', () => {
expect(draggableElement.classList.contains(newInstance.getClassNameFor('source:original'))).toBeFalsy(); 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, { const newInstance = new Draggable(containers, {
draggable: 'li', draggable: 'li',
}); });

View File

@ -1,10 +1,6 @@
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import Draggable from '../Draggable'; import Draggable from '../Draggable';
import {DroppableOverEvent, DroppableOutEvent} from './DroppableEvent';
import {
DroppableOverEvent,
DroppableOutEvent,
} from './DroppableEvent';
const onDragStart = Symbol('onDragStart'); const onDragStart = Symbol('onDragStart');
const onDragMove = Symbol('onDragMove'); const onDragMove = Symbol('onDragMove');
@ -65,7 +61,6 @@ const defaultOptions = {
* @extends Draggable * @extends Draggable
*/ */
export default class Droppable extends Draggable { export default class Droppable extends Draggable {
/** /**
* Droppable constructor. * Droppable constructor.
* @constructs Droppable * @constructs Droppable
@ -111,8 +106,7 @@ export default class Droppable extends Draggable {
this[onDragMove] = this[onDragMove].bind(this); this[onDragMove] = this[onDragMove].bind(this);
this[onDragStop] = this[onDragStop].bind(this); this[onDragStop] = this[onDragStop].bind(this);
this this.on('drag:start', this[onDragStart])
.on('drag:start', this[onDragStart])
.on('drag:move', this[onDragMove]) .on('drag:move', this[onDragMove])
.on('drag:stop', this[onDragStop]); .on('drag:stop', this[onDragStop]);
} }
@ -123,8 +117,7 @@ export default class Droppable extends Draggable {
destroy() { destroy() {
super.destroy(); super.destroy();
this this.off('drag:start', this[onDragStart])
.off('drag:start', this[onDragStart])
.off('drag:move', this[onDragMove]) .off('drag:move', this[onDragMove])
.off('drag:stop', this[onDragStop]); .off('drag:stop', this[onDragStop]);
} }

View File

@ -1,10 +1,6 @@
import AbstractPlugin from 'shared/AbstractPlugin'; import AbstractPlugin from 'shared/AbstractPlugin';
import {closest} from 'shared/utils'; import {closest} from 'shared/utils';
import {CollidableInEvent, CollidableOutEvent} from './CollidableEvent';
import {
CollidableInEvent,
CollidableOutEvent,
} from './CollidableEvent';
const onDragMove = Symbol('onDragMove'); const onDragMove = Symbol('onDragMove');
const onDragStop = Symbol('onDragStop'); const onDragStop = Symbol('onDragStop');
@ -17,7 +13,6 @@ const onRequestAnimationFrame = Symbol('onRequestAnimationFrame');
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Collidable extends AbstractPlugin { export default class Collidable extends AbstractPlugin {
/** /**
* Collidable constructor. * Collidable constructor.
* @constructs Collidable * @constructs Collidable
@ -56,18 +51,14 @@ export default class Collidable extends AbstractPlugin {
* Attaches plugins event listeners * Attaches plugins event listeners
*/ */
attach() { attach() {
this.draggable this.draggable.on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop]);
.on('drag:move', this[onDragMove])
.on('drag:stop', this[onDragStop]);
} }
/** /**
* Detaches plugins event listeners * Detaches plugins event listeners
*/ */
detach() { detach() {
this.draggable this.draggable.off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop]);
.off('drag:move', this[onDragMove])
.off('drag:stop', this[onDragStop]);
} }
/** /**
@ -114,7 +105,9 @@ export default class Collidable extends AbstractPlugin {
collidingElement: this.lastCollidingElement, 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); const leavingCollidable = Boolean(!this.currentlyCollidingElement && this.lastCollidingElement);
if (enteringCollidable) { if (enteringCollidable) {

View File

@ -1,9 +1,5 @@
import AbstractPlugin from 'shared/AbstractPlugin'; import AbstractPlugin from 'shared/AbstractPlugin';
import {SnapInEvent, SnapOutEvent} from './SnappableEvent';
import {
SnapInEvent,
SnapOutEvent,
} from './SnappableEvent';
const onDragStart = Symbol('onDragStart'); const onDragStart = Symbol('onDragStart');
const onDragStop = Symbol('onDragStop'); const onDragStop = Symbol('onDragStop');
@ -17,7 +13,6 @@ const onDragOut = Symbol('onDragOut');
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class Snappable extends AbstractPlugin { export default class Snappable extends AbstractPlugin {
/** /**
* Snappable constructor. * Snappable constructor.
* @constructs Snappable * @constructs Snappable

View File

@ -21,7 +21,6 @@ export const defaultOptions = {
* @extends AbstractPlugin * @extends AbstractPlugin
*/ */
export default class SwapAnimation extends AbstractPlugin { export default class SwapAnimation extends AbstractPlugin {
/** /**
* SwapAnimation constructor. * SwapAnimation constructor.
* @constructs SwapAnimation * @constructs SwapAnimation

View File

@ -1,12 +1,3 @@
export { export {default as Collidable} from './Collidable';
default as Collidable, export {default as Snappable} from './Snappable';
} from './Collidable'; export {default as SwapAnimation, defaultOptions as defaultSwapAnimationOptions} from './SwapAnimation';
export {
default as Snappable,
} from './Snappable';
export {
default as SwapAnimation,
defaultOptions as defaultSwapAnimationOptions,
} from './SwapAnimation';

View File

@ -1,11 +1,5 @@
import Draggable from '../Draggable'; import Draggable from '../Draggable';
import {SortableStartEvent, SortableSortEvent, SortableSortedEvent, SortableStopEvent} from './SortableEvent';
import {
SortableStartEvent,
SortableSortEvent,
SortableSortedEvent,
SortableStopEvent,
} from './SortableEvent';
const onDragStart = Symbol('onDragStart'); const onDragStart = Symbol('onDragStart');
const onDragOverContainer = Symbol('onDragOverContainer'); const onDragOverContainer = Symbol('onDragOverContainer');
@ -52,7 +46,6 @@ const defaultAnnouncements = {
* @extends Draggable * @extends Draggable
*/ */
export default class Sortable extends Draggable { export default class Sortable extends Draggable {
/** /**
* Sortable constructor. * Sortable constructor.
* @constructs Sortable * @constructs Sortable
@ -88,8 +81,7 @@ export default class Sortable extends Draggable {
this[onDragOver] = this[onDragOver].bind(this); this[onDragOver] = this[onDragOver].bind(this);
this[onDragStop] = this[onDragStop].bind(this); this[onDragStop] = this[onDragStop].bind(this);
this this.on('drag:start', this[onDragStart])
.on('drag:start', this[onDragStart])
.on('drag:over:container', this[onDragOverContainer]) .on('drag:over:container', this[onDragOverContainer])
.on('drag:over', this[onDragOver]) .on('drag:over', this[onDragOver])
.on('drag:stop', this[onDragStop]); .on('drag:stop', this[onDragStop]);
@ -101,8 +93,7 @@ export default class Sortable extends Draggable {
destroy() { destroy() {
super.destroy(); super.destroy();
this this.off('drag:start', this[onDragStart])
.off('drag:start', this[onDragStart])
.off('drag:over:container', this[onDragOverContainer]) .off('drag:over:container', this[onDragOverContainer])
.off('drag:over', this[onDragOver]) .off('drag:over', this[onDragOver])
.off('drag:stop', this[onDragStop]); .off('drag:stop', this[onDragStop]);
@ -260,7 +251,7 @@ function index(element) {
function move({source, over, overContainer, children}) { function move({source, over, overContainer, children}) {
const emptyOverContainer = !children.length; const emptyOverContainer = !children.length;
const differentContainer = (source.parentNode !== overContainer); const differentContainer = source.parentNode !== overContainer;
const sameContainer = over && !differentContainer; const sameContainer = over && !differentContainer;
if (emptyOverContainer) { if (emptyOverContainer) {

View File

@ -1,12 +1,4 @@
import { import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
createSandbox,
clickMouse,
moveMouse,
releaseMouse,
waitForDragDelay,
DRAG_DELAY,
} from 'helper';
import Sortable from '..'; import Sortable from '..';
const sampleMarkup = ` const sampleMarkup = `
@ -69,7 +61,7 @@ describe('Sortable', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('triggers events', () => { it('triggers events', () => {
const sortableStart = jest.fn(); const sortableStart = jest.fn();
const sortableSort = jest.fn(); const sortableSort = jest.fn();
const sortableSorted = jest.fn(); const sortableSorted = jest.fn();
@ -85,20 +77,16 @@ describe('Sortable', () => {
moveMouse(secondItem); moveMouse(secondItem);
releaseMouse(sortable.source); releaseMouse(sortable.source);
expect(sortableStart) expect(sortableStart).toHaveBeenCalled();
.toHaveBeenCalled();
expect(sortableSort) expect(sortableSort).toHaveBeenCalled();
.toHaveBeenCalled();
expect(sortableSorted) expect(sortableSorted).toHaveBeenCalled();
.toHaveBeenCalled();
expect(sortableStop) expect(sortableStop).toHaveBeenCalled();
.toHaveBeenCalled();
}); });
test('prevents drag when canceling sortable start event', () => { it('prevents drag when canceling sortable start event', () => {
sortable.on('sortable:start', (sortableEvent) => { sortable.on('sortable:start', (sortableEvent) => {
sortableEvent.cancel(); sortableEvent.cancel();
}); });
@ -107,20 +95,17 @@ describe('Sortable', () => {
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
expect(sortable.isDragging()) expect(sortable.isDragging()).toBe(false);
.toBe(false);
releaseMouse(sortable.source); releaseMouse(sortable.source);
}); });
test('sorts two first elements', () => { it('sorts two first elements', () => {
draggableElements = sandbox.querySelectorAll('li'); draggableElements = sandbox.querySelectorAll('li');
expect(draggableElements[0]) expect(draggableElements[0]).toBe(firstItem);
.toBe(firstItem);
expect(draggableElements[1]) expect(draggableElements[1]).toBe(secondItem);
.toBe(secondItem);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
@ -129,32 +114,21 @@ describe('Sortable', () => {
draggableElements = sandbox.querySelectorAll('li'); draggableElements = sandbox.querySelectorAll('li');
expect(draggableElements[0]) expect(draggableElements[0]).toBe(secondItem);
.toBe(secondItem);
expect(draggableElements[1]) expect(draggableElements[1]).toBe(firstItem);
.toBe(firstItem);
}); });
test('sorts elements as you drag within a single container', () => { it('sorts elements as you drag within a single container', () => {
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(containers[0]);
sortable.getDraggableElementsForContainer(containers[0]); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
secondItem, secondItem,
// original firstItem // original firstItem
sortable.source, sortable.source,
@ -164,10 +138,8 @@ describe('Sortable', () => {
moveMouse(thirdItem); moveMouse(thirdItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
secondItem, secondItem,
thirdItem, thirdItem,
// original firstItem // original firstItem
@ -177,10 +149,8 @@ describe('Sortable', () => {
moveMouse(forthItem); moveMouse(forthItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
secondItem, secondItem,
thirdItem, thirdItem,
forthItem, forthItem,
@ -190,55 +160,26 @@ describe('Sortable', () => {
releaseMouse(sortable.source); releaseMouse(sortable.source);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem, firstItem]);
expect(draggableElements)
.toHaveOrder([
secondItem,
thirdItem,
forthItem,
firstItem,
]);
}); });
test('sorts elements as you drag between multiple containers', () => { it('sorts elements as you drag between multiple containers', () => {
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
expect(draggableElements)
.toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
eighthItem,
]);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
moveMouse(fifthItem); moveMouse(fifthItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
// original firstItem // original firstItem
sortable.source, sortable.source,
fifthItem, fifthItem,
@ -249,19 +190,11 @@ describe('Sortable', () => {
moveMouse(eighthItem); moveMouse(eighthItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
fifthItem, fifthItem,
sixthItem, sixthItem,
seventhItem, seventhItem,
@ -272,28 +205,14 @@ describe('Sortable', () => {
releaseMouse(sortable.source); releaseMouse(sortable.source);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem, firstItem]);
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) => { sortable.on('sortable:sort', (sortableEvent) => {
sortableEvent.cancel(); sortableEvent.cancel();
}); });
@ -302,43 +221,25 @@ describe('Sortable', () => {
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([sortable.source, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
sortable.source,
secondItem,
thirdItem,
forthItem,
]);
releaseMouse(sortable.source); releaseMouse(sortable.source);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
}); });
test('sorts elements into empty container', () => { it('sorts elements into empty container', () => {
[fifthItem, sixthItem, seventhItem, eighthItem].forEach( [fifthItem, sixthItem, seventhItem, eighthItem].forEach((item) => {
(item) => {
clickMouse(item); clickMouse(item);
waitForDragDelay(); waitForDragDelay();
moveMouse(firstItem); moveMouse(firstItem);
releaseMouse(sortable.source); releaseMouse(sortable.source);
}, });
);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
fifthItem, fifthItem,
sixthItem, sixthItem,
seventhItem, seventhItem,
@ -349,19 +250,15 @@ describe('Sortable', () => {
forthItem, forthItem,
]); ]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([]);
expect(draggableElements)
.toHaveOrder([]);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
moveMouse(secondContainer); moveMouse(secondContainer);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
fifthItem, fifthItem,
sixthItem, sixthItem,
seventhItem, seventhItem,
@ -371,19 +268,13 @@ describe('Sortable', () => {
forthItem, forthItem,
]); ]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([sortable.source]);
expect(draggableElements)
.toHaveOrder([
sortable.source,
]);
releaseMouse(sortable.source); releaseMouse(sortable.source);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
sortable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
fifthItem, fifthItem,
sixthItem, sixthItem,
seventhItem, seventhItem,
@ -393,11 +284,7 @@ describe('Sortable', () => {
forthItem, forthItem,
]); ]);
draggableElements = draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
sortable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([firstItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
]);
}); });
}); });

View File

@ -1,11 +1,5 @@
import Draggable from '../Draggable'; import Draggable from '../Draggable';
import {SwappableStartEvent, SwappableSwapEvent, SwappableSwappedEvent, SwappableStopEvent} from './SwappableEvent';
import {
SwappableStartEvent,
SwappableSwapEvent,
SwappableSwappedEvent,
SwappableStopEvent,
} from './SwappableEvent';
const onDragStart = Symbol('onDragStart'); const onDragStart = Symbol('onDragStart');
const onDragOver = Symbol('onDragOver'); const onDragOver = Symbol('onDragOver');
@ -39,7 +33,6 @@ const defaultAnnouncements = {
* @extends Draggable * @extends Draggable
*/ */
export default class Swappable extends Draggable { export default class Swappable extends Draggable {
/** /**
* Swappable constructor. * Swappable constructor.
* @constructs Swappable * @constructs Swappable
@ -66,8 +59,7 @@ export default class Swappable extends Draggable {
this[onDragOver] = this[onDragOver].bind(this); this[onDragOver] = this[onDragOver].bind(this);
this[onDragStop] = this[onDragStop].bind(this); this[onDragStop] = this[onDragStop].bind(this);
this this.on('drag:start', this[onDragStart])
.on('drag:start', this[onDragStart])
.on('drag:over', this[onDragOver]) .on('drag:over', this[onDragOver])
.on('drag:stop', this[onDragStop]); .on('drag:stop', this[onDragStop]);
} }
@ -78,8 +70,7 @@ export default class Swappable extends Draggable {
destroy() { destroy() {
super.destroy(); super.destroy();
this this.off('drag:start', this._onDragStart)
.off('drag:start', this._onDragStart)
.off('drag:over', this._onDragOver) .off('drag:over', this._onDragOver)
.off('drag:stop', this._onDragStop); .off('drag:stop', this._onDragStop);
} }

View File

@ -1,12 +1,4 @@
import { import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
createSandbox,
clickMouse,
moveMouse,
releaseMouse,
waitForDragDelay,
DRAG_DELAY,
} from 'helper';
import Swappable from '..'; import Swappable from '..';
const sampleMarkup = ` const sampleMarkup = `
@ -69,7 +61,7 @@ describe('Swappable', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('triggers events', () => { it('triggers events', () => {
const swappableStart = jest.fn(); const swappableStart = jest.fn();
const swappableSwap = jest.fn(); const swappableSwap = jest.fn();
const swappableSwapped = jest.fn(); const swappableSwapped = jest.fn();
@ -85,20 +77,16 @@ describe('Swappable', () => {
moveMouse(secondItem); moveMouse(secondItem);
releaseMouse(swappable.source); releaseMouse(swappable.source);
expect(swappableStart) expect(swappableStart).toHaveBeenCalled();
.toHaveBeenCalled();
expect(swappableSwap) expect(swappableSwap).toHaveBeenCalled();
.toHaveBeenCalled();
expect(swappableSwapped) expect(swappableSwapped).toHaveBeenCalled();
.toHaveBeenCalled();
expect(swappableStop) expect(swappableStop).toHaveBeenCalled();
.toHaveBeenCalled();
}); });
test('prevents drag when canceling sortable start event', () => { it('prevents drag when canceling sortable start event', () => {
swappable.on('swappable:start', (swappableEvent) => { swappable.on('swappable:start', (swappableEvent) => {
swappableEvent.cancel(); swappableEvent.cancel();
}); });
@ -107,20 +95,17 @@ describe('Swappable', () => {
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
expect(swappable.isDragging()) expect(swappable.isDragging()).toBe(false);
.toBe(false);
releaseMouse(swappable.source); releaseMouse(swappable.source);
}); });
test('swaps two first elements', () => { it('swaps two first elements', () => {
draggableElements = sandbox.querySelectorAll('li'); draggableElements = sandbox.querySelectorAll('li');
expect(draggableElements[0]) expect(draggableElements[0]).toBe(firstItem);
.toBe(firstItem);
expect(draggableElements[1]) expect(draggableElements[1]).toBe(secondItem);
.toBe(secondItem);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
@ -129,32 +114,21 @@ describe('Swappable', () => {
draggableElements = sandbox.querySelectorAll('li'); draggableElements = sandbox.querySelectorAll('li');
expect(draggableElements[0]) expect(draggableElements[0]).toBe(secondItem);
.toBe(secondItem);
expect(draggableElements[1]) expect(draggableElements[1]).toBe(firstItem);
.toBe(firstItem);
}); });
test('swaps elements as you drag within a single container', () => { it('swaps elements as you drag within a single container', () => {
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(containers[0]);
swappable.getDraggableElementsForContainer(containers[0]); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
secondItem, secondItem,
// original firstItem // original firstItem
swappable.source, swappable.source,
@ -164,10 +138,8 @@ describe('Swappable', () => {
moveMouse(thirdItem); moveMouse(thirdItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
thirdItem, thirdItem,
secondItem, secondItem,
// original firstItem // original firstItem
@ -177,10 +149,8 @@ describe('Swappable', () => {
moveMouse(forthItem); moveMouse(forthItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
forthItem, forthItem,
secondItem, secondItem,
thirdItem, thirdItem,
@ -190,56 +160,26 @@ describe('Swappable', () => {
releaseMouse(swappable.source); releaseMouse(swappable.source);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([forthItem, secondItem, thirdItem, firstItem]);
expect(draggableElements)
.toHaveOrder([
forthItem,
secondItem,
thirdItem,
firstItem,
]);
}); });
test('sorts elements as you drag between multiple containers', () => { it('sorts elements as you drag between multiple containers', () => {
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
swappable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
expect(draggableElements)
.toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
eighthItem,
]);
clickMouse(firstItem); clickMouse(firstItem);
waitForDragDelay(); waitForDragDelay();
moveMouse(fifthItem); moveMouse(fifthItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([fifthItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
fifthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
swappable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
// original firstItem // original firstItem
swappable.source, swappable.source,
sixthItem, sixthItem,
@ -249,20 +189,11 @@ describe('Swappable', () => {
moveMouse(eighthItem); moveMouse(eighthItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
eighthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
swappable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([
expect(draggableElements)
.toHaveOrder([
fifthItem, fifthItem,
sixthItem, sixthItem,
seventhItem, seventhItem,
@ -272,28 +203,14 @@ describe('Swappable', () => {
releaseMouse(swappable.source); releaseMouse(swappable.source);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
eighthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
swappable.getDraggableElementsForContainer(secondContainer); expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, firstItem]);
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) => { swappable.on('swappable:swap', (swappableEvent) => {
swappableEvent.cancel(); swappableEvent.cancel();
}); });
@ -302,26 +219,12 @@ describe('Swappable', () => {
waitForDragDelay(); waitForDragDelay();
moveMouse(secondItem); moveMouse(secondItem);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([swappable.source, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
swappable.source,
secondItem,
thirdItem,
forthItem,
]);
releaseMouse(swappable.source); releaseMouse(swappable.source);
draggableElements = draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
swappable.getDraggableElementsForContainer(firstContainer); expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
expect(draggableElements)
.toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
}); });
}); });

View File

@ -4,25 +4,9 @@ import AbstractPlugin from 'shared/AbstractPlugin';
import * as Sensors from './Draggable/Sensors'; import * as Sensors from './Draggable/Sensors';
import * as Plugins from './Plugins'; import * as Plugins from './Plugins';
export { export {default as Draggable} from './Draggable';
default as Draggable, export {default as Droppable} from './Droppable';
} from './Draggable'; export {default as Swappable} from './Swappable';
export {default as Sortable} from './Sortable';
export { export {AbstractEvent as BaseEvent, AbstractPlugin as BasePlugin, Sensors, Plugins};
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,
};

View File

@ -9,25 +9,9 @@ import AbstractPlugin from 'shared/AbstractPlugin';
import * as Sensors from './Draggable/Sensors'; import * as Sensors from './Draggable/Sensors';
import * as Plugins from './Plugins'; import * as Plugins from './Plugins';
export { export {default as Draggable} from './Draggable';
default as Draggable, export {default as Droppable} from './Droppable';
} from './Draggable'; export {default as Swappable} from './Swappable';
export {default as Sortable} from './Sortable';
export { export {AbstractEvent as BaseEvent, AbstractPlugin as BasePlugin, Sensors, Plugins};
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,
};

View File

@ -9,7 +9,6 @@ const canceled = Symbol('canceled');
* @module AbstractEvent * @module AbstractEvent
*/ */
export default class AbstractEvent { export default class AbstractEvent {
/** /**
* Event type * Event type
* @static * @static

View File

@ -1,31 +1,31 @@
import AbstractEvent from '../AbstractEvent'; import AbstractEvent from '../AbstractEvent';
describe('AbstractEvent', () => { describe('AbstractEvent', () => {
test('should be of type AbstractEvent', () => { it('should be of type AbstractEvent', () => {
const event = new AbstractEvent(); const event = new AbstractEvent();
expect(event).toBeInstanceOf(AbstractEvent); expect(event).toBeInstanceOf(AbstractEvent);
}); });
test('should initialize with correct type', () => { it('should initialize with correct type', () => {
const event = new AbstractEvent(); const event = new AbstractEvent();
expect(event.type).toBe('event'); expect(event.type).toBe('event');
}); });
test('should initialize in uncancelable state', () => { it('should initialize in uncancelable state', () => {
const event = new AbstractEvent(); const event = new AbstractEvent();
expect(event.cancelable).toBe(false); expect(event.cancelable).toBe(false);
}); });
test('should initialize in uncancelled state', () => { it('should initialize in uncancelled state', () => {
const event = new AbstractEvent(); const event = new AbstractEvent();
expect(event.canceled()).toBe(false); expect(event.canceled()).toBe(false);
}); });
test('should initialize with data', () => { it('should initialize with data', () => {
const event = new AbstractEvent({ const event = new AbstractEvent({
foo: 'bar', foo: 'bar',
}); });
@ -35,7 +35,7 @@ describe('AbstractEvent', () => {
}); });
}); });
test('should cancel event', () => { it('should cancel event', () => {
const event = new AbstractEvent(); const event = new AbstractEvent();
expect(event.canceled()).toBe(false); expect(event.canceled()).toBe(false);

View File

@ -5,14 +5,12 @@
* @module AbstractPlugin * @module AbstractPlugin
*/ */
export default class AbstractPlugin { export default class AbstractPlugin {
/** /**
* AbstractPlugin constructor. * AbstractPlugin constructor.
* @constructs AbstractPlugin * @constructs AbstractPlugin
* @param {Draggable} draggable - Draggable instance * @param {Draggable} draggable - Draggable instance
*/ */
constructor(draggable) { constructor(draggable) {
/** /**
* Draggable instance * Draggable instance
* @property draggable * @property draggable

View File

@ -1,4 +1,5 @@
const matchFunction = Element.prototype.matches || const matchFunction =
Element.prototype.matches ||
Element.prototype.webkitMatchesSelector || Element.prototype.webkitMatchesSelector ||
Element.prototype.mozMatchesSelector || Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector; Element.prototype.msMatchesSelector;
@ -47,9 +48,11 @@ export default function closest(element, value) {
do { do {
current = current.correspondingUseElement || current.correspondingElement || current; current = current.correspondingUseElement || current.correspondingElement || current;
if (conditionFn(current)) { if (conditionFn(current)) {
return current; return current;
} }
current = current.parentNode; current = current.parentNode;
} while (current && current !== document.body && current !== document); } while (current && current !== document.body && current !== document);

View File

@ -1,7 +1,4 @@
import { import {createSandbox} from 'helper';
createSandbox,
} from 'helper';
import closest from '../closest'; import closest from '../closest';
const sampleMarkup = ` const sampleMarkup = `
@ -25,52 +22,43 @@ describe('utils', () => {
sandbox.parentNode.removeChild(sandbox); sandbox.parentNode.removeChild(sandbox);
}); });
test('should return null when no element specified', () => { it('should return null when no element specified', () => {
expect(closest()).toBe(null); 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'); 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'); 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'); 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'); const element = sandbox.querySelector('.leaf');
function callback(currentElement) { function callback(currentElement) {
return currentElement return currentElement.classList.contains('leaf');
.classList
.contains('leaf');
} }
expect(closest(element, callback)).toBe(element); expect(closest(element, callback)).toBe(element);
}); });
[ ['.twig', 'ul', '.branch', 'section', '.tree', 'div', 'body', 'document'].forEach((expectedMatchingSelector) => {
'.twig', it(`should return matched element when selector targets parent element matching selector ${expectedMatchingSelector}`, () => {
'ul',
'.branch',
'section',
'.tree',
'div',
'body',
'document',
].forEach((expectedMatchingSelector) => {
test(`should return matched element when selector targets parent element matching selector ${expectedMatchingSelector}`, () => {
const element = sandbox.querySelector('.leaf'); const element = sandbox.querySelector('.leaf');
const expected = sandbox.querySelector(expectedMatchingSelector); const expected = sandbox.querySelector(expectedMatchingSelector);

View File

@ -1,5 +1,3 @@
import closest from './closest'; import closest from './closest';
export { export {closest};
closest,
};