@ -45,6 +45,8 @@
tapEvt ,
tapEvt ,
touchEvt ,
touchEvt ,
moved ,
/** @const */
/** @const */
RSPACE = /\s+/g ,
RSPACE = /\s+/g ,
@ -176,7 +178,10 @@
dropBubble : false ,
dropBubble : false ,
dragoverBubble : false ,
dragoverBubble : false ,
dataIdAttr : 'data-id' ,
dataIdAttr : 'data-id' ,
delay : 0
delay : 0 ,
forceFallback : false ,
fallbackClass : 'sortable-fallback' ,
fallbackOnBody : false
} ;
} ;
@ -323,8 +328,12 @@
_on ( ownerDocument , 'touchcancel' , _this . _onDrop ) ;
_on ( ownerDocument , 'touchcancel' , _this . _onDrop ) ;
if ( options . delay ) {
if ( options . delay ) {
// If the user moves the pointer before the delay has been reached:
// If the user moves the pointer or let go the click or touch
// before the delay has been reached:
// disable the delayed drag
// disable the delayed drag
_on ( ownerDocument , 'mouseup' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'touchend' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'touchcancel' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'mousemove' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'mousemove' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'touchmove' , _this . _disableDelayedDrag ) ;
_on ( ownerDocument , 'touchmove' , _this . _disableDelayedDrag ) ;
@ -339,7 +348,9 @@
var ownerDocument = this . el . ownerDocument ;
var ownerDocument = this . el . ownerDocument ;
clearTimeout ( this . _dragStartTimer ) ;
clearTimeout ( this . _dragStartTimer ) ;
_off ( ownerDocument , 'mouseup' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'touchend' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'touchcancel' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'mousemove' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'mousemove' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'touchmove' , this . _disableDelayedDrag ) ;
_off ( ownerDocument , 'touchmove' , this . _disableDelayedDrag ) ;
} ,
} ,
@ -355,7 +366,7 @@
this . _onDragStart ( tapEvt , 'touch' ) ;
this . _onDragStart ( tapEvt , 'touch' ) ;
}
}
else if ( ! supportDraggable ) {
else if ( ! supportDraggable || this . options . forceFallback ) {
this . _onDragStart ( tapEvt , true ) ;
this . _onDragStart ( tapEvt , true ) ;
}
}
else {
else {
@ -422,6 +433,12 @@
_onTouchMove : function ( /**TouchEvent*/ evt ) {
_onTouchMove : function ( /**TouchEvent*/ evt ) {
if ( tapEvt ) {
if ( tapEvt ) {
// only set the status to dragging, when we are actually dragging
if ( ! Sortable . active ) {
this . _dragStarted ( ) ;
}
// as well as creating the ghost element on the document body
this . _appendGhost ( ) ;
var touch = evt . touches ? evt . touches [ 0 ] : evt ,
var touch = evt . touches ? evt . touches [ 0 ] : evt ,
dx = touch . clientX - tapEvt . clientX ,
dx = touch . clientX - tapEvt . clientX ,
dy = touch . clientY - tapEvt . clientY ,
dy = touch . clientY - tapEvt . clientY ,
@ -429,6 +446,8 @@
touchEvt = touch ;
touchEvt = touch ;
moved = true ;
_css ( ghostEl , 'webkitTransform' , translate3d ) ;
_css ( ghostEl , 'webkitTransform' , translate3d ) ;
_css ( ghostEl , 'mozTransform' , translate3d ) ;
_css ( ghostEl , 'mozTransform' , translate3d ) ;
_css ( ghostEl , 'msTransform' , translate3d ) ;
_css ( ghostEl , 'msTransform' , translate3d ) ;
@ -438,26 +457,17 @@
}
}
} ,
} ,
_appendGhost : function ( ) {
_onDragStart : function ( /**Event*/ evt , /**boolean*/ useFallback ) {
if ( ! ghostEl ) {
var dataTransfer = evt . dataTransfer ,
options = this . options ;
this . _offUpEvents ( ) ;
if ( activeGroup . pull == 'clone' ) {
cloneEl = dragEl . cloneNode ( true ) ;
_css ( cloneEl , 'display' , 'none' ) ;
rootEl . insertBefore ( cloneEl , dragEl ) ;
}
if ( useFallback ) {
var rect = dragEl . getBoundingClientRect ( ) ,
var rect = dragEl . getBoundingClientRect ( ) ,
css = _css ( dragEl ) ,
css = _css ( dragEl ) ,
ghostRect ;
ghostRect ;
ghostEl = dragEl . cloneNode ( true ) ;
ghostEl = dragEl . cloneNode ( true ) ;
_toggleClass ( ghostEl , this . options . ghostClass , false ) ;
_toggleClass ( ghostEl , this . options . fallbackClass , true ) ;
_css ( ghostEl , 'top' , rect . top - parseInt ( css . marginTop , 10 ) ) ;
_css ( ghostEl , 'top' , rect . top - parseInt ( css . marginTop , 10 ) ) ;
_css ( ghostEl , 'left' , rect . left - parseInt ( css . marginLeft , 10 ) ) ;
_css ( ghostEl , 'left' , rect . left - parseInt ( css . marginLeft , 10 ) ) ;
_css ( ghostEl , 'width' , rect . width ) ;
_css ( ghostEl , 'width' , rect . width ) ;
@ -466,12 +476,28 @@
_css ( ghostEl , 'position' , 'fixed' ) ;
_css ( ghostEl , 'position' , 'fixed' ) ;
_css ( ghostEl , 'zIndex' , '100000' ) ;
_css ( ghostEl , 'zIndex' , '100000' ) ;
rootEl . appendChild ( ghostEl ) ;
this . options . fallbackOnBody && document . body . appendChild ( ghostEl ) || rootEl . appendChild ( ghostEl ) ;
// Fixing dimensions.
// Fixing dimensions.
ghostRect = ghostEl . getBoundingClientRect ( ) ;
ghostRect = ghostEl . getBoundingClientRect ( ) ;
_css ( ghostEl , 'width' , rect . width * 2 - ghostRect . width ) ;
_css ( ghostEl , 'width' , rect . width * 2 - ghostRect . width ) ;
_css ( ghostEl , 'height' , rect . height * 2 - ghostRect . height ) ;
_css ( ghostEl , 'height' , rect . height * 2 - ghostRect . height ) ;
}
} ,
_onDragStart : function ( /**Event*/ evt , /**boolean*/ useFallback ) {
var dataTransfer = evt . dataTransfer ,
options = this . options ;
this . _offUpEvents ( ) ;
if ( activeGroup . pull == 'clone' ) {
cloneEl = dragEl . cloneNode ( true ) ;
_css ( cloneEl , 'display' , 'none' ) ;
rootEl . insertBefore ( cloneEl , dragEl ) ;
}
if ( useFallback ) {
if ( useFallback === 'touch' ) {
if ( useFallback === 'touch' ) {
// Bind touch events
// Bind touch events
@ -493,9 +519,9 @@
}
}
_on ( document , 'drop' , this ) ;
_on ( document , 'drop' , this ) ;
setTimeout ( this . _dragStarted , 0 ) ;
}
}
setTimeout ( this . _dragStarted , 0 ) ;
} ,
} ,
_onDragOver : function ( /**Event*/ evt ) {
_onDragOver : function ( /**Event*/ evt ) {
@ -665,9 +691,10 @@
this . _offUpEvents ( ) ;
this . _offUpEvents ( ) ;
if ( evt ) {
if ( evt ) {
evt . preventDefault ( ) ;
if ( moved ) {
! options . dropBubble && evt . stopPropagation ( ) ;
evt . preventDefault ( ) ;
! options . dropBubble && evt . stopPropagation ( ) ;
}
ghostEl && ghostEl . parentNode . removeChild ( ghostEl ) ;
ghostEl && ghostEl . parentNode . removeChild ( ghostEl ) ;
if ( dragEl ) {
if ( dragEl ) {
@ -725,6 +752,8 @@
tapEvt =
tapEvt =
touchEvt =
touchEvt =
moved =
lastEl =
lastEl =
lastCSS =
lastCSS =
@ -996,17 +1025,19 @@
onMoveFn = sortable . options . onMove ,
onMoveFn = sortable . options . onMove ,
retVal ;
retVal ;
if ( onMoveFn ) {
evt = document . createEvent ( 'Event' ) ;
evt = document . createEvent ( 'Event' ) ;
evt . initEvent ( 'move' , true , true ) ;
evt . initEvent ( 'move' , true , true ) ;
evt . to = toEl ;
evt . to = toEl ;
evt . from = fromEl ;
evt . from = fromEl ;
evt . dragged = dragEl ;
evt . dragged = dragEl ;
evt . draggedRect = dragRect ;
evt . draggedRect = dragRect ;
evt . related = targetEl || toEl ;
evt . related = targetEl || toEl ;
evt . relatedRect = targetRect || toEl . getBoundingClientRect ( ) ;
evt . relatedRect = targetRect || toEl . getBoundingClientRect ( ) ;
fromEl . dispatchEvent ( evt ) ;
if ( onMoveFn ) {
retVal = onMoveFn . call ( sortable , evt ) ;
retVal = onMoveFn . call ( sortable , evt ) ;
}
}