2008-06-04 02:34:33 +00:00
/ *
2008-09-04 22:03:30 +00:00
* jQuery UI Draggable @ VERSION
2008-06-04 02:34:33 +00:00
*
* Copyright ( c ) 2008 Paul Bakaus
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
2008-09-19 14:20:14 +00:00
*
2008-06-04 02:34:33 +00:00
* http : //docs.jquery.com/UI/Draggables
*
* Depends :
* ui . core . js
* /
2008-06-05 12:14:12 +00:00
( function ( $ ) {
2008-06-04 02:34:33 +00:00
2008-07-07 07:39:12 +00:00
$ . widget ( "ui.draggable" , $ . extend ( { } , $ . ui . mouse , {
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
getHandle : function ( e ) {
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
var handle = ! this . options . handle || ! $ ( this . options . handle , this . element ) . length ? true : false ;
$ ( this . options . handle , this . element )
. find ( "*" )
. andSelf ( )
. each ( function ( ) {
if ( this == e . target ) handle = true ;
} ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
return handle ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
} ,
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
createHelper : function ( ) {
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
var o = this . options ;
var helper = $ . isFunction ( o . helper ) ? $ ( o . helper . apply ( this . element [ 0 ] , [ e ] ) ) : ( o . helper == 'clone' ? this . element . clone ( ) : this . element ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
if ( ! helper . parents ( 'body' ) . length )
helper . appendTo ( ( o . appendTo == 'parent' ? this . element [ 0 ] . parentNode : o . appendTo ) ) ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
if ( helper [ 0 ] != this . element [ 0 ] && ! ( /(fixed|absolute)/ ) . test ( helper . css ( "position" ) ) )
helper . css ( "position" , "absolute" ) ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
return helper ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
} ,
2008-09-19 14:20:14 +00:00
2008-08-17 02:15:55 +00:00
_init : function ( ) {
2008-09-19 14:20:14 +00:00
2008-07-17 15:04:42 +00:00
if ( this . options . helper == 'original' && ! ( /^(?:r|a|f)/ ) . test ( this . element . css ( "position" ) ) )
this . element [ 0 ] . style . position = 'relative' ;
2008-09-19 14:20:14 +00:00
2008-07-28 21:06:04 +00:00
( this . options . cssNamespace && this . element . addClass ( this . options . cssNamespace + "-draggable" ) ) ;
2008-07-17 15:04:42 +00:00
( this . options . disabled && this . element . addClass ( 'ui-draggable-disabled' ) ) ;
2008-09-19 14:20:14 +00:00
2008-08-17 08:15:49 +00:00
this . _mouseInit ( ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-09-20 02:43:18 +00:00
2008-09-16 13:02:21 +00:00
_mouseCapture : function ( e ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var o = this . options ;
2008-09-19 14:20:14 +00:00
2008-07-17 15:04:42 +00:00
if ( this . helper || o . disabled || $ ( e . target ) . is ( '.ui-resizable-handle' ) )
return false ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
//Quit if we're not on a valid handle
2008-09-16 13:02:21 +00:00
this . handle = this . getHandle ( e ) ;
if ( ! this . handle )
2008-09-15 20:26:42 +00:00
return false ;
2008-09-19 14:20:14 +00:00
2008-09-16 13:02:21 +00:00
return true ;
2008-09-20 02:43:18 +00:00
2008-09-16 13:02:21 +00:00
} ,
2008-09-20 02:43:18 +00:00
2008-09-16 13:02:21 +00:00
_mouseStart : function ( e ) {
2008-09-19 14:20:14 +00:00
2008-09-16 13:02:21 +00:00
var o = this . options ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Create and append the visible helper
this . helper = this . createHelper ( ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//If ddmanager is used for droppables, set the global draggable
2008-07-17 15:04:42 +00:00
if ( $ . ui . ddmanager )
$ . ui . ddmanager . current = this ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
/ *
* - Position generation -
* This block generates everything position related - it ' s the core of draggables .
* /
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
this . margins = { //Cache the margins
left : ( parseInt ( this . element . css ( "marginLeft" ) , 10 ) || 0 ) ,
top : ( parseInt ( this . element . css ( "marginTop" ) , 10 ) || 0 )
2008-09-19 14:20:14 +00:00
} ;
2008-06-04 02:34:33 +00:00
this . cssPosition = this . helper . css ( "position" ) ; //Store the helper's css position
this . offset = this . element . offset ( ) ; //The element's absolute position on the page
this . offset = { //Substract the margins from the element's absolute offset
top : this . offset . top - this . margins . top ,
left : this . offset . left - this . margins . left
} ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
this . offset . click = { //Where the click happened, relative to the element
left : e . pageX - this . offset . left ,
top : e . pageY - this . offset . top
} ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
//Calling this method cached the next parents that have scrollTop / scrollLeft attached
this . cacheScrollParents ( ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
this . offsetParent = this . helper . offsetParent ( ) ; var po = this . offsetParent . offset ( ) ; //Get the offsetParent and cache its position
2008-06-07 22:56:56 +00:00
if ( this . offsetParent [ 0 ] == document . body && $ . browser . mozilla ) po = { top : 0 , left : 0 } ; //Ugly FF3 fix
2008-06-04 02:34:33 +00:00
this . offset . parent = { //Store its position plus border
top : po . top + ( parseInt ( this . offsetParent . css ( "borderTopWidth" ) , 10 ) || 0 ) ,
left : po . left + ( parseInt ( this . offsetParent . css ( "borderLeftWidth" ) , 10 ) || 0 )
} ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
if ( this . cssPosition == "relative" ) {
var p = this . element . position ( ) ;
this . offset . relative = {
top : p . top - ( parseInt ( this . helper . css ( "top" ) , 10 ) || 0 ) + this . scrollTopParent . scrollTop ( ) ,
left : p . left - ( parseInt ( this . helper . css ( "left" ) , 10 ) || 0 ) + this . scrollLeftParent . scrollLeft ( )
} ;
} else {
this . offset . relative = { top : 0 , left : 0 } ;
}
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Generate the original position
this . originalPosition = this . _generatePosition ( e ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Cache the helper size
this . cacheHelperProportions ( ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
if ( o . cursorAt )
this . adjustOffsetFromHelper ( o . cursorAt ) ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
//Cache later used stuff
$ . extend ( this , {
PAGEY _INCLUDES _SCROLL : ( this . cssPosition == "absolute" && ( ! this . scrollTopParent [ 0 ] . tagName || ( /(html|body)/i ) . test ( this . scrollTopParent [ 0 ] . tagName ) ) ) ,
PAGEX _INCLUDES _SCROLL : ( this . cssPosition == "absolute" && ( ! this . scrollLeftParent [ 0 ] . tagName || ( /(html|body)/i ) . test ( this . scrollLeftParent [ 0 ] . tagName ) ) ) ,
OFFSET _PARENT _NOT _SCROLL _PARENT _Y : this . scrollTopParent [ 0 ] != this . offsetParent [ 0 ] && ! ( this . scrollTopParent [ 0 ] == document && ( /(body|html)/i ) . test ( this . offsetParent [ 0 ] . tagName ) ) ,
OFFSET _PARENT _NOT _SCROLL _PARENT _X : this . scrollLeftParent [ 0 ] != this . offsetParent [ 0 ] && ! ( this . scrollLeftParent [ 0 ] == document && ( /(body|html)/i ) . test ( this . offsetParent [ 0 ] . tagName ) )
} ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
if ( o . containment )
this . setContainment ( ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//Call plugins and callbacks
2008-08-17 02:15:55 +00:00
this . _propagate ( "start" , e ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Recache the helper size
this . cacheHelperProportions ( ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
//Prepare the droppable offsets
if ( $ . ui . ddmanager && ! o . dropBehaviour )
$ . ui . ddmanager . prepareOffsets ( this , e ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
this . helper . addClass ( "ui-draggable-dragging" ) ;
2008-08-17 08:15:49 +00:00
this . _mouseDrag ( e ) ; //Execute the drag once - this causes the helper not to be visible before getting its correct position
2008-06-04 02:34:33 +00:00
return true ;
} ,
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
cacheScrollParents : function ( ) {
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
this . scrollTopParent = function ( el ) {
do { if ( /auto|scroll/ . test ( el . css ( 'overflow' ) ) || ( /auto|scroll/ ) . test ( el . css ( 'overflow-y' ) ) ) return el ; el = el . parent ( ) ; } while ( el [ 0 ] . parentNode ) ;
return $ ( document ) ;
} ( this . helper ) ;
this . scrollLeftParent = function ( el ) {
do { if ( /auto|scroll/ . test ( el . css ( 'overflow' ) ) || ( /auto|scroll/ ) . test ( el . css ( 'overflow-x' ) ) ) return el ; el = el . parent ( ) ; } while ( el [ 0 ] . parentNode ) ;
return $ ( document ) ;
} ( this . helper ) ;
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
} ,
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
adjustOffsetFromHelper : function ( obj ) {
if ( obj . left != undefined ) this . offset . click . left = obj . left + this . margins . left ;
if ( obj . right != undefined ) this . offset . click . left = this . helperProportions . width - obj . right + this . margins . left ;
if ( obj . top != undefined ) this . offset . click . top = obj . top + this . margins . top ;
if ( obj . bottom != undefined ) this . offset . click . top = this . helperProportions . height - obj . bottom + this . margins . top ;
} ,
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
cacheHelperProportions : function ( ) {
this . helperProportions = {
width : this . helper . outerWidth ( ) ,
height : this . helper . outerHeight ( )
} ;
} ,
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
setContainment : function ( ) {
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
var o = this . options ;
if ( o . containment == 'parent' ) o . containment = this . helper [ 0 ] . parentNode ;
if ( o . containment == 'document' || o . containment == 'window' ) this . containment = [
0 - this . offset . relative . left - this . offset . parent . left ,
0 - this . offset . relative . top - this . offset . parent . top ,
$ ( o . containment == 'document' ? document : window ) . width ( ) - this . offset . relative . left - this . offset . parent . left - this . helperProportions . width - this . margins . left - ( parseInt ( this . element . css ( "marginRight" ) , 10 ) || 0 ) ,
( $ ( o . containment == 'document' ? document : window ) . height ( ) || document . body . parentNode . scrollHeight ) - this . offset . relative . top - this . offset . parent . top - this . helperProportions . height - this . margins . top - ( parseInt ( this . element . css ( "marginBottom" ) , 10 ) || 0 )
] ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
if ( ! ( /^(document|window|parent)$/ ) . test ( o . containment ) ) {
var ce = $ ( o . containment ) [ 0 ] ;
var co = $ ( o . containment ) . offset ( ) ;
2008-09-16 10:38:12 +00:00
var over = ( $ ( ce ) . css ( "overflow" ) != 'hidden' ) ;
2008-09-19 14:20:14 +00:00
2008-09-15 20:26:42 +00:00
this . containment = [
co . left + ( parseInt ( $ ( ce ) . css ( "borderLeftWidth" ) , 10 ) || 0 ) - this . offset . relative . left - this . offset . parent . left ,
co . top + ( parseInt ( $ ( ce ) . css ( "borderTopWidth" ) , 10 ) || 0 ) - this . offset . relative . top - this . offset . parent . top ,
2008-09-16 10:38:12 +00:00
co . left + ( over ? Math . max ( ce . scrollWidth , ce . offsetWidth ) : ce . offsetWidth ) - ( parseInt ( $ ( ce ) . css ( "borderLeftWidth" ) , 10 ) || 0 ) - this . offset . relative . left - this . offset . parent . left - this . helperProportions . width - this . margins . left - ( parseInt ( this . element . css ( "marginRight" ) , 10 ) || 0 ) ,
co . top + ( over ? Math . max ( ce . scrollHeight , ce . offsetHeight ) : ce . offsetHeight ) - ( parseInt ( $ ( ce ) . css ( "borderTopWidth" ) , 10 ) || 0 ) - this . offset . relative . top - this . offset . parent . top - this . helperProportions . height - this . margins . top - ( parseInt ( this . element . css ( "marginBottom" ) , 10 ) || 0 )
2008-09-15 20:26:42 +00:00
] ;
}
2008-09-20 02:43:18 +00:00
2008-09-15 20:26:42 +00:00
} ,
2008-09-19 14:20:14 +00:00
2008-08-17 02:15:55 +00:00
_convertPositionTo : function ( d , pos ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( ! pos ) pos = this . position ;
var mod = d == "absolute" ? 1 : - 1 ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
return {
top : (
pos . top // the calculated relative position
+ this . offset . relative . top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ this . offset . parent . top * mod // The offsetParent's offset without borders (offset + border)
2008-09-15 20:26:42 +00:00
- ( this . cssPosition == "fixed" || this . PAGEY _INCLUDES _SCROLL || this . OFFSET _PARENT _NOT _SCROLL _PARENT _Y ? 0 : this . scrollTopParent . scrollTop ( ) ) * mod // The offsetParent's scroll position, not if the element is fixed
2008-06-24 13:32:17 +00:00
+ ( this . cssPosition == "fixed" ? $ ( document ) . scrollTop ( ) : 0 ) * mod
2008-06-04 02:34:33 +00:00
+ this . margins . top * mod //Add the margin (you don't want the margin counting in intersection methods)
) ,
left : (
pos . left // the calculated relative position
+ this . offset . relative . left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ this . offset . parent . left * mod // The offsetParent's offset without borders (offset + border)
2008-09-15 20:26:42 +00:00
- ( this . cssPosition == "fixed" || this . PAGEX _INCLUDES _SCROLL || this . OFFSET _PARENT _NOT _SCROLL _PARENT _X ? 0 : this . scrollLeftParent . scrollLeft ( ) ) * mod // The offsetParent's scroll position, not if the element is fixed
2008-06-24 13:32:17 +00:00
+ ( this . cssPosition == "fixed" ? $ ( document ) . scrollLeft ( ) : 0 ) * mod
2008-06-04 02:34:33 +00:00
+ this . margins . left * mod //Add the margin (you don't want the margin counting in intersection methods)
)
} ;
} ,
2008-08-17 02:15:55 +00:00
_generatePosition : function ( e ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var o = this . options ;
var position = {
top : (
e . pageY // The absolute mouse position
- this . offset . click . top // Click offset (relative to the element)
- this . offset . relative . top // Only for relative positioned nodes: Relative offset from element to offset parent
- this . offset . parent . top // The offsetParent's offset without borders (offset + border)
2008-09-15 20:26:42 +00:00
+ ( this . cssPosition == "fixed" || this . PAGEY _INCLUDES _SCROLL || this . OFFSET _PARENT _NOT _SCROLL _PARENT _Y ? 0 : this . scrollTopParent . scrollTop ( ) ) // The offsetParent's scroll position, not if the element is fixed
2008-06-24 13:32:17 +00:00
- ( this . cssPosition == "fixed" ? $ ( document ) . scrollTop ( ) : 0 )
2008-06-04 02:34:33 +00:00
) ,
left : (
e . pageX // The absolute mouse position
- this . offset . click . left // Click offset (relative to the element)
- this . offset . relative . left // Only for relative positioned nodes: Relative offset from element to offset parent
- this . offset . parent . left // The offsetParent's offset without borders (offset + border)
2008-09-15 20:26:42 +00:00
+ ( this . cssPosition == "fixed" || this . PAGEX _INCLUDES _SCROLL || this . OFFSET _PARENT _NOT _SCROLL _PARENT _X ? 0 : this . scrollLeftParent . scrollLeft ( ) ) // The offsetParent's scroll position, not if the element is fixed
2008-06-24 13:32:17 +00:00
- ( this . cssPosition == "fixed" ? $ ( document ) . scrollLeft ( ) : 0 )
2008-06-04 02:34:33 +00:00
)
} ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( ! this . originalPosition ) return position ; //If we are not dragging yet, we won't check for options
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
/ *
* - Position constraining -
* Constrain the position to a mix of grid , containment .
* /
if ( this . containment ) {
if ( position . left < this . containment [ 0 ] ) position . left = this . containment [ 0 ] ;
if ( position . top < this . containment [ 1 ] ) position . top = this . containment [ 1 ] ;
if ( position . left > this . containment [ 2 ] ) position . left = this . containment [ 2 ] ;
if ( position . top > this . containment [ 3 ] ) position . top = this . containment [ 3 ] ;
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
if ( o . grid ) {
var top = this . originalPosition . top + Math . round ( ( position . top - this . originalPosition . top ) / o . grid [ 1 ] ) * o . grid [ 1 ] ;
position . top = this . containment ? ( ! ( top < this . containment [ 1 ] || top > this . containment [ 3 ] ) ? top : ( ! ( top < this . containment [ 1 ] ) ? top - o . grid [ 1 ] : top + o . grid [ 1 ] ) ) : top ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var left = this . originalPosition . left + Math . round ( ( position . left - this . originalPosition . left ) / o . grid [ 0 ] ) * o . grid [ 0 ] ;
position . left = this . containment ? ( ! ( left < this . containment [ 0 ] || left > this . containment [ 2 ] ) ? left : ( ! ( left < this . containment [ 0 ] ) ? left - o . grid [ 0 ] : left + o . grid [ 0 ] ) ) : left ;
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
return position ;
} ,
2008-08-17 08:15:49 +00:00
_mouseDrag : function ( e ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//Compute the helpers position
2008-08-17 02:15:55 +00:00
this . position = this . _generatePosition ( e ) ;
this . positionAbs = this . _convertPositionTo ( "absolute" ) ;
2008-09-19 14:20:14 +00:00
//Call plugins and callbacks and use the resulting position if something is returned
2008-08-17 02:15:55 +00:00
this . position = this . _propagate ( "drag" , e ) || this . position ;
2008-09-20 02:43:18 +00:00
2008-06-07 06:10:52 +00:00
if ( ! this . options . axis || this . options . axis != "y" ) this . helper [ 0 ] . style . left = this . position . left + 'px' ;
if ( ! this . options . axis || this . options . axis != "x" ) this . helper [ 0 ] . style . top = this . position . top + 'px' ;
2008-06-04 02:34:33 +00:00
if ( $ . ui . ddmanager ) $ . ui . ddmanager . drag ( this , e ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
return false ;
} ,
2008-08-17 08:15:49 +00:00
_mouseStop : function ( e ) {
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//If we are using droppables, inform the manager about the drop
2008-07-03 14:59:10 +00:00
var dropped = false ;
2008-06-04 02:34:33 +00:00
if ( $ . ui . ddmanager && ! this . options . dropBehaviour )
2008-09-19 14:20:14 +00:00
var dropped = $ . ui . ddmanager . drop ( this , e ) ;
2008-09-18 09:51:50 +00:00
if ( ( this . options . revert == "invalid" && ! dropped ) || ( this . options . revert == "valid" && dropped ) || this . options . revert === true || ( $ . isFunction ( this . options . revert ) && this . options . revert . call ( this . element , dropped ) ) ) {
2008-06-04 02:34:33 +00:00
var self = this ;
2008-10-08 10:21:28 +00:00
$ ( this . helper ) . animate ( this . originalPosition , parseInt ( this . options . revertDuration , 10 ) , function ( ) {
2008-08-17 02:15:55 +00:00
self . _propagate ( "stop" , e ) ;
self . _clear ( ) ;
2008-06-04 02:34:33 +00:00
} ) ;
} else {
2008-08-17 02:15:55 +00:00
this . _propagate ( "stop" , e ) ;
this . _clear ( ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
return false ;
} ,
2008-08-17 02:15:55 +00:00
_clear : function ( ) {
2008-06-04 02:34:33 +00:00
this . helper . removeClass ( "ui-draggable-dragging" ) ;
if ( this . options . helper != 'original' && ! this . cancelHelperRemoval ) this . helper . remove ( ) ;
2008-06-09 06:53:37 +00:00
//if($.ui.ddmanager) $.ui.ddmanager.current = null;
2008-06-04 02:34:33 +00:00
this . helper = null ;
this . cancelHelperRemoval = false ;
} ,
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// From now on bulk stuff - mainly helpers
plugins : { } ,
uiHash : function ( e ) {
return {
helper : this . helper ,
position : this . position ,
absolutePosition : this . positionAbs ,
2008-09-19 14:20:14 +00:00
options : this . options
2008-06-04 02:34:33 +00:00
} ;
} ,
2008-08-17 02:15:55 +00:00
_propagate : function ( n , e ) {
2008-06-04 02:34:33 +00:00
$ . ui . plugin . call ( this , n , [ e , this . uiHash ( ) ] ) ;
2008-08-17 02:15:55 +00:00
if ( n == "drag" ) this . positionAbs = this . _convertPositionTo ( "absolute" ) ; //The absolute position has to be recalculated after plugins
2008-06-04 02:34:33 +00:00
return this . element . triggerHandler ( n == "drag" ? n : "drag" + n , [ e , this . uiHash ( ) ] , this . options [ n ] ) ;
} ,
destroy : function ( ) {
if ( ! this . element . data ( 'draggable' ) ) return ;
2008-09-16 10:39:54 +00:00
this . element . removeData ( "draggable" ) . unbind ( ".draggable" ) . removeClass ( 'ui-draggable ui-draggable-dragging ui-draggable-disabled' ) ;
2008-08-17 08:15:49 +00:00
this . _mouseDestroy ( ) ;
2008-06-04 02:34:33 +00:00
}
} ) ) ;
$ . extend ( $ . ui . draggable , {
2008-10-05 16:29:21 +00:00
version : "@VERSION" ,
2008-06-04 02:34:33 +00:00
defaults : {
2008-06-07 06:10:52 +00:00
appendTo : "parent" ,
axis : false ,
2008-06-18 14:29:53 +00:00
cancel : ":input" ,
2008-10-08 10:21:28 +00:00
connectToSortable : false ,
containment : false ,
cursor : "default" ,
2008-06-07 06:10:52 +00:00
delay : 0 ,
2008-06-18 11:10:39 +00:00
distance : 1 ,
2008-10-08 10:21:28 +00:00
grid : false ,
2008-07-28 18:34:01 +00:00
helper : "original" ,
2008-10-08 10:21:28 +00:00
iframeFix : false ,
opacity : 1 ,
refreshPositions : false ,
revert : false ,
revertDuration : 500 ,
2008-07-28 21:06:04 +00:00
scope : "default" ,
2008-10-08 10:21:28 +00:00
scroll : false ,
scrollSensitivity : 20 ,
scrollSpeed : 20 ,
snap : false ,
snapMode : "both" ,
snapTolerance : 20 ,
2008-07-28 21:06:04 +00:00
cssNamespace : "ui"
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . plugin . add ( "draggable" , "cursor" , {
start : function ( e , ui ) {
var t = $ ( 'body' ) ;
if ( t . css ( "cursor" ) ) ui . options . _cursor = t . css ( "cursor" ) ;
t . css ( "cursor" , ui . options . cursor ) ;
} ,
stop : function ( e , ui ) {
if ( ui . options . _cursor ) $ ( 'body' ) . css ( "cursor" , ui . options . _cursor ) ;
}
} ) ;
$ . ui . plugin . add ( "draggable" , "zIndex" , {
start : function ( e , ui ) {
var t = $ ( ui . helper ) ;
if ( t . css ( "zIndex" ) ) ui . options . _zIndex = t . css ( "zIndex" ) ;
t . css ( 'zIndex' , ui . options . zIndex ) ;
} ,
stop : function ( e , ui ) {
if ( ui . options . _zIndex ) $ ( ui . helper ) . css ( 'zIndex' , ui . options . _zIndex ) ;
}
} ) ;
$ . ui . plugin . add ( "draggable" , "opacity" , {
start : function ( e , ui ) {
var t = $ ( ui . helper ) ;
if ( t . css ( "opacity" ) ) ui . options . _opacity = t . css ( "opacity" ) ;
t . css ( 'opacity' , ui . options . opacity ) ;
} ,
stop : function ( e , ui ) {
if ( ui . options . _opacity ) $ ( ui . helper ) . css ( 'opacity' , ui . options . _opacity ) ;
}
} ) ;
$ . ui . plugin . add ( "draggable" , "iframeFix" , {
start : function ( e , ui ) {
2008-09-19 14:20:14 +00:00
$ ( ui . options . iframeFix === true ? "iframe" : ui . options . iframeFix ) . each ( function ( ) {
2008-06-04 02:34:33 +00:00
$ ( '<div class="ui-draggable-iframeFix" style="background: #fff;"></div>' )
. css ( {
width : this . offsetWidth + "px" , height : this . offsetHeight + "px" ,
position : "absolute" , opacity : "0.001" , zIndex : 1000
} )
. css ( $ ( this ) . offset ( ) )
. appendTo ( "body" ) ;
} ) ;
} ,
stop : function ( e , ui ) {
2008-09-19 14:20:14 +00:00
$ ( "div.ui-draggable-iframeFix" ) . each ( function ( ) { this . parentNode . removeChild ( this ) ; } ) ; //Remove frame helpers
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . plugin . add ( "draggable" , "scroll" , {
start : function ( e , ui ) {
var o = ui . options ;
var i = $ ( this ) . data ( "draggable" ) ;
2008-09-19 14:20:14 +00:00
2008-07-29 01:32:46 +00:00
i . overflowY = function ( el ) {
do { if ( /auto|scroll/ . test ( el . css ( 'overflow' ) ) || ( /auto|scroll/ ) . test ( el . css ( 'overflow-y' ) ) ) return el ; el = el . parent ( ) ; } while ( el [ 0 ] . parentNode ) ;
return $ ( document ) ;
} ( this ) ;
i . overflowX = function ( el ) {
do { if ( /auto|scroll/ . test ( el . css ( 'overflow' ) ) || ( /auto|scroll/ ) . test ( el . css ( 'overflow-x' ) ) ) return el ; el = el . parent ( ) ; } while ( el [ 0 ] . parentNode ) ;
return $ ( document ) ;
} ( this ) ;
2008-09-19 14:20:14 +00:00
2008-07-29 01:32:46 +00:00
if ( i . overflowY [ 0 ] != document && i . overflowY [ 0 ] . tagName != 'HTML' ) i . overflowYOffset = i . overflowY . offset ( ) ;
if ( i . overflowX [ 0 ] != document && i . overflowX [ 0 ] . tagName != 'HTML' ) i . overflowXOffset = i . overflowX . offset ( ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ,
drag : function ( e , ui ) {
2008-09-19 14:20:14 +00:00
2008-07-29 01:32:46 +00:00
var o = ui . options , scrolled = false ;
2008-06-04 02:34:33 +00:00
var i = $ ( this ) . data ( "draggable" ) ;
2008-09-19 14:20:14 +00:00
2008-07-29 01:32:46 +00:00
if ( i . overflowY [ 0 ] != document && i . overflowY [ 0 ] . tagName != 'HTML' ) {
if ( ( i . overflowYOffset . top + i . overflowY [ 0 ] . offsetHeight ) - e . pageY < o . scrollSensitivity )
i . overflowY [ 0 ] . scrollTop = scrolled = i . overflowY [ 0 ] . scrollTop + o . scrollSpeed ;
2008-06-04 02:34:33 +00:00
if ( e . pageY - i . overflowYOffset . top < o . scrollSensitivity )
2008-07-29 01:32:46 +00:00
i . overflowY [ 0 ] . scrollTop = scrolled = i . overflowY [ 0 ] . scrollTop - o . scrollSpeed ;
2008-06-04 02:34:33 +00:00
} else {
if ( e . pageY - $ ( document ) . scrollTop ( ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollTop ( $ ( document ) . scrollTop ( ) - o . scrollSpeed ) ;
2008-06-04 02:34:33 +00:00
if ( $ ( window ) . height ( ) - ( e . pageY - $ ( document ) . scrollTop ( ) ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollTop ( $ ( document ) . scrollTop ( ) + o . scrollSpeed ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-07-29 01:32:46 +00:00
if ( i . overflowX [ 0 ] != document && i . overflowX [ 0 ] . tagName != 'HTML' ) {
if ( ( i . overflowXOffset . left + i . overflowX [ 0 ] . offsetWidth ) - e . pageX < o . scrollSensitivity )
i . overflowX [ 0 ] . scrollLeft = scrolled = i . overflowX [ 0 ] . scrollLeft + o . scrollSpeed ;
2008-06-04 02:34:33 +00:00
if ( e . pageX - i . overflowXOffset . left < o . scrollSensitivity )
2008-07-29 01:32:46 +00:00
i . overflowX [ 0 ] . scrollLeft = scrolled = i . overflowX [ 0 ] . scrollLeft - o . scrollSpeed ;
2008-06-04 02:34:33 +00:00
} else {
if ( e . pageX - $ ( document ) . scrollLeft ( ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollLeft ( $ ( document ) . scrollLeft ( ) - o . scrollSpeed ) ;
2008-06-04 02:34:33 +00:00
if ( $ ( window ) . width ( ) - ( e . pageX - $ ( document ) . scrollLeft ( ) ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollLeft ( $ ( document ) . scrollLeft ( ) + o . scrollSpeed ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-07-29 00:54:29 +00:00
if ( scrolled !== false )
$ . ui . ddmanager . prepareOffsets ( i , e ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . plugin . add ( "draggable" , "snap" , {
start : function ( e , ui ) {
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
inst . snapElements = [ ] ;
2008-09-20 02:43:18 +00:00
2008-07-17 16:13:10 +00:00
$ ( ui . options . snap . constructor != String ? ( ui . options . snap . items || ':data(draggable)' ) : ui . options . snap ) . each ( function ( ) {
2008-06-04 02:34:33 +00:00
var $t = $ ( this ) ; var $o = $t . offset ( ) ;
if ( this != inst . element [ 0 ] ) inst . snapElements . push ( {
item : this ,
width : $t . outerWidth ( ) , height : $t . outerHeight ( ) ,
top : $o . top , left : $o . left
} ) ;
} ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ,
drag : function ( e , ui ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
2008-10-08 10:21:28 +00:00
var d = ui . options . snapTolerance ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var x1 = ui . absolutePosition . left , x2 = x1 + inst . helperProportions . width ,
y1 = ui . absolutePosition . top , y2 = y1 + inst . helperProportions . height ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
for ( var i = inst . snapElements . length - 1 ; i >= 0 ; i -- ) {
2008-09-19 14:20:14 +00:00
2008-09-20 03:23:42 +00:00
var l = inst . snapElements [ i ] . left , r = l + inst . snapElements [ i ] . width ,
2008-06-04 02:34:33 +00:00
t = inst . snapElements [ i ] . top , b = t + inst . snapElements [ i ] . height ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//Yes, I know, this is insane ;)
2008-07-17 16:13:10 +00:00
if ( ! ( ( l - d < x1 && x1 < r + d && t - d < y1 && y1 < b + d ) || ( l - d < x1 && x1 < r + d && t - d < y2 && y2 < b + d ) || ( l - d < x2 && x2 < r + d && t - d < y1 && y1 < b + d ) || ( l - d < x2 && x2 < r + d && t - d < y2 && y2 < b + d ) ) ) {
if ( inst . snapElements [ i ] . snapping ) ( inst . options . snap . release && inst . options . snap . release . call ( inst . element , null , $ . extend ( inst . uiHash ( ) , { snapItem : inst . snapElements [ i ] . item } ) ) ) ;
inst . snapElements [ i ] . snapping = false ;
continue ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( ui . options . snapMode != 'inner' ) {
2008-08-10 07:58:50 +00:00
var ts = Math . abs ( t - y2 ) <= d ;
var bs = Math . abs ( b - y1 ) <= d ;
var ls = Math . abs ( l - x2 ) <= d ;
var rs = Math . abs ( r - x1 ) <= d ;
2008-08-17 02:15:55 +00:00
if ( ts ) ui . position . top = inst . _convertPositionTo ( "relative" , { top : t - inst . helperProportions . height , left : 0 } ) . top ;
if ( bs ) ui . position . top = inst . _convertPositionTo ( "relative" , { top : b , left : 0 } ) . top ;
if ( ls ) ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l - inst . helperProportions . width } ) . left ;
if ( rs ) ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r } ) . left ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-07-17 16:13:10 +00:00
var first = ( ts || bs || ls || rs ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
if ( ui . options . snapMode != 'outer' ) {
2008-08-10 07:58:50 +00:00
var ts = Math . abs ( t - y1 ) <= d ;
var bs = Math . abs ( b - y2 ) <= d ;
var ls = Math . abs ( l - x1 ) <= d ;
var rs = Math . abs ( r - x2 ) <= d ;
2008-08-17 02:15:55 +00:00
if ( ts ) ui . position . top = inst . _convertPositionTo ( "relative" , { top : t , left : 0 } ) . top ;
if ( bs ) ui . position . top = inst . _convertPositionTo ( "relative" , { top : b - inst . helperProportions . height , left : 0 } ) . top ;
if ( ls ) ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l } ) . left ;
if ( rs ) ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r - inst . helperProportions . width } ) . left ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-07-17 16:13:10 +00:00
if ( ! inst . snapElements [ i ] . snapping && ( ts || bs || ls || rs || first ) )
( inst . options . snap . snap && inst . options . snap . snap . call ( inst . element , null , $ . extend ( inst . uiHash ( ) , { snapItem : inst . snapElements [ i ] . item } ) ) ) ;
inst . snapElements [ i ] . snapping = ( ts || bs || ls || rs || first ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . plugin . add ( "draggable" , "connectToSortable" , {
start : function ( e , ui ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
inst . sortables = [ ] ;
$ ( ui . options . connectToSortable ) . each ( function ( ) {
if ( $ . data ( this , 'sortable' ) ) {
var sortable = $ . data ( this , 'sortable' ) ;
inst . sortables . push ( {
instance : sortable ,
shouldRevert : sortable . options . revert
} ) ;
2008-09-19 14:20:14 +00:00
sortable . _refreshItems ( ) ; //Do a one-time refresh at start to refresh the containerCache
2008-08-17 02:15:55 +00:00
sortable . _propagate ( "activate" , e , inst ) ;
2008-06-04 02:34:33 +00:00
}
} ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} ,
stop : function ( e , ui ) {
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
var inst = $ ( this ) . data ( "draggable" ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
$ . each ( inst . sortables , function ( ) {
if ( this . instance . isOver ) {
this . instance . isOver = 0 ;
inst . cancelHelperRemoval = true ; //Don't remove the helper in the draggable instance
this . instance . cancelHelperRemoval = false ; //Remove it in the sortable instance (so sortable plugins like revert still work)
if ( this . shouldRevert ) this . instance . options . revert = true ; //revert here
2008-08-17 08:15:49 +00:00
this . instance . _mouseStop ( e ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//Also propagate receive event, since the sortable is actually receiving a element
this . instance . element . triggerHandler ( "sortreceive" , [ e , $ . extend ( this . instance . ui ( ) , { sender : inst . element } ) ] , this . instance . options [ "receive" ] ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
this . instance . options . helper = this . instance . options . _helper ;
} else {
2008-09-26 02:29:46 +00:00
this . instance . cancelHelperRemoval = false ; //Remove the helper in the sortable instance
2008-08-17 02:15:55 +00:00
this . instance . _propagate ( "deactivate" , e , inst ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ,
drag : function ( e , ui ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var inst = $ ( this ) . data ( "draggable" ) , self = this ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var checkPos = function ( o ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var l = o . left , r = l + o . width ,
t = o . top , b = t + o . height ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
return ( l < ( this . positionAbs . left + this . offset . click . left ) && ( this . positionAbs . left + this . offset . click . left ) < r
2008-09-19 14:20:14 +00:00
&& t < ( this . positionAbs . top + this . offset . click . top ) && ( this . positionAbs . top + this . offset . click . top ) < b ) ;
2008-06-04 02:34:33 +00:00
} ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
$ . each ( inst . sortables , function ( i ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( checkPos . call ( inst , this . instance . containerCache ) ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
if ( ! this . instance . isOver ) {
this . instance . isOver = 1 ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//Now we fake the start of dragging for the sortable instance,
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
this . instance . currentItem = $ ( self ) . clone ( ) . appendTo ( this . instance . element ) . data ( "sortable-item" , true ) ;
this . instance . options . _helper = this . instance . options . helper ; //Store helper option to later restore it
this . instance . options . helper = function ( ) { return ui . helper [ 0 ] ; } ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
e . target = this . instance . currentItem [ 0 ] ;
2008-08-17 08:15:49 +00:00
this . instance . _mouseCapture ( e , true ) ;
this . instance . _mouseStart ( e , true , true ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
this . instance . offset . click . top = inst . offset . click . top ;
this . instance . offset . click . left = inst . offset . click . left ;
this . instance . offset . parent . left -= inst . offset . parent . left - this . instance . offset . parent . left ;
this . instance . offset . parent . top -= inst . offset . parent . top - this . instance . offset . parent . top ;
2008-09-19 14:20:14 +00:00
2008-08-17 02:15:55 +00:00
inst . _propagate ( "toSortable" , e ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
2008-08-17 08:15:49 +00:00
if ( this . instance . currentItem ) this . instance . _mouseDrag ( e ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} else {
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//If it doesn't intersect with the sortable, and it intersected before,
//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
if ( this . instance . isOver ) {
this . instance . isOver = 0 ;
this . instance . cancelHelperRemoval = true ;
this . instance . options . revert = false ; //No revert here
2008-08-17 08:15:49 +00:00
this . instance . _mouseStop ( e , true ) ;
2008-06-04 02:34:33 +00:00
this . instance . options . helper = this . instance . options . _helper ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
this . instance . currentItem . remove ( ) ;
2008-06-24 13:32:17 +00:00
if ( this . instance . placeholder ) this . instance . placeholder . remove ( ) ;
2008-09-19 14:20:14 +00:00
2008-08-17 02:15:55 +00:00
inst . _propagate ( "fromSortable" , e ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
} ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . plugin . add ( "draggable" , "stack" , {
start : function ( e , ui ) {
var group = $ . makeArray ( $ ( ui . options . stack . group ) ) . sort ( function ( a , b ) {
return ( parseInt ( $ ( a ) . css ( "zIndex" ) , 10 ) || ui . options . stack . min ) - ( parseInt ( $ ( b ) . css ( "zIndex" ) , 10 ) || ui . options . stack . min ) ;
} ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
$ ( group ) . each ( function ( i ) {
this . style . zIndex = ui . options . stack . min + i ;
} ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
this [ 0 ] . style . zIndex = ui . options . stack . min + group . length ;
}
} ) ;
} ) ( jQuery ) ;