@@ -2,6 +2,7 @@ import { DDDraggable } from '../src/dd-draggable';
22import { DDDroppable } from '../src/dd-droppable' ;
33import { DDResizable } from '../src/dd-resizable' ;
44import { DDElement } from '../src/dd-element' ;
5+ import { DDManager } from '../src/dd-manager' ;
56import { GridItemHTMLElement } from '../src/types' ;
67
78describe ( 'DD Integration Tests' , ( ) => {
@@ -229,6 +230,141 @@ describe('DD Integration Tests', () => {
229230 } ) ;
230231 } ) ;
231232
233+ describe ( 'drag gesture' , ( ) => {
234+ /** dispatch a real mouse event - the drag code listens on document for move/up */
235+ const mouse = ( type : string , x : number , y : number , target : EventTarget = document ) => {
236+ target . dispatchEvent ( new MouseEvent ( type , { bubbles : true , cancelable : true , button : 0 , clientX : x , clientY : y } ) ) ;
237+ } ;
238+
239+ it ( 'should fire dragstart/drag/dragstop as the mouse moves and releases' , ( ) => {
240+ const start = vi . fn ( ) , drag = vi . fn ( ) , stop = vi . fn ( ) ;
241+ const draggable = new DDDraggable ( element , { start, drag, stop} ) ;
242+
243+ mouse ( 'mousedown' , 10 , 10 , element ) ;
244+ expect ( start ) . not . toHaveBeenCalled ( ) ; // a click alone isn't a drag
245+
246+ mouse ( 'mousemove' , 30 , 30 ) ;
247+ expect ( start ) . toHaveBeenCalled ( ) ;
248+ expect ( DDManager . dragElement ) . toBe ( draggable ) ;
249+
250+ mouse ( 'mousemove' , 50 , 60 ) ;
251+ expect ( drag ) . toHaveBeenCalled ( ) ;
252+
253+ mouse ( 'mouseup' , 50 , 60 ) ;
254+ expect ( stop ) . toHaveBeenCalled ( ) ;
255+ expect ( DDManager . dragElement ) . toBeUndefined ( ) ;
256+
257+ draggable . destroy ( ) ;
258+ } ) ;
259+
260+ it ( 'should not start dragging for a tiny mouse move (#3px threshold)' , ( ) => {
261+ const start = vi . fn ( ) ;
262+ const draggable = new DDDraggable ( element , { start} ) ;
263+
264+ mouse ( 'mousedown' , 10 , 10 , element ) ;
265+ mouse ( 'mousemove' , 11 , 11 ) ;
266+ expect ( start ) . not . toHaveBeenCalled ( ) ;
267+ expect ( DDManager . dragElement ) . toBeUndefined ( ) ;
268+
269+ mouse ( 'mouseup' , 11 , 11 ) ;
270+ draggable . destroy ( ) ;
271+ } ) ;
272+
273+ it ( 'should ignore a non left click' , ( ) => {
274+ const start = vi . fn ( ) ;
275+ const draggable = new DDDraggable ( element , { start} ) ;
276+
277+ element . dispatchEvent ( new MouseEvent ( 'mousedown' , { bubbles : true , button : 2 , clientX : 10 , clientY : 10 } ) ) ;
278+ mouse ( 'mousemove' , 40 , 40 ) ;
279+
280+ expect ( start ) . not . toHaveBeenCalled ( ) ;
281+ draggable . destroy ( ) ;
282+ } ) ;
283+
284+ it ( 'should cancel the drag on Escape' , ( ) => {
285+ const stop = vi . fn ( ) ;
286+ const draggable = new DDDraggable ( element , { stop} ) ;
287+
288+ mouse ( 'mousedown' , 10 , 10 , element ) ;
289+ mouse ( 'mousemove' , 40 , 40 ) ;
290+ expect ( DDManager . dragElement ) . toBe ( draggable ) ;
291+
292+ document . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Escape' , bubbles : true } ) ) ;
293+
294+ expect ( stop ) . toHaveBeenCalled ( ) ;
295+ expect ( DDManager . dragElement ) . toBeUndefined ( ) ;
296+ draggable . destroy ( ) ;
297+ } ) ;
298+
299+ it ( 'should only let one item handle a drag at a time' , ( ) => {
300+ const other = document . createElement ( 'div' ) ;
301+ document . body . appendChild ( other ) ;
302+ const start1 = vi . fn ( ) , start2 = vi . fn ( ) ;
303+ const d1 = new DDDraggable ( element , { start : start1 } ) ;
304+ const d2 = new DDDraggable ( other , { start : start2 } ) ;
305+
306+ mouse ( 'mousedown' , 10 , 10 , element ) ;
307+ mouse ( 'mousedown' , 10 , 10 , other ) ; // second one must be ignored
308+ mouse ( 'mousemove' , 40 , 40 ) ;
309+
310+ expect ( start1 ) . toHaveBeenCalled ( ) ;
311+ expect ( start2 ) . not . toHaveBeenCalled ( ) ;
312+
313+ mouse ( 'mouseup' , 40 , 40 ) ;
314+ d1 . destroy ( ) ; d2 . destroy ( ) ; other . remove ( ) ;
315+ } ) ;
316+ } ) ;
317+
318+ describe ( 'resize gesture' , ( ) => {
319+ const mouse = ( type : string , x : number , y : number , target : EventTarget = document ) => {
320+ target . dispatchEvent ( new MouseEvent ( type , { bubbles : true , cancelable : true , button : 0 , clientX : x , clientY : y } ) ) ;
321+ } ;
322+
323+ it ( 'should fire resizestart/resize/resizestop when dragging a handle' , ( ) => {
324+ const start = vi . fn ( ) , resize = vi . fn ( ) , stop = vi . fn ( ) ;
325+ const resizable = new DDResizable ( element , { handles : 'se' , start, resize, stop} ) ;
326+ const handle = element . querySelector ( '.ui-resizable-se' ) ! ;
327+
328+ mouse ( 'mousedown' , 100 , 100 , handle ) ;
329+ expect ( start ) . not . toHaveBeenCalled ( ) ;
330+
331+ mouse ( 'mousemove' , 140 , 150 ) ;
332+ expect ( start ) . toHaveBeenCalled ( ) ;
333+ expect ( resize ) . toHaveBeenCalled ( ) ;
334+
335+ mouse ( 'mouseup' , 140 , 150 ) ;
336+ expect ( stop ) . toHaveBeenCalled ( ) ;
337+
338+ resizable . destroy ( ) ;
339+ } ) ;
340+
341+ it ( 'should not resize for a tiny move' , ( ) => {
342+ const start = vi . fn ( ) ;
343+ const resizable = new DDResizable ( element , { handles : 'se' , start} ) ;
344+ const handle = element . querySelector ( '.ui-resizable-se' ) ! ;
345+
346+ mouse ( 'mousedown' , 100 , 100 , handle ) ;
347+ mouse ( 'mousemove' , 101 , 101 ) ;
348+ expect ( start ) . not . toHaveBeenCalled ( ) ;
349+
350+ mouse ( 'mouseup' , 101 , 101 ) ;
351+ resizable . destroy ( ) ;
352+ } ) ;
353+
354+ it ( 'should cancel the resize on Escape' , ( ) => {
355+ const stop = vi . fn ( ) ;
356+ const resizable = new DDResizable ( element , { handles : 'se' , stop} ) ;
357+ const handle = element . querySelector ( '.ui-resizable-se' ) ! ;
358+
359+ mouse ( 'mousedown' , 100 , 100 , handle ) ;
360+ mouse ( 'mousemove' , 140 , 150 ) ;
361+ document . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Escape' , bubbles : true } ) ) ;
362+
363+ expect ( stop ) . toHaveBeenCalled ( ) ;
364+ resizable . destroy ( ) ;
365+ } ) ;
366+ } ) ;
367+
232368 describe ( 'Event handling' , ( ) => {
233369 it ( 'should support event listeners on DDElement' , ( ) => {
234370 const ddElement = DDElement . init ( element ) ;
0 commit comments