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
*
2009-01-03 21:55:13 +00:00
* Copyright ( c ) 2009 AUTHORS . txt ( http : //ui.jquery.com/about)
2008-06-04 02:34:33 +00:00
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-08-17 02:15:55 +00:00
_init : function ( ) {
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-07-28 21:06:04 +00:00
( this . options . cssNamespace && this . element . addClass ( this . options . cssNamespace + "-draggable" ) ) ;
2009-01-07 17:43:15 +00:00
( this . options . disabled && this . element . addClass ( this . options . cssNamespace + '-draggable-disabled' ) ) ;
2008-11-10 05:18:20 +00:00
2008-08-17 08:15:49 +00:00
this . _mouseInit ( ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-10 05:18:20 +00:00
2008-11-21 04:01:33 +00:00
destroy : function ( ) {
2009-01-16 02:09:45 +00:00
if ( ! this . element . data ( 'draggable' ) ) return ;
this . element . removeData ( "draggable" ) . unbind ( ".draggable" ) . removeClass ( this . options . cssNamespace + '-draggable ' + this . options . cssNamespace + '-draggable-dragging ' + this . options . cssNamespace + '-draggable-disabled' ) ;
2008-11-21 04:01:33 +00:00
this . _mouseDestroy ( ) ;
} ,
2008-11-14 03:00:16 +00:00
_mouseCapture : function ( event ) {
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
var o = this . options ;
2008-11-10 05:18:20 +00:00
2009-01-07 17:43:15 +00:00
if ( this . helper || o . disabled || $ ( event . target ) . is ( '.' + this . options . cssNamespace + '-resizable-handle' ) )
2008-07-17 15:04:42 +00:00
return false ;
2008-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
//Quit if we're not on a valid handle
2008-11-23 17:42:24 +00:00
this . handle = this . _getHandle ( event ) ;
2008-09-16 13:02:21 +00:00
if ( ! this . handle )
2008-09-15 20:26:42 +00:00
return false ;
2008-11-10 05:18:20 +00:00
2008-09-16 13:02:21 +00:00
return true ;
2008-11-10 05:18:20 +00:00
2008-09-16 13:02:21 +00:00
} ,
2008-11-10 05:18:20 +00:00
2008-11-14 03:00:16 +00:00
_mouseStart : function ( event ) {
2008-11-10 05:18:20 +00:00
2008-09-16 13:02:21 +00:00
var o = this . options ;
2008-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
//Create and append the visible helper
2008-11-23 17:42:24 +00:00
this . helper = this . _createHelper ( event ) ;
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
//Cache the helper size
this . _cacheHelperProportions ( ) ;
2008-11-10 05:18:20 +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-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
//Cache the margins of the original element
this . _cacheMargins ( ) ;
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
//Store the helper's css position
this . cssPosition = this . helper . css ( "position" ) ;
this . scrollParent = this . helper . scrollParent ( ) ;
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
//The element's absolute position on the page minus margins
2008-11-28 15:43:32 +00:00
this . offset = this . element . offset ( ) ;
2008-11-23 17:42:24 +00:00
this . offset = {
2008-06-04 02:34:33 +00:00
top : this . offset . top - this . margins . top ,
left : this . offset . left - this . margins . left
} ;
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
$ . extend ( this . offset , {
click : { //Where the click happened, relative to the element
left : event . pageX - this . offset . left ,
top : event . pageY - this . offset . top
} ,
parent : this . _getParentOffset ( ) ,
relative : this . _getRelativeOffset ( ) //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
} ) ;
2008-11-28 15:43:32 +00:00
2008-09-15 20:26:42 +00:00
//Generate the original position
2008-11-14 03:00:16 +00:00
this . originalPosition = this . _generatePosition ( event ) ;
2009-01-08 12:37:15 +00:00
this . originalPageX = event . pageX ;
this . originalPageY = event . pageY ;
2008-11-10 05:18:20 +00:00
2009-01-08 13:39:58 +00:00
//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
if ( o . cursorAt )
this . _adjustOffsetFromHelper ( o . cursorAt ) ;
2008-11-23 17:42:24 +00:00
//Set a containment if given in the options
2008-09-15 20:26:42 +00:00
if ( o . containment )
2008-11-23 17:42:24 +00:00
this . _setContainment ( ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
//Call plugins and callbacks
2009-01-08 15:49:20 +00:00
this . _trigger ( "start" , event ) ;
2008-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
//Recache the helper size
2008-11-23 17:42:24 +00:00
this . _cacheHelperProportions ( ) ;
2008-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
//Prepare the droppable offsets
if ( $ . ui . ddmanager && ! o . dropBehaviour )
2008-11-14 03:00:16 +00:00
$ . ui . ddmanager . prepareOffsets ( this , event ) ;
2008-11-10 05:18:20 +00:00
2009-01-07 17:43:15 +00:00
this . helper . addClass ( o . cssNamespace + "-draggable-dragging" ) ;
2008-11-23 17:42:24 +00:00
this . _mouseDrag ( event , true ) ; //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-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
_mouseDrag : function ( event , noPropagation ) {
2008-11-21 04:01:33 +00:00
//Compute the helpers position
this . position = this . _generatePosition ( event ) ;
this . positionAbs = this . _convertPositionTo ( "absolute" ) ;
//Call plugins and callbacks and use the resulting position if something is returned
2009-01-15 19:40:11 +00:00
if ( ! noPropagation ) {
var ui = this . _uiHash ( ) ;
this . _trigger ( 'drag' , event , ui ) ;
this . position = ui . position ;
}
2008-11-21 04:01:33 +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' ;
if ( $ . ui . ddmanager ) $ . ui . ddmanager . drag ( this , event ) ;
return false ;
} ,
_mouseStop : function ( event ) {
//If we are using droppables, inform the manager about the drop
var dropped = false ;
if ( $ . ui . ddmanager && ! this . options . dropBehaviour )
2009-01-08 14:03:34 +00:00
dropped = $ . ui . ddmanager . drop ( this , event ) ;
//if a drop comes from outside (a sortable)
if ( this . dropped ) {
dropped = this . dropped ;
this . dropped = false ;
}
2008-11-21 04:01:33 +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 ) ) ) {
var self = this ;
$ ( this . helper ) . animate ( this . originalPosition , parseInt ( this . options . revertDuration , 10 ) , function ( ) {
2009-01-08 15:49:20 +00:00
self . _trigger ( "stop" , event ) ;
2008-11-21 04:01:33 +00:00
self . _clear ( ) ;
} ) ;
} else {
2009-01-08 15:49:20 +00:00
this . _trigger ( "stop" , event ) ;
2008-11-21 04:01:33 +00:00
this . _clear ( ) ;
}
return false ;
} ,
2008-11-23 17:42:24 +00:00
_getHandle : function ( event ) {
2008-11-21 04:01:33 +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 == event . target ) handle = true ;
} ) ;
return handle ;
} ,
2008-11-23 17:42:24 +00:00
_createHelper : function ( event ) {
2008-11-21 04:01:33 +00:00
var o = this . options ;
var helper = $ . isFunction ( o . helper ) ? $ ( o . helper . apply ( this . element [ 0 ] , [ event ] ) ) : ( o . helper == 'clone' ? this . element . clone ( ) : this . element ) ;
if ( ! helper . parents ( 'body' ) . length )
helper . appendTo ( ( o . appendTo == 'parent' ? this . element [ 0 ] . parentNode : o . appendTo ) ) ;
if ( helper [ 0 ] != this . element [ 0 ] && ! ( /(fixed|absolute)/ ) . test ( helper . css ( "position" ) ) )
helper . css ( "position" , "absolute" ) ;
return helper ;
} ,
2008-11-23 17:42:24 +00:00
_adjustOffsetFromHelper : function ( obj ) {
2008-09-15 20:26:42 +00:00
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-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
_getParentOffset : function ( ) {
2008-11-10 05:18:20 +00:00
2009-01-08 11:19:48 +00:00
//Get the offsetParent and cache its position
this . offsetParent = this . helper . offsetParent ( ) ;
var po = this . offsetParent . offset ( ) ;
// This is a special case where we need to modify a offset calculated on start, since the following happened:
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
if ( this . cssPosition == 'absolute' && this . scrollParent [ 0 ] != document && $ . ui . contains ( this . scrollParent [ 0 ] , this . offsetParent [ 0 ] ) ) {
po . left += this . scrollParent . scrollLeft ( ) ;
po . top += this . scrollParent . scrollTop ( ) ;
}
2008-11-23 17:42:24 +00:00
if ( ( this . offsetParent [ 0 ] == document . body && $ . browser . mozilla ) //Ugly FF3 fix
|| ( this . offsetParent [ 0 ] . tagName && this . offsetParent [ 0 ] . tagName . toLowerCase ( ) == 'html' && $ . browser . msie ) ) //Ugly IE fix
2008-11-28 15:43:32 +00:00
po = { top : 0 , left : 0 } ;
2008-11-23 17:42:24 +00:00
return {
top : po . top + ( parseInt ( this . offsetParent . css ( "borderTopWidth" ) , 10 ) || 0 ) ,
left : po . left + ( parseInt ( this . offsetParent . css ( "borderLeftWidth" ) , 10 ) || 0 )
} ;
} ,
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
_getRelativeOffset : function ( ) {
if ( this . cssPosition == "relative" ) {
var p = this . element . position ( ) ;
return {
top : p . top - ( parseInt ( this . helper . css ( "top" ) , 10 ) || 0 ) + this . scrollParent . scrollTop ( ) ,
left : p . left - ( parseInt ( this . helper . css ( "left" ) , 10 ) || 0 ) + this . scrollParent . scrollLeft ( )
} ;
} else {
return { top : 0 , left : 0 } ;
}
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
} ,
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
_cacheMargins : function ( ) {
this . margins = {
left : ( parseInt ( this . element . css ( "marginLeft" ) , 10 ) || 0 ) ,
top : ( parseInt ( this . element . css ( "marginTop" ) , 10 ) || 0 )
} ;
} ,
_cacheHelperProportions : function ( ) {
2008-09-15 20:26:42 +00:00
this . helperProportions = {
width : this . helper . outerWidth ( ) ,
height : this . helper . outerHeight ( )
} ;
} ,
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
_setContainment : function ( ) {
2008-11-10 05:18:20 +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 ,
2009-01-08 07:54:40 +00:00
$ ( o . containment == 'document' ? document : window ) . width ( ) - this . helperProportions . width - this . margins . left ,
( $ ( o . containment == 'document' ? document : window ) . height ( ) || document . body . parentNode . scrollHeight ) - this . helperProportions . height - this . margins . top
2008-09-15 20:26:42 +00:00
] ;
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
this . containment = [
2009-01-08 07:54:40 +00:00
co . left + ( parseInt ( $ ( ce ) . css ( "borderLeftWidth" ) , 10 ) || 0 ) - this . margins . left ,
co . top + ( parseInt ( $ ( ce ) . css ( "borderTopWidth" ) , 10 ) || 0 ) - this . margins . top ,
co . left + ( over ? Math . max ( ce . scrollWidth , ce . offsetWidth ) : ce . offsetWidth ) - ( parseInt ( $ ( ce ) . css ( "borderLeftWidth" ) , 10 ) || 0 ) - this . helperProportions . width - this . margins . left ,
co . top + ( over ? Math . max ( ce . scrollHeight , ce . offsetHeight ) : ce . offsetHeight ) - ( parseInt ( $ ( ce ) . css ( "borderTopWidth" ) , 10 ) || 0 ) - this . helperProportions . height - this . margins . top
2008-09-15 20:26:42 +00:00
] ;
}
2008-11-10 05:18:20 +00:00
2008-09-15 20:26:42 +00:00
} ,
2008-11-10 05:18:20 +00:00
2008-08-17 02:15:55 +00:00
_convertPositionTo : function ( d , pos ) {
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
if ( ! pos ) pos = this . position ;
var mod = d == "absolute" ? 1 : - 1 ;
2009-01-08 12:37:15 +00:00
var o = this . options , scroll = this . cssPosition == 'absolute' && ! ( this . scrollParent [ 0 ] != document && $ . ui . contains ( this . scrollParent [ 0 ] , this . offsetParent [ 0 ] ) ) ? this . offsetParent : this . scrollParent , scrollIsRootNode = ( /(html|body)/i ) . test ( scroll [ 0 ] . tagName ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
return {
top : (
2009-01-08 13:31:16 +00:00
pos . top // The absolute mouse position
+ this . offset . relative . top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
2008-06-04 02:34:33 +00:00
+ this . offset . parent . top * mod // The offsetParent's offset without borders (offset + border)
2009-01-08 13:31:16 +00:00
- ( this . cssPosition == 'fixed' ? - this . scrollParent . scrollTop ( ) : ( scrollIsRootNode ? 0 : scroll . scrollTop ( ) ) ) * mod
2008-06-04 02:34:33 +00:00
) ,
left : (
2009-01-08 13:31:16 +00:00
pos . left // The absolute mouse position
+ this . offset . relative . left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
2008-06-04 02:34:33 +00:00
+ this . offset . parent . left * mod // The offsetParent's offset without borders (offset + border)
2009-01-08 13:31:16 +00:00
- ( this . cssPosition == 'fixed' ? - this . scrollParent . scrollLeft ( ) : scrollIsRootNode ? 0 : scroll . scrollLeft ( ) ) * mod
2008-06-04 02:34:33 +00:00
)
} ;
2009-01-08 13:31:16 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
2008-11-14 03:00:16 +00:00
_generatePosition : function ( event ) {
2008-11-10 05:18:20 +00:00
2009-01-08 11:19:48 +00:00
var o = this . options , scroll = this . cssPosition == 'absolute' && ! ( this . scrollParent [ 0 ] != document && $ . ui . contains ( this . scrollParent [ 0 ] , this . offsetParent [ 0 ] ) ) ? this . offsetParent : this . scrollParent , scrollIsRootNode = ( /(html|body)/i ) . test ( scroll [ 0 ] . tagName ) ;
2009-01-08 07:54:40 +00:00
// This is another very weird special case that only happens for relative elements:
// 1. If the css position is relative
// 2. and the scroll parent is the document or similar to the offset parent
// we have to refresh the relative offset during the scroll so there are no jumps
if ( this . cssPosition == 'relative' && ! ( this . scrollParent [ 0 ] != document && this . scrollParent [ 0 ] != this . offsetParent [ 0 ] ) ) {
this . offset . relative = this . _getRelativeOffset ( ) ;
}
2009-01-08 12:37:15 +00:00
var pageX = event . pageX ;
var pageY = event . pageY ;
/ *
* - Position constraining -
* Constrain the position to a mix of grid , containment .
* /
if ( this . originalPosition ) { //If we are not dragging yet, we won't check for options
if ( this . containment ) {
if ( event . pageX - this . offset . click . left < this . containment [ 0 ] ) pageX = this . containment [ 0 ] + this . offset . click . left ;
if ( event . pageY - this . offset . click . top < this . containment [ 1 ] ) pageY = this . containment [ 1 ] + this . offset . click . top ;
if ( event . pageX - this . offset . click . left > this . containment [ 2 ] ) pageX = this . containment [ 2 ] + this . offset . click . left ;
if ( event . pageY - this . offset . click . top > this . containment [ 3 ] ) pageY = this . containment [ 3 ] + this . offset . click . top ;
}
if ( o . grid ) {
var top = this . originalPageY + Math . round ( ( pageY - this . originalPageY ) / o . grid [ 1 ] ) * o . grid [ 1 ] ;
pageY = this . containment ? ( ! ( top - this . offset . click . top < this . containment [ 1 ] || top - this . offset . click . top > this . containment [ 3 ] ) ? top : ( ! ( top - this . offset . click . top < this . containment [ 1 ] ) ? top - o . grid [ 1 ] : top + o . grid [ 1 ] ) ) : top ;
var left = this . originalPageX + Math . round ( ( pageX - this . originalPageX ) / o . grid [ 0 ] ) * o . grid [ 0 ] ;
pageX = this . containment ? ( ! ( left - this . offset . click . left < this . containment [ 0 ] || left - this . offset . click . left > this . containment [ 2 ] ) ? left : ( ! ( left - this . offset . click . left < this . containment [ 0 ] ) ? left - o . grid [ 0 ] : left + o . grid [ 0 ] ) ) : left ;
}
}
2009-01-08 13:31:16 +00:00
return {
2008-06-04 02:34:33 +00:00
top : (
2009-01-08 12:37:15 +00:00
pageY // The absolute mouse position
2008-06-04 02:34:33 +00:00
- 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-11-23 17:42:24 +00:00
+ ( this . cssPosition == 'fixed' ? - this . scrollParent . scrollTop ( ) : ( scrollIsRootNode ? 0 : scroll . scrollTop ( ) ) )
2008-06-04 02:34:33 +00:00
) ,
left : (
2009-01-08 12:37:15 +00:00
pageX // The absolute mouse position
2008-06-04 02:34:33 +00:00
- 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-11-23 17:42:24 +00:00
+ ( this . cssPosition == 'fixed' ? - this . scrollParent . scrollLeft ( ) : scrollIsRootNode ? 0 : scroll . scrollLeft ( ) )
2008-06-04 02:34:33 +00:00
)
} ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-10 05:18:20 +00:00
2008-08-17 02:15:55 +00:00
_clear : function ( ) {
2009-01-07 17:43:15 +00:00
this . helper . removeClass ( this . options . cssNamespace + "-draggable-dragging" ) ;
2008-11-03 11:24:48 +00:00
if ( this . helper [ 0 ] != this . element [ 0 ] && ! 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-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
// From now on bulk stuff - mainly helpers
2008-11-21 04:01:33 +00:00
2009-01-15 19:40:11 +00:00
_trigger : function ( type , event , ui ) {
ui = ui || this . _uiHash ( ) ;
$ . ui . plugin . call ( this , type , [ event , ui ] ) ;
2009-01-13 02:51:13 +00:00
if ( type == "drag" ) this . positionAbs = this . _convertPositionTo ( "absolute" ) ; //The absolute position has to be recalculated after plugins
2009-01-15 19:40:11 +00:00
return $ . widget . prototype . _trigger . call ( this , type , event , ui ) ;
2008-11-21 04:01:33 +00:00
} ,
2008-06-04 02:34:33 +00:00
plugins : { } ,
2008-11-21 04:01:33 +00:00
2008-11-23 17:42:24 +00:00
_uiHash : function ( event ) {
2008-06-04 02:34:33 +00:00
return {
helper : this . helper ,
position : this . position ,
absolutePosition : this . positionAbs ,
2008-11-10 05:18:20 +00:00
options : this . options
2008-06-04 02:34:33 +00:00
} ;
}
2008-11-21 04:01:33 +00:00
2008-06-04 02:34:33 +00:00
} ) ) ;
$ . extend ( $ . ui . draggable , {
2008-10-05 16:29:21 +00:00
version : "@VERSION" ,
2009-01-03 15:15:22 +00:00
eventPrefix : "drag" ,
2008-06-04 02:34:33 +00:00
defaults : {
2008-06-07 06:10:52 +00:00
appendTo : "parent" ,
axis : false ,
2009-01-07 15:37:02 +00:00
cancel : ":input,option" ,
2008-10-08 10:21:28 +00:00
connectToSortable : false ,
containment : false ,
2008-11-21 04:01:33 +00:00
cssNamespace : "ui" ,
2008-10-08 10:21:28 +00:00
cursor : "default" ,
2008-11-21 19:40:45 +00:00
cursorAt : null ,
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-11-21 04:01:33 +00:00
handle : false ,
2008-07-28 18:34:01 +00:00
helper : "original" ,
2008-10-08 10:21:28 +00:00
iframeFix : false ,
2009-01-15 23:19:27 +00:00
opacity : null ,
2008-10-08 10:21:28 +00:00
refreshPositions : false ,
revert : false ,
revertDuration : 500 ,
2008-07-28 21:06:04 +00:00
scope : "default" ,
2008-12-30 14:50:53 +00:00
scroll : true ,
2008-10-08 10:21:28 +00:00
scrollSensitivity : 20 ,
scrollSpeed : 20 ,
snap : false ,
snapMode : "both" ,
snapTolerance : 20 ,
2008-11-21 19:40:45 +00:00
stack : false ,
zIndex : null
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "connectToSortable" , {
2008-11-14 03:00:16 +00:00
start : function ( event , ui ) {
2008-11-21 04:01:33 +00:00
2009-01-16 02:09:45 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
2008-11-21 04:01:33 +00:00
inst . sortables = [ ] ;
$ ( ui . options . connectToSortable ) . each ( function ( ) {
2008-12-11 15:02:21 +00:00
// 'this' points to a string, and should therefore resolved as query, but instead, if the string is assigned to a variable, it loops through the strings properties,
// so we have to append '' to make it anonymous again
$ ( this + '' ) . each ( function ( ) {
if ( $ . data ( this , 'sortable' ) ) {
var sortable = $ . data ( this , 'sortable' ) ;
inst . sortables . push ( {
instance : sortable ,
shouldRevert : sortable . options . revert
} ) ;
sortable . _refreshItems ( ) ; //Do a one-time refresh at start to refresh the containerCache
2009-01-08 15:49:20 +00:00
sortable . _trigger ( "activate" , event , inst ) ;
2008-12-11 15:02:21 +00:00
}
} ) ;
2008-11-21 04:01:33 +00:00
} ) ;
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
stop : function ( event , ui ) {
2008-06-04 02:34:33 +00:00
2008-11-21 04:01:33 +00:00
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2009-01-16 02:09:45 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
2008-11-21 04:01:33 +00:00
$ . each ( inst . sortables , function ( ) {
if ( this . instance . isOver ) {
2009-01-08 14:03:34 +00:00
2008-11-21 04:01:33 +00:00
this . instance . isOver = 0 ;
2009-01-08 14:03:34 +00:00
2008-11-21 04:01:33 +00:00
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)
2009-01-08 14:03:34 +00:00
//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
if ( this . shouldRevert ) this . instance . options . revert = true ;
//Trigger the stop of the sortable
2008-11-21 04:01:33 +00:00
this . instance . _mouseStop ( event ) ;
2009-01-19 11:34:22 +00:00
2008-11-21 04:01:33 +00:00
this . instance . options . helper = this . instance . options . _helper ;
2008-12-31 08:22:11 +00:00
2009-01-08 14:03:34 +00:00
//If the helper has been the original item, restore properties in the sortable
if ( inst . options . helper == 'original' )
2008-12-30 16:34:23 +00:00
this . instance . currentItem . css ( { top : 'auto' , left : 'auto' } ) ;
2008-11-21 04:01:33 +00:00
} else {
this . instance . cancelHelperRemoval = false ; //Remove the helper in the sortable instance
2009-01-08 15:49:20 +00:00
this . instance . _trigger ( "deactivate" , event , inst ) ;
2008-11-21 04:01:33 +00:00
}
} ) ;
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
drag : function ( event , ui ) {
2009-01-16 02:09:45 +00:00
var inst = $ ( this ) . data ( "draggable" ) , self = this ;
2008-11-21 04:01:33 +00:00
var checkPos = function ( o ) {
var dyClick = this . offset . click . top , dxClick = this . offset . click . left ;
var helperTop = this . positionAbs . top , helperLeft = this . positionAbs . left ;
var itemHeight = o . height , itemWidth = o . width ;
var itemTop = o . top , itemLeft = o . left ;
return $ . ui . isOver ( helperTop + dyClick , helperLeft + dxClick , itemTop , itemLeft , itemHeight , itemWidth ) ;
} ;
$ . each ( inst . sortables , function ( i ) {
if ( checkPos . call ( inst , this . instance . containerCache ) ) {
//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 ;
//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 ] ; } ;
event . target = this . instance . currentItem [ 0 ] ;
this . instance . _mouseCapture ( event , true ) ;
this . instance . _mouseStart ( event , true , true ) ;
//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 ;
2009-01-08 15:49:20 +00:00
inst . _trigger ( "toSortable" , event ) ;
2009-01-08 14:03:34 +00:00
inst . dropped = this . instance . element ; //draggable revert needs that
2009-01-19 11:34:22 +00:00
this . instance . fromOutside = inst ; //Little hack so receive/update callbacks work
2008-11-21 04:01: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
if ( this . instance . currentItem ) this . instance . _mouseDrag ( event ) ;
} else {
//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
this . instance . _mouseStop ( event , true ) ;
this . instance . options . helper = this . instance . options . _helper ;
//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 ( ) ;
if ( this . instance . placeholder ) this . instance . placeholder . remove ( ) ;
2009-01-08 15:49:20 +00:00
inst . _trigger ( "fromSortable" , event ) ;
2009-01-08 14:03:34 +00:00
inst . dropped = false ; //draggable revert needs that
2008-11-21 04:01:33 +00:00
}
} ;
} ) ;
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "cursor" , {
2008-11-14 03:00:16 +00:00
start : function ( event , ui ) {
2008-11-21 04:01:33 +00:00
var t = $ ( 'body' ) ;
if ( t . css ( "cursor" ) ) ui . options . _cursor = t . css ( "cursor" ) ;
t . css ( "cursor" , ui . options . cursor ) ;
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
stop : function ( event , ui ) {
2008-11-21 04:01:33 +00:00
if ( ui . options . _cursor ) $ ( 'body' ) . css ( "cursor" , ui . options . _cursor ) ;
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "iframeFix" , {
2008-11-14 03:00:16 +00:00
start : function ( event , ui ) {
2008-11-10 05:18:20 +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" ) ;
} ) ;
} ,
2008-11-14 03:00:16 +00:00
stop : function ( event , ui ) {
2008-11-10 05:18:20 +00:00
$ ( "div.ui-draggable-iframeFix" ) . each ( function ( ) { this . parentNode . removeChild ( this ) ; } ) ; //Remove frame helpers
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "opacity" , {
2008-11-21 04:01:33 +00:00
start : function ( event , ui ) {
var t = $ ( ui . helper ) ;
if ( t . css ( "opacity" ) ) ui . options . _opacity = t . css ( "opacity" ) ;
t . css ( 'opacity' , ui . options . opacity ) ;
} ,
stop : function ( event , ui ) {
if ( ui . options . _opacity ) $ ( ui . helper ) . css ( 'opacity' , ui . options . _opacity ) ;
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "scroll" , {
2008-11-14 03:00:16 +00:00
start : function ( event , ui ) {
2008-06-04 02:34:33 +00:00
var o = ui . options ;
2009-01-16 02:09:45 +00:00
var i = $ ( this ) . data ( "draggable" ) ;
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
if ( i . scrollParent [ 0 ] != document && i . scrollParent [ 0 ] . tagName != 'HTML' ) i . overflowOffset = i . scrollParent . offset ( ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
drag : function ( event , ui ) {
2008-11-10 05:18:20 +00:00
2008-07-29 01:32:46 +00:00
var o = ui . options , scrolled = false ;
2009-01-16 02:09:45 +00:00
var i = $ ( this ) . data ( "draggable" ) ;
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
if ( i . scrollParent [ 0 ] != document && i . scrollParent [ 0 ] . tagName != 'HTML' ) {
if ( ( i . overflowOffset . top + i . scrollParent [ 0 ] . offsetHeight ) - event . pageY < o . scrollSensitivity )
i . scrollParent [ 0 ] . scrollTop = scrolled = i . scrollParent [ 0 ] . scrollTop + o . scrollSpeed ;
else if ( event . pageY - i . overflowOffset . top < o . scrollSensitivity )
i . scrollParent [ 0 ] . scrollTop = scrolled = i . scrollParent [ 0 ] . scrollTop - o . scrollSpeed ;
2008-11-28 15:43:32 +00:00
2008-11-23 17:42:24 +00:00
if ( ( i . overflowOffset . left + i . scrollParent [ 0 ] . offsetWidth ) - event . pageX < o . scrollSensitivity )
i . scrollParent [ 0 ] . scrollLeft = scrolled = i . scrollParent [ 0 ] . scrollLeft + o . scrollSpeed ;
else if ( event . pageX - i . overflowOffset . left < o . scrollSensitivity )
2008-11-28 15:43:32 +00:00
i . scrollParent [ 0 ] . scrollLeft = scrolled = i . scrollParent [ 0 ] . scrollLeft - o . scrollSpeed ;
2008-06-04 02:34:33 +00:00
} else {
2008-11-28 15:43:32 +00:00
2008-11-14 03:00:16 +00:00
if ( event . pageY - $ ( document ) . scrollTop ( ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollTop ( $ ( document ) . scrollTop ( ) - o . scrollSpeed ) ;
2008-11-23 17:42:24 +00:00
else if ( $ ( window ) . height ( ) - ( event . pageY - $ ( document ) . scrollTop ( ) ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollTop ( $ ( document ) . scrollTop ( ) + o . scrollSpeed ) ;
2008-11-10 05:18:20 +00:00
2008-11-14 03:00:16 +00:00
if ( event . pageX - $ ( document ) . scrollLeft ( ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollLeft ( $ ( document ) . scrollLeft ( ) - o . scrollSpeed ) ;
2008-11-23 17:42:24 +00:00
else if ( $ ( window ) . width ( ) - ( event . pageX - $ ( document ) . scrollLeft ( ) ) < o . scrollSensitivity )
2008-07-29 00:54:29 +00:00
scrolled = $ ( document ) . scrollLeft ( $ ( document ) . scrollLeft ( ) + o . scrollSpeed ) ;
2008-11-23 17:42:24 +00:00
2008-06-04 02:34:33 +00:00
}
2008-11-10 05:18:20 +00:00
2008-11-23 17:42:24 +00:00
if ( scrolled !== false && $ . ui . ddmanager && ! o . dropBehaviour )
2008-11-14 03:00:16 +00:00
$ . ui . ddmanager . prepareOffsets ( i , event ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "snap" , {
2008-11-14 03:00:16 +00:00
start : function ( event , ui ) {
2008-11-10 05:18:20 +00:00
2009-01-16 02:09:45 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
2008-06-04 02:34:33 +00:00
inst . snapElements = [ ] ;
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
drag : function ( event , ui ) {
2008-11-10 05:18:20 +00:00
2009-01-16 02:09:45 +00:00
var inst = $ ( this ) . data ( "draggable" ) ;
2008-10-08 10:21:28 +00:00
var d = ui . options . snapTolerance ;
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
for ( var i = inst . snapElements . length - 1 ; i >= 0 ; i -- ) {
2008-11-10 05:18:20 +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-11-10 05:18:20 +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 ) ) ) {
2008-11-23 17:42:24 +00:00
if ( inst . snapElements [ i ] . snapping ) ( inst . options . snap . release && inst . options . snap . release . call ( inst . element , event , $ . extend ( inst . _uiHash ( ) , { snapItem : inst . snapElements [ i ] . item } ) ) ) ;
2008-07-17 16:13:10 +00:00
inst . snapElements [ i ] . snapping = false ;
continue ;
}
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-07-17 16:13:10 +00:00
var first = ( ts || bs || ls || rs ) ;
2008-11-10 05:18:20 +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-11-10 05:18:20 +00:00
2008-07-17 16:13:10 +00:00
if ( ! inst . snapElements [ i ] . snapping && ( ts || bs || ls || rs || first ) )
2008-11-23 17:42:24 +00:00
( inst . options . snap . snap && inst . options . snap . snap . call ( inst . element , event , $ . extend ( inst . _uiHash ( ) , { snapItem : inst . snapElements [ i ] . item } ) ) ) ;
2008-07-17 16:13:10 +00:00
inst . snapElements [ i ] . snapping = ( ts || bs || ls || rs || first ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
} ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "stack" , {
2008-11-21 04:01:33 +00:00
start : function ( event , ui ) {
2008-06-04 02:34:33 +00:00
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-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
$ ( group ) . each ( function ( i ) {
this . style . zIndex = ui . options . stack . min + i ;
} ) ;
2008-11-10 05:18:20 +00:00
2008-06-04 02:34:33 +00:00
this [ 0 ] . style . zIndex = ui . options . stack . min + group . length ;
}
} ) ;
2009-01-16 02:09:45 +00:00
$ . ui . plugin . add ( "draggable" , "zIndex" , {
2008-11-21 04:01:33 +00:00
start : function ( event , ui ) {
var t = $ ( ui . helper ) ;
if ( t . css ( "zIndex" ) ) ui . options . _zIndex = t . css ( "zIndex" ) ;
t . css ( 'zIndex' , ui . options . zIndex ) ;
} ,
stop : function ( event , ui ) {
if ( ui . options . _zIndex ) $ ( ui . helper ) . css ( 'zIndex' , ui . options . _zIndex ) ;
}
} ) ;
2008-06-04 02:34:33 +00:00
} ) ( jQuery ) ;