2012-02-27 00:49:51 +00:00
/ * !
2011-10-14 18:19:04 +00:00
* jQuery UI Draggable @ VERSION
2012-07-04 13:08:08 +00:00
* http : //jqueryui.com
2008-06-04 02:34:33 +00:00
*
2013-01-10 13:52:20 +00:00
* Copyright 2013 jQuery Foundation and other contributors
2012-08-09 14:13:24 +00:00
* Released under the MIT license .
2010-07-09 13:01:04 +00:00
* http : //jquery.org/license
2008-11-10 05:18:20 +00:00
*
2011-10-14 18:19:04 +00:00
* http : //docs.jquery.com/UI/Draggable
2008-06-04 02:34:33 +00:00
*
* Depends :
2009-09-17 10:39:12 +00:00
* jquery . ui . core . js
2012-01-07 17:20:49 +00:00
* jquery . ui . interaction . js
2009-12-22 19:51:24 +00:00
* jquery . ui . widget . js
2008-06-04 02:34:33 +00:00
* /
2010-07-13 13:57:58 +00:00
( function ( $ , undefined ) {
2008-06-04 02:34:33 +00:00
2012-01-28 03:06:37 +00:00
// create a shallow copy of an object
function copy ( obj ) {
var prop ,
ret = { } ;
for ( prop in obj ) {
ret [ prop ] = obj [ prop ] ;
}
return ret ;
}
2011-11-23 17:03:09 +00:00
$ . widget ( "ui.draggable" , $ . ui . interaction , {
2011-10-14 18:19:04 +00:00
version : "@VERSION" ,
2010-02-05 03:03:50 +00:00
widgetEventPrefix : "drag" ,
2011-09-28 01:33:38 +00:00
2010-01-07 03:19:50 +00:00
options : {
2012-01-23 02:51:46 +00:00
appendTo : null ,
2012-12-12 19:23:17 +00:00
exclude : "input,textarea,button,select,option" ,
2012-01-14 21:15:02 +00:00
handle : null ,
2013-01-02 23:34:34 +00:00
helper : false ,
2013-01-02 23:27:22 +00:00
// callbacks
2013-01-02 23:34:34 +00:00
beforeStart : null ,
2013-01-02 23:27:22 +00:00
drag : null ,
start : null ,
stop : null
2008-11-21 04:01:33 +00:00
} ,
2011-10-14 18:19:04 +00:00
// dragEl: element being dragged (original or helper)
2011-10-26 01:54:03 +00:00
// position: final CSS position of dragEl
2011-10-14 18:19:04 +00:00
// offset: offset of dragEl
2012-01-28 03:06:37 +00:00
// originalPosition: CSS position before drag start
// originalOffset: offset before drag start
2012-01-29 00:34:29 +00:00
// originalPointer: pageX/Y at drag start (offset of pointer)
2012-01-28 03:06:37 +00:00
// startPosition: CSS position at drag start (after beforeStart)
// startOffset: offset at drag start (after beforeStart)
2011-10-26 01:54:03 +00:00
// tempPosition: overridable CSS position of dragEl
2011-10-14 18:19:04 +00:00
// overflowOffset: offset of scroll parent
2011-10-26 01:54:03 +00:00
// overflow: object containing width and height keys of scroll parent
2012-01-23 02:51:46 +00:00
// domPosition: object containing original parent and index when using
2012-12-10 22:35:15 +00:00
// appendTo option without a helper
2012-12-22 21:57:51 +00:00
// dragDimensions: saved off width and height used for various options
2008-11-21 04:01:33 +00:00
2011-09-28 01:33:38 +00:00
_create : function ( ) {
2011-11-23 17:32:55 +00:00
this . _super ( ) ;
2012-01-28 16:12:54 +00:00
2012-12-20 21:52:26 +00:00
this . scrollSensitivity = 20 ;
this . scrollSpeed = 5 ;
2011-10-14 18:19:04 +00:00
// Static position elements can't be moved with top/left
2011-09-28 01:33:38 +00:00
if ( this . element . css ( "position" ) === "static" ) {
this . element . css ( "position" , "relative" ) ;
}
2012-01-28 16:12:54 +00:00
this . element . addClass ( "ui-draggable" ) ;
2011-10-01 16:38:48 +00:00
} ,
2008-11-23 17:42:24 +00:00
2012-01-14 20:49:58 +00:00
/** interaction interface **/
2011-10-26 01:54:03 +00:00
2012-01-14 21:15:02 +00:00
_isValidTarget : function ( element ) {
2012-12-10 22:35:15 +00:00
var handle = this . options . handle ? element . is ( this . options . handle ) : true ,
exclude = this . options . exclude ? element . is ( this . options . exclude ) : false ;
return ( handle && ! exclude ) ;
2012-01-14 21:15:02 +00:00
} ,
2012-01-15 17:57:39 +00:00
_start : function ( event , pointerPosition ) {
2012-12-21 22:40:47 +00:00
var offset , startCssLeft , startCssTop , startPosition , startOffset ;
2012-01-23 02:51:46 +00:00
2012-12-22 21:57:51 +00:00
// Reset
this . dragDimensions = null ;
2011-10-01 16:38:48 +00:00
// The actual dragging element, should always be a jQuery object
2013-01-02 04:43:34 +00:00
this . dragEl = ( this . options . helper === true || typeof this . options . helper === "function" ) ?
2012-01-15 20:18:12 +00:00
this . _createHelper ( pointerPosition ) :
this . element ;
2011-11-06 22:42:35 +00:00
2012-01-23 02:51:46 +00:00
// _createHelper() ensures that helpers are in the correct position
// in the DOM, but we need to handle appendTo when there is no helper
if ( this . options . appendTo && this . dragEl === this . element ) {
this . domPosition = {
parent : this . element . parent ( ) ,
index : this . element . index ( )
} ;
offset = this . dragEl . offset ( ) ;
this . dragEl
2012-12-21 17:01:23 +00:00
. appendTo ( this . _appendToEl ( ) )
2012-01-23 02:51:46 +00:00
. offset ( offset ) ;
}
2011-10-26 01:54:03 +00:00
this . cssPosition = this . dragEl . css ( "position" ) ;
2011-11-23 14:03:02 +00:00
this . scrollParent = this . element . scrollParent ( ) ;
2008-06-04 02:34:33 +00:00
2012-01-21 02:17:11 +00:00
// Cache starting positions
2012-01-28 03:06:37 +00:00
this . originalPosition = this . startPosition = this . _getPosition ( ) ;
this . originalOffset = this . startOffset = this . dragEl . offset ( ) ;
2012-01-29 00:34:29 +00:00
this . originalPointer = pointerPosition ;
2008-11-21 04:01:33 +00:00
2012-12-22 21:57:51 +00:00
// If not already cached within _createHelper
if ( ! this . dragDimensions ) {
this . _cacheDragDimensions ( this . dragEl ) ;
}
2011-09-28 01:33:38 +00:00
// Cache current position and offset
2012-01-28 03:06:37 +00:00
this . position = copy ( this . startPosition ) ;
this . offset = copy ( this . startOffset ) ;
2009-01-22 13:10:18 +00:00
2011-10-26 01:54:03 +00:00
// Cache the offset of scrollParent, if required for _handleScrolling
2012-01-07 17:18:08 +00:00
if ( this . scrollParent [ 0 ] !== this . document [ 0 ] && this . scrollParent [ 0 ] . tagName !== "HTML" ) {
2011-10-26 01:54:03 +00:00
this . overflowOffset = this . scrollParent . offset ( ) ;
}
2012-01-07 17:18:08 +00:00
this . overflow = {
height : this . scrollParent [ 0 ] === this . document [ 0 ] ?
this . window . height ( ) : this . scrollParent . height ( ) ,
width : this . scrollParent [ 0 ] === this . document [ 0 ] ?
this . window . width ( ) : this . scrollParent . width ( )
} ;
2011-10-14 18:19:04 +00:00
2012-01-15 17:57:39 +00:00
this . _preparePosition ( pointerPosition ) ;
2011-10-26 01:54:03 +00:00
2012-01-28 03:06:37 +00:00
// If user cancels beforeStart, don't allow dragging
2012-01-28 03:17:27 +00:00
if ( this . _trigger ( "beforeStart" , event ,
this . _originalHash ( pointerPosition ) ) === false ) {
2012-12-05 03:26:40 +00:00
2012-11-08 21:10:43 +00:00
// domPosition needs to be undone even if beforeStart is stopped
// Otherwise this.dragEl will remain in the element appendTo is set to
this . _resetDomPosition ( ) ;
2011-11-23 17:03:09 +00:00
return false ;
2012-12-05 03:26:40 +00:00
2011-10-26 01:54:03 +00:00
}
2012-12-21 22:40:47 +00:00
// Save off the usual properties locally, so they can be reverted from start
startCssLeft = this . dragEl . css ( "left" ) ;
startCssTop = this . dragEl . css ( "top" ) ;
startPosition = copy ( this . _getPosition ( ) ) ;
startOffset = copy ( this . offset ) ;
2012-01-09 02:48:53 +00:00
this . _setCss ( ) ;
2012-01-28 03:06:37 +00:00
this . startPosition = this . _getPosition ( ) ;
this . startOffset = this . dragEl . offset ( ) ;
2012-12-21 22:40:47 +00:00
// If user cancels on start, don't allow dragging
if ( this . _trigger ( "start" , event ,
this . _fullHash ( pointerPosition ) ) === false ) {
// domPosition needs to be undone even if start is stopped
// Otherwise this.dragEl will remain in the element appendTo is set to
this . startPosition = startPosition ;
this . startOffset = startOffset ;
this . dragEl . css ( {
left : startCssLeft ,
top : startCssTop
} ) ;
this . _resetDomPosition ( ) ;
return false ;
}
2012-01-28 03:06:37 +00:00
this . _blockFrames ( ) ;
2011-09-28 01:33:38 +00:00
} ,
2012-12-05 03:26:40 +00:00
2012-12-12 19:23:17 +00:00
_resetDomPosition : function ( ) {
2012-12-05 03:26:40 +00:00
2012-11-08 21:10:43 +00:00
// Nothing to do in this case
if ( ! this . domPosition ) {
return ;
}
2012-12-05 03:26:40 +00:00
var parent = this . domPosition . parent ,
next = parent . children ( ) . eq ( this . domPosition . index ) ;
2012-11-08 21:10:43 +00:00
if ( next . length ) {
next . before ( this . element ) ;
} else {
parent . append ( this . element ) ;
}
this . element . offset ( this . offset ) ;
this . domPosition = null ;
2012-12-05 03:26:40 +00:00
2012-11-08 21:10:43 +00:00
} ,
2008-11-21 04:01:33 +00:00
2012-01-15 17:57:39 +00:00
_move : function ( event , pointerPosition ) {
this . _preparePosition ( pointerPosition ) ;
2011-10-26 01:54:03 +00:00
2012-01-08 01:44:51 +00:00
// If user cancels drag, don't move the element
2012-01-28 03:17:27 +00:00
if ( this . _trigger ( "drag" , event , this . _fullHash ( pointerPosition ) ) === false ) {
2012-12-21 22:40:47 +00:00
return false ;
2011-10-26 01:54:03 +00:00
}
2012-01-09 02:48:53 +00:00
this . _setCss ( ) ;
2011-10-26 01:54:03 +00:00
// Scroll the scrollParent, if needed
2012-01-15 17:57:39 +00:00
this . _handleScrolling ( pointerPosition ) ;
2011-10-26 01:54:03 +00:00
} ,
2012-01-15 17:57:39 +00:00
_stop : function ( event , pointerPosition ) {
this . _preparePosition ( pointerPosition ) ;
2011-10-26 01:54:03 +00:00
2012-01-21 03:07:52 +00:00
// If user cancels stop, leave helper there
2012-01-28 03:17:27 +00:00
if ( this . _trigger ( "stop" , event , this . _fullHash ( pointerPosition ) ) !== false ) {
2011-10-26 01:54:03 +00:00
if ( this . options . helper ) {
2013-02-18 16:59:31 +00:00
delete this . element . data ( "ui-draggable" ) . helper ;
2011-10-26 01:54:03 +00:00
this . dragEl . remove ( ) ;
}
2012-11-08 21:10:43 +00:00
this . _resetDomPosition ( ) ;
2011-10-26 01:54:03 +00:00
}
2011-11-18 00:48:04 +00:00
this . _unblockFrames ( ) ;
2011-10-26 01:54:03 +00:00
} ,
2012-01-14 20:49:58 +00:00
/** internal **/
2012-01-15 20:18:12 +00:00
_createHelper : function ( pointerPosition ) {
var helper ,
offset = this . element . offset ( ) ,
xPos = ( pointerPosition . x - offset . left ) / this . element . outerWidth ( ) ,
yPos = ( pointerPosition . y - offset . top ) / this . element . outerHeight ( ) ;
// clone
if ( this . options . helper === true ) {
helper = this . element . clone ( )
. removeAttr ( "id" )
. find ( "[id]" )
. removeAttr ( "id" )
. end ( ) ;
} else {
// TODO: figure out the signature for this; see #4957
helper = $ ( this . options . helper ( ) ) ;
}
2012-01-23 02:51:46 +00:00
// Ensure the helper is in the DOM; obey the appendTo option if it exists
if ( this . options . appendTo || ! helper . closest ( "body" ) . length ) {
2012-12-21 17:01:23 +00:00
helper . appendTo ( this . _appendToEl ( ) || this . document [ 0 ] . body ) ;
2012-01-23 02:51:46 +00:00
}
2012-12-22 21:57:51 +00:00
2013-02-18 16:59:31 +00:00
this . element . data ( "ui-draggable" ) . helper = helper ;
2012-01-23 02:51:46 +00:00
2012-12-22 21:57:51 +00:00
this . _cacheDragDimensions ( helper ) ;
2012-01-15 20:18:12 +00:00
return helper
// Helper must be absolute to function properly
. css ( "position" , "absolute" )
. offset ( {
2012-12-22 21:57:51 +00:00
left : pointerPosition . x - this . dragDimensions . width * xPos ,
top : pointerPosition . y - this . dragDimensions . height * yPos
2012-01-15 20:18:12 +00:00
} ) ;
} ,
2012-12-22 21:57:51 +00:00
_cacheDragDimensions : function ( el ) {
this . dragDimensions = {
width : el . outerWidth ( ) ,
height : el . outerHeight ( )
} ;
} ,
2012-12-21 17:01:23 +00:00
// TODO: Remove after 2.0, only used for backCompat
_appendToEl : function ( ) {
return this . options . appendTo ;
} ,
2012-01-14 20:49:58 +00:00
_getPosition : function ( ) {
var left , top , position ,
scrollTop = this . scrollParent . scrollTop ( ) ,
scrollLeft = this . scrollParent . scrollLeft ( ) ;
// If fixed or absolute
if ( this . cssPosition !== "relative" ) {
position = this . dragEl . position ( ) ;
// Take into account scrollbar
position . top -= scrollTop ;
position . left -= scrollLeft ;
return position ;
}
// When using relative, css values are checked
// Otherwise the position wouldn't account for padding on ancestors
left = this . dragEl . css ( "left" ) ;
top = this . dragEl . css ( "top" ) ;
// Webkit will give back auto if there is no explicit value
left = ( left === "auto" ) ? 0 : parseInt ( left , 10 ) ;
top = ( top === "auto" ) ? 0 : parseInt ( top , 10 ) ;
return {
left : left - scrollLeft ,
top : top - scrollTop
} ;
} ,
2012-01-15 17:57:39 +00:00
_handleScrolling : function ( pointerPosition ) {
2013-01-07 19:44:00 +00:00
var newScrollTop , newScrollLeft ,
scrollTop = this . scrollParent . scrollTop ( ) ,
2012-01-14 20:49:58 +00:00
scrollLeft = this . scrollParent . scrollLeft ( ) ,
2012-12-20 21:52:26 +00:00
scrollSensitivity = this . scrollSensitivity ,
2012-01-14 20:49:58 +00:00
// overflowOffset is only set when scrollParent is not doc/html
overflowLeft = this . overflowOffset ?
this . overflowOffset . left :
scrollLeft ,
overflowTop = this . overflowOffset ?
this . overflowOffset . top :
scrollTop ,
2012-01-15 17:57:39 +00:00
xRight = this . overflow . width + overflowLeft - pointerPosition . x ,
xLeft = pointerPosition . x - overflowLeft ,
yBottom = this . overflow . height + overflowTop - pointerPosition . y ,
2013-01-07 19:44:00 +00:00
yTop = pointerPosition . y - overflowTop ,
// accounts for change in scrollbar to modify "original" pointer so calc
change ;
2012-01-14 20:49:58 +00:00
// Handle vertical scrolling
if ( yBottom < scrollSensitivity ) {
2013-01-12 01:25:03 +00:00
2013-01-07 19:44:00 +00:00
change = this . _speed ( scrollSensitivity - yBottom ) ;
this . scrollParent . scrollTop ( scrollTop + change ) ;
this . originalPointer . y = this . originalPointer . y + change ;
2013-01-12 01:25:03 +00:00
2012-01-14 20:49:58 +00:00
} else if ( yTop < scrollSensitivity ) {
2013-01-07 19:44:00 +00:00
change = this . _speed ( scrollSensitivity - yTop ) ;
newScrollTop = scrollTop - change ;
2013-01-12 01:25:03 +00:00
2013-01-07 19:44:00 +00:00
// Don't do anything unless new value is "real"
if ( newScrollTop >= 0 ) {
this . scrollParent . scrollTop ( newScrollTop ) ;
2013-01-07 20:07:42 +00:00
this . _speed ( scrollSensitivity - yTop ) ;
2013-01-07 19:44:00 +00:00
this . originalPointer . y = this . originalPointer . y - change ;
}
2012-01-14 20:49:58 +00:00
}
// Handle horizontal scrolling
if ( xRight < scrollSensitivity ) {
2013-01-07 19:44:00 +00:00
change = this . _speed ( scrollSensitivity - xRight ) ;
this . scrollParent . scrollLeft ( scrollLeft + change ) ;
this . originalPointer . x = this . originalPointer . x + change ;
2012-01-14 20:49:58 +00:00
} else if ( xLeft < scrollSensitivity ) {
2013-01-07 19:44:00 +00:00
change = this . _speed ( scrollSensitivity - xLeft ) ;
newScrollLeft = scrollLeft - change ;
// Don't do anything unless new value is "real"
if ( newScrollLeft >= 0 ) {
this . scrollParent . scrollLeft ( newScrollLeft ) ;
this . originalPointer . x = this . originalPointer . x - change ;
}
2013-01-12 01:25:03 +00:00
2012-01-14 20:49:58 +00:00
}
} ,
2012-12-20 21:52:26 +00:00
_speed : function ( distance ) {
return this . scrollSpeed + Math . round ( distance / 2 ) ;
} ,
2011-10-26 01:54:03 +00:00
// Uses event to determine new position of draggable, before any override from callbacks
2011-11-27 22:27:55 +00:00
// TODO: handle absolute element inside relative parent like a relative element
2012-01-15 17:57:39 +00:00
_preparePosition : function ( pointerPosition ) {
2012-01-29 00:34:29 +00:00
var leftDiff = pointerPosition . x - this . originalPointer . x ,
topDiff = pointerPosition . y - this . originalPointer . y ,
2011-10-14 18:19:04 +00:00
newLeft = leftDiff + this . startPosition . left ,
newTop = topDiff + this . startPosition . top ;
2008-11-21 04:01:33 +00:00
2011-10-26 01:54:03 +00:00
// Save off new values for .css() in various callbacks using this function
2011-09-28 01:33:38 +00:00
this . position = {
2011-10-01 16:05:36 +00:00
left : newLeft ,
top : newTop
2011-09-28 01:33:38 +00:00
} ;
2008-11-21 04:01:33 +00:00
2011-10-26 01:54:03 +00:00
// Save off values to compare user override against automatic coordinates
this . tempPosition = {
left : newLeft ,
top : newTop
2011-11-06 21:39:17 +00:00
} ;
2011-11-18 00:48:04 +00:00
2011-09-28 01:33:38 +00:00
// Refresh offset cache with new positions
2011-11-13 22:14:19 +00:00
this . offset . left = this . startOffset . left + leftDiff ;
this . offset . top = this . startOffset . top + topDiff ;
2011-10-26 01:54:03 +00:00
} ,
2008-06-04 02:34:33 +00:00
2012-01-09 02:48:53 +00:00
// Places draggable where event, or user via event/callback, indicates
_setCss : function ( ) {
2012-10-22 01:50:03 +00:00
2012-01-14 20:49:58 +00:00
var newLeft = this . position . left ,
newTop = this . position . top ;
2008-06-04 02:34:33 +00:00
2011-09-28 01:33:38 +00:00
// User overriding left/top so shortcut math is no longer valid
2012-01-14 20:49:58 +00:00
if ( this . tempPosition . left !== this . position . left ||
this . tempPosition . top !== this . position . top ) {
2012-01-07 17:18:08 +00:00
// Reset offset based on difference of expected and overridden values
2012-01-14 20:49:58 +00:00
this . offset . left += newLeft - this . tempPosition . left ;
this . offset . top += newTop - this . tempPosition . top ;
2011-09-28 01:33:38 +00:00
}
2011-10-14 18:19:04 +00:00
// TODO: does this work with nested scrollable parents?
2013-01-07 20:07:42 +00:00
if ( this . cssPosition !== "fixed" ) {
2012-01-14 20:49:58 +00:00
newLeft += this . scrollParent . scrollLeft ( ) ;
newTop += this . scrollParent . scrollTop ( ) ;
2011-10-09 04:54:47 +00:00
}
2012-10-22 01:50:03 +00:00
2011-09-28 01:33:38 +00:00
this . dragEl . css ( {
2011-11-18 00:48:04 +00:00
left : newLeft ,
top : newTop
2011-09-28 01:33:38 +00:00
} ) ;
} ,
2008-11-10 05:18:20 +00:00
2012-01-28 03:17:27 +00:00
_originalHash : function ( pointerPosition ) {
2013-01-02 03:15:03 +00:00
2011-11-06 21:20:56 +00:00
var ret = {
2011-11-13 22:14:19 +00:00
position : this . position ,
2012-01-28 03:06:37 +00:00
offset : copy ( this . offset ) ,
pointer : copy ( pointerPosition )
2008-06-04 02:34:33 +00:00
} ;
2011-11-06 22:42:35 +00:00
2011-11-06 21:20:56 +00:00
if ( this . options . helper ) {
ret . helper = this . dragEl ;
}
2011-11-06 22:42:35 +00:00
2011-11-06 21:20:56 +00:00
return ret ;
2011-11-06 22:42:35 +00:00
} ,
2012-01-29 00:34:29 +00:00
_fullHash : function ( pointerPosition ) {
2012-01-28 03:17:27 +00:00
return $ . extend ( this . _originalHash ( pointerPosition ) , {
originalPosition : copy ( this . originalPosition ) ,
2012-01-29 00:34:29 +00:00
originalOffset : copy ( this . originalOffset ) ,
originalPointer : copy ( this . originalPointer )
2012-01-28 03:17:27 +00:00
} ) ;
} ,
2011-11-23 14:03:02 +00:00
_blockFrames : function ( ) {
this . iframeBlocks = this . document . find ( "iframe" ) . map ( function ( ) {
var iframe = $ ( this ) ,
iframeOffset = iframe . offset ( ) ;
return $ ( "<div>" )
. css ( {
position : "absolute" ,
width : iframe . outerWidth ( ) ,
height : iframe . outerHeight ( ) ,
top : iframeOffset . top ,
left : iframeOffset . left
} )
2012-12-10 22:14:37 +00:00
. appendTo ( iframe . parent ( ) ) [ 0 ] ;
2011-11-23 14:03:02 +00:00
} ) ;
} ,
2011-11-06 22:42:35 +00:00
_unblockFrames : function ( ) {
2011-11-27 22:27:55 +00:00
if ( this . iframeBlocks ) {
2011-11-18 00:48:04 +00:00
this . iframeBlocks . remove ( ) ;
delete this . iframeBlocks ;
2011-11-06 22:42:35 +00:00
}
2012-01-28 16:12:54 +00:00
} ,
_destroy : function ( ) {
this . element . removeClass ( "ui-draggable" ) ;
this . _super ( ) ;
2011-09-28 01:33:38 +00:00
}
2008-06-04 02:34:33 +00:00
} ) ;
2012-01-31 01:57:52 +00:00
$ . widget ( "ui.draggable" , $ . ui . draggable , {
// $.widget doesn't know how to handle redefinitions with a custom prefix
// custom prefixes are going away anyway, so it's not worth fixing right now
widgetEventPrefix : "drag" ,
options : {
containment : null
} ,
_create : function ( ) {
this . _super ( ) ;
2012-07-24 15:20:18 +00:00
this . _on ( {
2012-01-31 01:57:52 +00:00
dragstart : "_setContainment" ,
drag : "_contain"
} ) ;
} ,
_setContainment : function ( event , ui ) {
var offset , left , top ,
container = this . _getContainer ( ) ;
if ( ! container ) {
this . containment = null ;
return ;
}
2012-11-13 21:37:09 +00:00
offset = container . offset ( ) ;
2012-01-31 01:57:52 +00:00
left = offset . left +
2012-11-05 21:49:51 +00:00
( parseFloat ( $ . css ( container [ 0 ] , "borderLeftWidth" , true ) ) || 0 ) +
( parseFloat ( $ . css ( container [ 0 ] , "paddingLeft" , true ) ) || 0 ) ;
2012-01-31 01:57:52 +00:00
top = offset . top +
2012-11-05 21:49:51 +00:00
( parseFloat ( $ . css ( container [ 0 ] , "borderTopWidth" , true ) ) || 0 ) +
( parseFloat ( $ . css ( container [ 0 ] , "paddingTop" , true ) ) || 0 ) ;
2012-01-31 01:57:52 +00:00
this . containment = {
left : left ,
top : top ,
right : left + container . width ( ) ,
bottom : top + container . height ( ) ,
leftDiff : ui . originalOffset . left - ui . originalPosition . left ,
topDiff : ui . originalOffset . top - ui . originalPosition . top ,
2012-12-22 21:57:51 +00:00
width : this . dragDimensions . width ,
height : this . dragDimensions . height
2012-01-31 01:57:52 +00:00
} ;
} ,
_contain : function ( event , ui ) {
var containment = this . containment ;
if ( ! containment ) {
return ;
}
ui . position . left = Math . max ( ui . position . left ,
containment . left - containment . leftDiff ) ;
ui . position . left = Math . min ( ui . position . left ,
containment . right - containment . width - containment . leftDiff ) ;
ui . position . top = Math . max ( ui . position . top ,
containment . top - containment . topDiff ) ;
ui . position . top = Math . min ( ui . position . top ,
containment . bottom - containment . height - containment . topDiff ) ;
} ,
_getContainer : function ( ) {
var container ,
containment = this . options . containment ;
if ( ! containment ) {
container = null ;
} else if ( containment === "parent" ) {
container = this . element . parent ( ) ;
} else {
container = $ ( containment ) ;
if ( ! container . length ) {
container = null ;
}
}
return container ;
}
} ) ;
2011-10-14 18:19:04 +00:00
} ) ( jQuery ) ;
2012-12-10 22:50:13 +00:00
// DEPRECATED
if ( $ . uiBackCompat !== false ) {
2012-12-21 17:01:23 +00:00
// appendTo 'parent' value
$ . widget ( "ui.draggable" , $ . ui . draggable , {
_appendToEl : function ( ) {
2012-12-21 22:40:47 +00:00
2012-12-21 17:01:23 +00:00
var el = this . options . appendTo ;
2012-12-21 22:40:47 +00:00
2013-01-02 04:43:34 +00:00
if ( el === "parent" ) {
2012-12-21 17:01:23 +00:00
el = this . dragEl . parent ( ) ;
}
2012-12-21 22:40:47 +00:00
2012-12-21 17:01:23 +00:00
return el ;
2012-12-21 22:40:47 +00:00
2012-12-21 17:01:23 +00:00
}
} ) ;
2012-12-21 22:40:47 +00:00
2012-12-23 17:42:50 +00:00
// helper 'original' or 'clone' value + helper return value
2012-12-21 17:01:23 +00:00
$ . widget ( "ui.draggable" , $ . ui . draggable , {
_create : function ( ) {
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
var self = this ,
orig = this . _originalHash ;
2012-12-21 17:01:23 +00:00
this . _super ( ) ;
2012-12-21 22:40:47 +00:00
2013-01-02 04:43:34 +00:00
if ( this . options . helper === "original" ) {
2012-12-21 17:01:23 +00:00
this . options . helper = false ;
}
2013-01-02 04:43:34 +00:00
if ( this . options . helper === "clone" ) {
2012-12-21 17:01:23 +00:00
this . options . helper = true ;
}
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
this . _originalHash = function ( ) {
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
var ret = orig . apply ( self , arguments ) ;
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
if ( ! ret . helper ) {
ret . helper = self . element ;
}
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
return ret ;
2013-01-02 03:15:03 +00:00
2012-12-23 17:42:50 +00:00
} ;
2012-12-21 17:01:23 +00:00
} ,
_setOption : function ( key , value ) {
2013-01-02 04:43:34 +00:00
if ( key !== "helper" ) {
2012-12-21 17:01:23 +00:00
return this . _super ( key , value ) ;
}
2012-12-21 22:40:47 +00:00
2013-01-02 04:43:34 +00:00
if ( value === "clone" ) {
2012-12-21 17:01:23 +00:00
value = true ;
}
2012-12-21 22:40:47 +00:00
2013-01-02 04:43:34 +00:00
if ( value === "original" ) {
2012-12-21 17:01:23 +00:00
value = false ;
}
this . _super ( key , value ) ;
}
} ) ;
2012-12-10 22:50:13 +00:00
// axis option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
axis : false
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 19:10:09 +00:00
var self = this ;
2012-12-10 22:50:13 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
// On drag, make sure top does not change so axis is locked
this . element . on ( "drag" , function ( event , ui ) {
if ( self . options . axis === "x" ) {
ui . position . top = ui . originalPosition . top ;
}
if ( self . options . axis === "y" ) {
ui . position . left = ui . originalPosition . left ;
}
} ) ;
2012-12-20 21:52:26 +00:00
2012-12-10 22:50:13 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-10 22:50:13 +00:00
} ) ;
2012-12-20 21:52:26 +00:00
2012-12-20 19:58:44 +00:00
// cancel option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
cancel : null
} ,
_create : function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 19:58:44 +00:00
this . _super ( ) ;
if ( this . options . cancel !== null ) {
this . options . exclude = this . options . cancel ;
}
2012-12-20 21:52:26 +00:00
2012-12-20 19:58:44 +00:00
} ,
2012-12-20 21:52:26 +00:00
2012-12-20 19:58:44 +00:00
_setOption : function ( key , value ) {
2012-12-20 21:52:26 +00:00
2013-01-02 04:43:34 +00:00
if ( key !== "cancel" ) {
2012-12-20 19:58:44 +00:00
return this . _super ( key , value ) ;
}
2012-12-20 21:52:26 +00:00
2012-12-20 19:58:44 +00:00
this . _super ( key , value ) ;
2012-12-20 21:52:26 +00:00
this . options . exclude = this . options . cancel ;
2012-12-20 19:58:44 +00:00
}
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-10 23:03:58 +00:00
// cursor option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
2012-12-11 23:20:48 +00:00
cursor : "auto"
2012-12-10 23:03:58 +00:00
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-11 16:55:08 +00:00
var startCursor , self , body ;
2012-12-20 19:10:09 +00:00
2012-12-10 23:03:58 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
self = this ;
body = $ ( this . document [ 0 ] . body ) ;
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
// Cache original cursor to set back
2012-12-21 22:26:10 +00:00
this . element . on ( "dragbeforestart" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
if ( self . options . cursor ) {
2012-12-20 19:10:09 +00:00
startCursor = body [ 0 ] . style . cursor ;
2012-12-11 23:20:48 +00:00
body . css ( "cursor" , self . options . cursor ) ;
2012-12-20 20:21:30 +00:00
}
2012-12-21 22:26:10 +00:00
2012-12-20 20:21:30 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
// Set back cursor to whatever default was
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstop" , function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
if ( self . options . cursor ) {
2012-12-12 19:23:17 +00:00
body . css ( "cursor" , startCursor ) ;
2012-12-20 20:21:30 +00:00
}
2012-12-10 23:03:58 +00:00
2012-12-20 20:21:30 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-10 23:03:58 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-10 23:03:58 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-11 16:55:08 +00:00
// cursorAt option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
cursorAt : false
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
var self = this ;
2012-12-20 19:10:09 +00:00
2012-12-11 16:55:08 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 19:23:17 +00:00
this . element . on ( "dragbeforestart" , function ( event , ui ) {
2012-12-20 21:52:26 +00:00
2012-12-22 22:03:53 +00:00
var cursorAt = self . options . cursorAt ;
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! cursorAt ) {
return ;
}
2012-12-20 19:10:09 +00:00
2013-01-02 03:15:03 +00:00
// support array and string position notation
// TODO: Remove after 2.0, only used for backCompat
if ( typeof cursorAt === "string" ) {
cursorAt = cursorAt . split ( " " ) ;
}
if ( $ . isArray ( cursorAt ) ) {
cursorAt = {
left : + cursorAt [ 0 ] ,
top : + cursorAt [ 1 ] || 0
} ;
}
2012-12-11 16:55:08 +00:00
if ( "top" in cursorAt ) {
ui . position . top += ui . pointer . y - ui . offset . top - cursorAt . top ;
}
if ( "left" in cursorAt ) {
ui . position . left += ui . pointer . x - ui . offset . left - cursorAt . left ;
}
if ( "bottom" in cursorAt ) {
2012-12-22 21:57:51 +00:00
ui . position . top += ui . pointer . y - ui . offset . top - self . dragDimensions . height + cursorAt . bottom ;
2012-12-11 16:55:08 +00:00
}
if ( "right" in cursorAt ) {
2012-12-22 21:57:51 +00:00
ui . position . left += ui . pointer . x - ui . offset . left - self . dragDimensions . width + cursorAt . right ;
2012-12-11 16:55:08 +00:00
}
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-11 16:55:08 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-11 16:55:08 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
// grid option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
grid : false
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-20 21:52:26 +00:00
var self = this ,
2012-12-20 20:21:30 +00:00
currentX , currentY ;
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 19:23:17 +00:00
this . element . on ( "dragbeforestart" , function ( event , ui ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
if ( ! self . options . grid ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-20 20:21:30 +00:00
// Save off the start position, which may be overwritten during drag
2012-12-11 23:20:48 +00:00
currentX = ui . position . left ;
currentY = ui . position . top ;
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 19:23:17 +00:00
this . element . on ( "drag" , function ( event , ui ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
if ( ! self . options . grid ) {
return ;
}
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// Save off the intended intervals
var x = self . options . grid [ 0 ] ,
y = self . options . grid [ 1 ] ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// If x is actually something, check that user is at least half way to next point
2012-12-11 23:20:48 +00:00
if ( x ) {
2013-01-07 16:35:18 +00:00
if ( ui . position . left - currentX >= x / 2 ) {
2012-12-11 23:20:48 +00:00
currentX = currentX + x ;
2013-01-07 16:35:18 +00:00
} else if ( currentX - ui . position . left >= x / 2 ) {
2012-12-11 23:20:48 +00:00
currentX = currentX - x ;
}
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// If y is actually something, check that user is at least half way to next point
2012-12-11 23:20:48 +00:00
if ( y ) {
2013-01-07 16:35:18 +00:00
if ( ui . position . top - currentY >= y / 2 ) {
2012-12-11 23:20:48 +00:00
currentY = currentY + y ;
2013-01-07 16:35:18 +00:00
} else if ( currentY - ui . position . top >= y / 2 ) {
2012-12-11 23:20:48 +00:00
currentY = currentY - y ;
}
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// If there threshold wasn't crossed these variables wouldn't be changed
// Otherwise this will now bump the draggable to the next spot on grid
2012-12-11 23:20:48 +00:00
ui . position . left = currentX ;
ui . position . top = currentY ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// opacity option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
opacity : false
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
var self = this ,
originalOpacity ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstart" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . opacity ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// Cache the original opacity of draggable element to reset later
2013-01-02 04:43:34 +00:00
originalOpacity = self . dragEl . css ( "opacity" ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// Set draggable element to new opacity
2013-01-02 04:43:34 +00:00
self . dragEl . css ( "opacity" , self . options . opacity ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstop" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . opacity ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:16:20 +00:00
// Reset opacity
2013-01-02 04:43:34 +00:00
self . dragEl . css ( "opacity" , originalOpacity ) ;
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-11 23:20:48 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
// TODO: handle droppables
2012-12-12 00:28:47 +00:00
// revert + revertDuration options
2012-12-12 00:21:37 +00:00
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
2012-12-12 00:28:47 +00:00
revert : false ,
revertDuration : 500
2012-12-12 00:21:37 +00:00
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
var self = this ,
originalLeft , originalTop , originalPosition ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragbeforestart" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . revert ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
// Cache the original css of draggable element to reset later
2013-01-02 04:43:34 +00:00
originalLeft = self . dragEl . css ( "left" ) ;
originalTop = self . dragEl . css ( "top" ) ;
originalPosition = self . dragEl . css ( "position" ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstop" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . revert ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
// Reset to before drag
2012-12-12 00:28:47 +00:00
self . dragEl . animate ( {
2012-12-20 19:10:09 +00:00
left : originalLeft ,
top : originalTop ,
position : originalPosition
2012-12-12 00:28:47 +00:00
} , self . options . revertDuration ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:21:37 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
// zIndex option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
zIndex : false
} ,
2012-12-20 19:10:09 +00:00
2012-12-20 19:58:44 +00:00
_create : function ( ) {
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
var self = this ,
originalZIndex ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
this . _super ( ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstart" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . zIndex ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
// Cache the original zIndex of draggable element to reset later
2013-01-02 04:43:34 +00:00
originalZIndex = self . dragEl . css ( "z-index" ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
// Set draggable element to new zIndex
2013-01-02 04:43:34 +00:00
self . dragEl . css ( "z-index" , self . options . zIndex ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-21 16:33:13 +00:00
this . element . on ( "dragstop" , function ( ) {
2012-12-20 21:52:26 +00:00
2012-12-20 20:21:30 +00:00
// No need to continue
if ( ! self . options . zIndex ) {
return ;
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
// Reset zIndex
2013-01-02 04:43:34 +00:00
self . dragEl . css ( "z-index" , originalZIndex ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
}
2012-12-20 19:10:09 +00:00
2012-12-12 00:49:41 +00:00
} ) ;
2012-12-20 19:10:09 +00:00
2012-12-20 21:52:26 +00:00
// TODO: need droppable working
// scope option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
scope : "default"
}
} ) ;
// scroll + scrollSensitivity + scrollSpeedType option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
scroll : true ,
scrollSpeed : null ,
scrollSensitivity : null
} ,
_create : function ( ) {
var self = this ,
handleScroll = this . _handleScrolling ,
speed = this . _speed ;
this . _super ( ) ;
this . _speed = function ( distance ) {
if ( self . options . scrollSpeed !== null ) {
self . scrollSpeed = self . options . scrollSpeed ;
// Undo calculation that makes things go faster as distance increases
distance = 0 ;
}
return speed . call ( self , distance ) ;
} ;
// Wrap member function to check for ability to scroll
this . _handleScrolling = function ( pointerPosition ) {
if ( ! self . options . scroll ) {
return ;
}
if ( self . options . scrollSensitivity !== null ) {
self . scrollSensitivity = self . options . scrollSensitivity ;
}
handleScroll . call ( self , pointerPosition ) ;
} ;
}
} ) ;
2012-12-20 23:02:00 +00:00
// stack option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
stack : false
} ,
_create : function ( ) {
var self = this ;
this . _super ( ) ;
2012-12-21 16:33:13 +00:00
this . element . on ( "dragbeforestart" , function ( ) {
2012-12-20 23:02:00 +00:00
var stack = self . options . stack ,
group , min ;
if ( ! self . options . stack ) {
return ;
}
group = $ . makeArray ( $ ( stack ) ) . sort ( function ( a , b ) {
var aZIndex = parseInt ( $ ( a ) . css ( "zIndex" ) , 10 ) ,
2012-12-21 16:33:13 +00:00
bZIndex = parseInt ( $ ( b ) . css ( "zIndex" ) , 10 ) ;
2012-12-20 23:02:00 +00:00
return ( aZIndex || 0 ) - ( bZIndex || 0 ) ;
} ) ;
if ( ! group . length ) {
return ;
}
min = parseInt ( group [ 0 ] . style . zIndex , 10 ) || 0 ;
$ ( group ) . each ( function ( i ) {
this . style . zIndex = min + i ;
} ) ;
self . element [ 0 ] . style . zIndex = min + group . length ;
} ) ;
}
} ) ;
2012-12-22 21:57:51 +00:00
// snap snapMode snapTolerance options
// mainly copy-pasted from 1.9 since the code is so "insane" didn't want to reverse-engineer into sanity
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
snap : false ,
2013-01-02 04:43:34 +00:00
snapMode : "both" ,
2012-12-22 21:57:51 +00:00
snapTolerance : 20
} ,
_create : function ( ) {
var inst = this ,
snapElements ;
this . _super ( ) ;
2013-01-02 04:43:34 +00:00
this . element . on ( "dragstart" , function ( ) {
2012-12-22 21:57:51 +00:00
// Nothing to do
if ( ! inst . options . snap ) {
return ;
}
// Reset snapElements on every start in case there have been changes
snapElements = [ ] ;
// Select either all draggable elements, or the selector that was passed in
2013-01-02 04:43:34 +00:00
$ ( inst . options . snap === true ? ":data(ui-draggable)" : inst . options . snap ) . each ( function ( ) {
2012-12-22 21:57:51 +00:00
var el = $ ( this ) ,
offset = el . offset ( ) ;
// Don't add this draggable to list of elements for snapping
if ( this === inst . element [ 0 ] ) {
return ;
}
// Save off elements dimensions for later
snapElements . push ( {
item : this ,
width : el . outerWidth ( ) ,
height : el . outerHeight ( ) ,
top : offset . top ,
left : offset . left
} ) ;
} ) ;
2013-01-02 03:15:03 +00:00
2012-12-22 21:57:51 +00:00
inst . margins = {
left : ( parseInt ( inst . element . css ( "marginLeft" ) , 10 ) || 0 ) ,
top : ( parseInt ( inst . element . css ( "marginTop" ) , 10 ) || 0 ) ,
right : ( parseInt ( inst . element . css ( "marginRight" ) , 10 ) || 0 ) ,
bottom : ( parseInt ( inst . element . css ( "marginBottom" ) , 10 ) || 0 )
} ;
} ) ;
2013-01-02 04:43:34 +00:00
this . element . on ( "drag" , function ( event , ui ) {
2013-01-02 03:15:03 +00:00
2012-12-22 21:57:51 +00:00
// Nothing to do
if ( ! inst . options . snap ) {
return ;
}
var ts , bs , ls , rs , l , r , t , b , i , first ,
o = inst . options ,
d = o . snapTolerance ,
x1 = ui . offset . left , x2 = x1 + inst . dragDimensions . width ,
y1 = ui . offset . top , y2 = y1 + inst . dragDimensions . height ;
for ( i = snapElements . length - 1 ; i >= 0 ; i -- ) {
l = snapElements [ i ] . left ;
r = l + snapElements [ i ] . width ;
t = snapElements [ i ] . top ;
b = t + snapElements [ i ] . height ;
//Yes, I know, this is insane ;)
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 ( snapElements [ i ] . snapping ) {
( inst . options . snap . release && inst . options . snap . release . call ( inst . element , event , $ . extend ( inst . _uiHash ( ) , { snapItem : snapElements [ i ] . item } ) ) ) ;
}
snapElements [ i ] . snapping = false ;
continue ;
}
2013-01-02 04:43:34 +00:00
if ( o . snapMode !== "inner" ) {
2012-12-22 21:57:51 +00:00
ts = Math . abs ( t - y2 ) <= d ;
bs = Math . abs ( b - y1 ) <= d ;
ls = Math . abs ( l - x2 ) <= d ;
rs = Math . abs ( r - x1 ) <= d ;
if ( ts ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : t - inst . dragDimensions . height , left : 0 } ) . top - inst . margins . top ;
}
if ( bs ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : b , left : 0 } ) . top - inst . margins . top ;
}
if ( ls ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l - inst . dragDimensions . width } ) . left - inst . margins . left ;
}
if ( rs ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r } ) . left - inst . margins . left ;
}
}
first = ( ts || bs || ls || rs ) ;
2013-01-02 04:43:34 +00:00
if ( o . snapMode !== "outer" ) {
2012-12-22 21:57:51 +00:00
ts = Math . abs ( t - y1 ) <= d ;
bs = Math . abs ( b - y2 ) <= d ;
ls = Math . abs ( l - x1 ) <= d ;
rs = Math . abs ( r - x2 ) <= d ;
if ( ts ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : t , left : 0 } ) . top - inst . margins . top ;
}
if ( bs ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : b - inst . dragDimensions . height , left : 0 } ) . top - inst . margins . top ;
}
if ( ls ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l } ) . left - inst . margins . left ;
}
if ( rs ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r - inst . dragDimensions . width } ) . left - inst . margins . left ;
}
}
if ( ! snapElements [ i ] . snapping && ( ts || bs || ls || rs || first ) ) {
( inst . options . snap . snap && inst . options . snap . snap . call ( inst . element , event , $ . extend ( inst . _uiHash ( ) , { snapItem : snapElements [ i ] . item } ) ) ) ;
}
snapElements [ i ] . snapping = ( ts || bs || ls || rs || first ) ;
}
} ) ;
} ,
_convertPositionTo : function ( d , pos ) {
if ( ! pos ) {
pos = this . position ;
}
var mod = d === "absolute" ? 1 : - 1 ,
2012-12-22 22:03:53 +00:00
offset = { } ,
2013-01-02 04:43:34 +00:00
scroll = this . cssPosition === "absolute" && ! ( this . scrollParent [ 0 ] !== document && $ . contains ( this . scrollParent [ 0 ] , this . offsetParent [ 0 ] ) ) ? this . offsetParent : this . scrollParent , scrollIsRootNode = ( /(html|body)/i ) . test ( scroll [ 0 ] . tagName ) ;
2012-12-22 21:57:51 +00:00
$ . extend ( offset , {
parent : this . _getParentOffset ( ) ,
relative : this . _getRelativeOffset ( ) //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
} ) ;
return {
top : (
pos . top + // The absolute mouse position
offset . relative . top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
offset . parent . top * mod - // The offsetParent's offset without borders (offset + border)
2013-01-02 04:43:34 +00:00
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollTop ( ) : ( scrollIsRootNode ? 0 : scroll . scrollTop ( ) ) ) * mod )
2012-12-22 21:57:51 +00:00
) ,
left : (
pos . left + // The absolute mouse position
offset . relative . left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
offset . parent . left * mod - // The offsetParent's offset without borders (offset + border)
2013-01-02 04:43:34 +00:00
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollLeft ( ) : scrollIsRootNode ? 0 : scroll . scrollLeft ( ) ) * mod )
2012-12-22 21:57:51 +00:00
)
} ;
} ,
_getParentOffset : function ( ) {
//Get the offsetParent and cache its position
this . offsetParent = this . dragEl . 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
2013-01-02 04:43:34 +00:00
if ( this . cssPosition === "absolute" && this . scrollParent [ 0 ] !== document && $ . contains ( this . scrollParent [ 0 ] , this . offsetParent [ 0 ] ) ) {
2012-12-22 21:57:51 +00:00
po . left += this . scrollParent . scrollLeft ( ) ;
po . top += this . scrollParent . scrollTop ( ) ;
}
//This needs to be actually done for all browsers, since pageX/pageY includes this information
//Ugly IE fix
if ( ( this . offsetParent [ 0 ] === document . body ) ||
2013-01-02 04:43:34 +00:00
( this . offsetParent [ 0 ] . tagName && this . offsetParent [ 0 ] . tagName . toLowerCase ( ) === "html" && $ . ui . ie ) ) {
2012-12-22 21:57:51 +00:00
po = { top : 0 , left : 0 } ;
}
return {
top : po . top + ( parseInt ( this . offsetParent . css ( "borderTopWidth" ) , 10 ) || 0 ) ,
left : po . left + ( parseInt ( this . offsetParent . css ( "borderLeftWidth" ) , 10 ) || 0 )
} ;
} ,
_getRelativeOffset : function ( ) {
if ( this . cssPosition === "relative" ) {
var p = this . element . position ( ) ;
return {
top : p . top - ( parseInt ( this . dragEl . css ( "top" ) , 10 ) || 0 ) + this . scrollParent . scrollTop ( ) ,
left : p . left - ( parseInt ( this . dragEl . css ( "left" ) , 10 ) || 0 ) + this . scrollParent . scrollLeft ( )
} ;
}
return { top : 0 , left : 0 } ;
}
} ) ;
2012-12-22 22:03:53 +00:00
// refreshPositions option
$ . widget ( "ui.draggable" , $ . ui . draggable , {
options : {
refreshPositions : false
} ,
_create : function ( ) {
var self = this ,
drops ;
this . _super ( ) ;
2013-01-02 03:15:03 +00:00
2012-12-22 22:03:53 +00:00
this . element . on ( "dragstart" , function ( ) {
2013-01-02 04:43:34 +00:00
drops = $ ( ":data(ui-sortable)" ) ;
2012-12-22 22:03:53 +00:00
} ) ;
// On drag, make sure top does not change so axis is locked
this . element . on ( "drag" , function ( ) {
if ( self . options . refreshPositions !== true ) {
return ;
}
drops . each ( function ( ) {
2013-01-02 04:43:34 +00:00
$ ( this ) . sortable ( "refreshPositions" ) ;
2012-12-22 22:03:53 +00:00
} ) ;
2013-01-02 03:15:03 +00:00
2012-12-22 22:03:53 +00:00
} ) ;
}
} ) ;
2013-01-02 03:15:03 +00:00
2013-01-02 04:43:34 +00:00
}