Permalink
Browse files

Merge pull request #2 from scottgonzalez/interactions

Draggable: Cleanup.
  • Loading branch information...
2 parents c8e1370 + ee094cc commit 6ea6c47855258c407a09ccf93058d91369eeeba8 @DaveStein DaveStein committed Oct 14, 2011
Showing with 78 additions and 161 deletions.
  1. +78 −161 ui/jquery.ui.draggable.js
View
239 ui/jquery.ui.draggable.js
@@ -1,11 +1,11 @@
/*
- * jQuery UI Draggable 2.0.0
+ * jQuery UI Draggable @VERSION
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
- * http://docs.jquery.com/UI/Draggables
+ * http://docs.jquery.com/UI/Draggable
*
* Depends:
* jquery.ui.core.js
@@ -14,90 +14,59 @@
(function( $, undefined ) {
$.widget( "ui.draggable", {
-
+ version: "@VERSION",
widgetEventPrefix: "drag",
options: {
-
- scrollSpeed: 20,
- scrollSensitivity:20,
- helper: false
-
+ helper: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 20
},
- // TODO: actually remove data
- destroy: function() {
- return this;
- },
+ // dragEl: element being dragged (original or helper)
+ // position: CSS position of dragEl
+ // offset: offset of dragEl
+ // startCoords: clientX/Y of the mousedown (offset of pointer)
+ // startPosition: CSS position prior to drag start
+ // startOffset: offset prior to drag start
+ // overflowOffset: offset of scroll parent
+ // overflowHeight: height of scroll parent
+ // overflowWidth: width of scroll parent
_create: function() {
-
- // Either initialized element or the helper
- this.dragEl = false,
-
- this.position = {},
- this.offset = {},
-
- // Start X/Y coords of mouse before drag
- this.startCoords = {},
-
- // Start position of element before drag
- this.startPosition = {},
-
- // Start offset of element before drag
- this.startOffset = {},
+ // TODO: add these to the base widget
+ this.doc = $( this.element[0].ownerDocument );
+ this.win = $( this.doc[0].defaultView );
this.scrollParent = this.element.scrollParent();
- // Offset of scrollParent, used for auto-scrolling
- this.overflowOffset = {};
-
- // Height of scrollParent, used for auto-scrolling
- this.overflowHeight = 0;
-
- // Width of scrollParent, used for auto-scrolling
- this.overflowWidth = 0;
-
- // Static position elements can"t be moved with top/left
+ // Static position elements can't be moved with top/left
if ( this.element.css( "position" ) === "static" ) {
this.element.css( "position", "relative" );
}
-
- // Using proxy to avoid anon functions using self to pass "this" along
- this.element.bind( "mousedown." + this.widgetName, $.proxy( this._mouseDown, this ) );
-
- },
- _usingHelper : function() {
- return ( this.options.helper === true || typeof this.options.helper === 'function' );
+ // TODO: use _bind()
+ this.element.bind( "mousedown." + this.widgetName, $.proxy( this, "_mouseDown" ) );
},
- _setPosition: function() {
-
+ // TODO: why is relative handled differently than fixed/absolute?
+ _getPosition: function() {
var left, top, position,
- scrollTop = this.scrollParent.scrollTop(),
- scrollLeft = this.scrollParent.scrollLeft();
-
- // Helper is appended to body so offset of element is all that's needed
- if ( this._usingHelper() ) {
- return this.element.offset();
- }
+ 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 = position.top - scrollTop;
- position.left = position.left - scrollLeft
+ position.top -= scrollTop;
+ position.left -= scrollLeft
return position;
-
}
- /** When using relative, css values are checked **/
-
+ // When using relative, css values are checked
left = this.dragEl.css( "left" );
top = this.dragEl.css( "top" );
@@ -106,64 +75,42 @@ $.widget( "ui.draggable", {
top = ( top === "auto" ) ? 0: parseInt( top, 10 );
return {
-
left: left - scrollLeft,
top: top - scrollTop
-
};
-
},
_mouseDown: function( event ) {
-
- // Stop browser from highlighting, among other things
- event.preventDefault();
+ // Prevent text selection, among other things
+ event.preventDefault();
// The actual dragging element, should always be a jQuery object
this.dragEl = this.element;
-
this.cssPosition = this.dragEl.css( "position" );
- // Helper required, so clone, hide, and set reference
- if ( this._usingHelper() ) {
-
- // If getting a cloned helper
+ // Helper required
+ if ( this.options.helper ) {
+ // clone
if ( this.options.helper === true ) {
-
- this.dragEl = this.element.clone();
-
// If source element has an ID, change ID of helper to avoid overlap
+ this.dragEl = this.element.clone();
if ( this.element.attr( "id" ) ) {
-
this.dragEl.attr( "id", this.element.attr( "id" ) + "-" + this.widgetName );
-
}
-
} else {
-
- this.dragEl = this.options.helper();
-
- // If function was passed, it should return a DOMElement
- if ( typeof this.dragEl.nodeType !== 'number' ) {
- throw "Helper function must return a DOMElement";
- }
-
- this.dragEl = $( this.dragEl );
-
+ // TODO: figure out the signature for this; see #4957
+ this.dragEl = $( this.options.helper() );
}
- // Automatically make helper absolute
this.dragEl
- .css({
- position: "absolute"
- });
-
- $( "body" ).append( this.dragEl );
-
+ // TODO: should we move this to the stylesheet and use a class?
+ .css( "position", "absolute" )
+ .appendTo( this.doc[0].body )
+ .offset( this.element.offset() );
}
// Cache starting absolute and relative positions
- this.startPosition = this._setPosition();
+ this.startPosition = this._getPosition();
this.startOffset = this.dragEl.offset();
// Cache current position and offset
@@ -176,38 +123,28 @@ $.widget( "ui.draggable", {
};
// Cache the offset of scrollParent
+ // TODO: store overflow height/width in a hash instead of separate properties
this.overflowOffset = this.scrollParent.offset();
- this.overflowHeight = ( this.scrollParent[0] === document ) ? $(window).height() : this.scrollParent.height();
- this.overflowWidth = ( this.scrollParent[0] === document ) ? $(window).width() : this.scrollParent.width();
-
- this._trigger( "start", event );
-
- $(document).bind( "mousemove." + this.widgetName, $.proxy( this._mouseMove, this ) )
- .bind( "mouseup." + this.widgetName, $.proxy( this._mouseUp, this ) );
-
-
- // Set the helper up by actual element
- if ( this._usingHelper() ) {
-
- // get the absolute position of element so that helper will know where to go
- elOffset = this.element.offset();
-
- this.dragEl.css({
- display: "block",
- top: elOffset.top + "px",
- left: elOffset.left + "px"
- });
-
- }
-
+ this.overflowHeight = ( this.scrollParent[0] === this.doc[0] ) ?
+ this.win.height() : this.scrollParent.height();
+ this.overflowWidth = ( this.scrollParent[0] === this.doc[0] ) ?
+ this.win.width() : this.scrollParent.width();
+
+ // TODO: allow modifying position, just like during drag
+ this._trigger( "start", event, this._uiHash() );
+
+ // TODO: use ._bind()
+ // TODO: rename _bind() to _on(); add _off()
+ this.doc
+ .bind( "mousemove." + this.widgetName, $.proxy( this, "_mouseMove" ) )
+ .bind( "mouseup." + this.widgetName, $.proxy( this, "_mouseUp" ) );
},
_mouseMove: function( event ) {
-
var leftDiff = event.clientX - this.startCoords.left,
- topDiff = event.clientY - this.startCoords.top,
- newLeft = leftDiff + this.startPosition.left,
- newTop = topDiff + this.startPosition.top;
+ topDiff = event.clientY - this.startCoords.top,
+ newLeft = leftDiff + this.startPosition.left,
+ newTop = topDiff + this.startPosition.top;
this.position = {
left: newLeft,
@@ -218,87 +155,67 @@ $.widget( "ui.draggable", {
this.offset.left = this.startOffset.left + newLeft;
this.offset.top = this.startOffset.top + newTop;
- this._trigger( "drag", event );
+ this._trigger( "drag", event, this._uiHash() );
// User overriding left/top so shortcut math is no longer valid
if ( newLeft !== this.position.left || newTop !== this.position.top ) {
-
+ // TODO: can we just store the previous offset values
+ // and not go through .offset()?
// refresh offset using slower functions
this.offset = this.dragEl.offset();
-
}
-
+
newLeft = this.position.left;
newTop = this.position.top;
-
- if ( this.cssPosition !== 'fixed' ) {
-
+
+ // TODO: does this work with nested scrollable parents?
+ if ( this.cssPosition !== "fixed" ) {
newLeft = newLeft + this.scrollParent.scrollLeft();
newTop = newTop + this.scrollParent.scrollTop();
-
}
this.dragEl.css({
-
left: newLeft + "px",
top: newTop + "px"
-
});
-
+
// Scroll the scrollParent, if needed
this._handleScrolling( event );
-
},
_handleScrolling: function( event ) {
-
- var doc = $(document),
- scrollTop = doc.scrollTop(),
- scrollLeft = doc.scrollLeft();
+ var scrollTop = this.doc.scrollTop(),
+ scrollLeft = this.doc.scrollLeft();
// Handle vertical scrolling
if ( ( ( this.overflowHeight + scrollTop ) - event.pageY ) < this.options.scrollSensitivity ) {
- doc.scrollTop( scrollTop + this.options.scrollSpeed );
+ this.doc.scrollTop( scrollTop + this.options.scrollSpeed );
}
-
+
// Handle horizontal scrolling
if ( ( ( this.overflowWidth + scrollLeft ) - event.pageX ) < this.options.scrollSensitivity ) {
- doc.scrollLeft( scrollLeft + this.options.scrollSpeed );
+ this.doc.scrollLeft( scrollLeft + this.options.scrollSpeed );
}
-
},
_mouseUp: function( event ) {
+ this._trigger( "stop", event, this._uiHash() );
- var doc = $(document);
-
- this._trigger( "stop", event );
-
- this.startCoords = {};
-
- if ( this._usingHelper() ) {
+ if ( this.options.helper ) {
this.dragEl.remove();
}
- doc.unbind( "mousemove." + this.widgetName );
- doc.unbind( "mouseup." + this.widgetName );
-
+ this.doc
+ .unbind( "mousemove." + this.widgetName )
+ .unbind( "mouseup." + this.widgetName );
},
- _uiHash: function(event) {
-
+ _uiHash: function( event ) {
return {
position: this.position,
offset: this.offset
};
-
}
-
-});
-
-$.extend($.ui.draggable, {
- version: "2.0.0"
});
-
-})(jQuery);
+})( jQuery );

0 comments on commit 6ea6c47

Please sign in to comment.