]> source.dussan.org Git - jquery-ui.git/commitdiff
sortable: refactored big parts of sortable with new parts of draggable - scrolling...
authorPaul Bakaus <paul.bakaus@googlemail.com>
Mon, 26 May 2008 11:24:50 +0000 (11:24 +0000)
committerPaul Bakaus <paul.bakaus@googlemail.com>
Mon, 26 May 2008 11:24:50 +0000 (11:24 +0000)
ui/source/ui.draggable.js
ui/source/ui.sortable.js

index 361b9a8d709392a03ebbb490b892f705c741abcc..21f0b868c454bb4d95c68520f7e1f92fca7b6692 100644 (file)
                },\r
                drag: function(e,ui) {\r
 \r
-                       //This is handy: We reuse the intersectsWith method for checking if the current draggable helper\r
-                       //intersects with the sortable container\r
                        var inst = $(this).data("draggable"), self = this;\r
-                       inst.position.absolute = ui.absolutePosition; //Sorry, this is an ugly API fix\r
                        \r
                        var checkPos = function(o) {\r
                                        \r
                                var l = o.left, r = l + o.width,\r
                                        t = o.top, b = t + o.height;\r
                                        \r
-                               return (l < (this.position.absolute.left + this.offset.click.left) && (this.position.absolute.left + this.offset.click.left) < r\r
-                                               && t < (this.position.absolute.top + this.offset.click.top) && (this.position.absolute.top + this.offset.click.top) < b);                               \r
+                               return (l < (this.positionAbs.left + this.offset.click.left) && (this.positionAbs.left + this.offset.click.left) < r\r
+                                               && t < (this.positionAbs.top + this.offset.click.top) && (this.positionAbs.top + this.offset.click.top) < b);                           \r
                        };\r
                        \r
                        $.each(inst.sortables, function() {\r
                                                this.instance.mouseStart(e, true);\r
 \r
                                                //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes\r
-                                               this.instance.clickOffset.top = inst.offset.click.top;\r
-                                               this.instance.clickOffset.left = inst.offset.click.left;\r
-                                               this.instance.offset.left -= ui.absolutePosition.left - this.instance.position.absolute.left;\r
-                                               this.instance.offset.top -= ui.absolutePosition.top - this.instance.position.absolute.top;\r
+                                               this.instance.offset.click.top = inst.offset.click.top;\r
+                                               this.instance.offset.click.left = inst.offset.click.left;\r
+                                               this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;\r
+                                               this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;\r
                                                \r
                                                inst.propagate("toSortable", e);\r
                                        \r
index 4fddc310f5b4ee38a1faf1caf184a17b4291412e..aa44faf18377fe44b42a0650e39bcd94ce907ccf 100644 (file)
@@ -52,8 +52,8 @@
                        return {\r
                                helper: (inst || this)["helper"],\r
                                placeholder: (inst || this)["placeholder"] || $([]),\r
-                               position: (inst || this)["position"].current,\r
-                               absolutePosition: (inst || this)["position"].absolute,\r
+                               position: (inst || this)["position"],\r
+                               absolutePosition: (inst || this)["positionAbs"],\r
                                options: this.options,\r
                                element: this.element,\r
                                item: (inst || this)["currentItem"],\r
                /* Be careful with the following core functions */\r
                intersectsWith: function(item) {\r
                        \r
-                       var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,\r
-                       y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;\r
+                       var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width,\r
+                       y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height;\r
                        var l = item.left, r = l + item.width, \r
                        t = item.top, b = t + item.height;\r
 \r
                        if(this.options.tolerance == "pointer") {\r
-                               return (y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < b && x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < r);\r
+                               return (y1 + this.offset.click.top > t && y1 + this.offset.click.top < b && x1 + this.offset.click.left > l && x1 + this.offset.click.left < r);\r
                        } else {\r
                        \r
                                return (l < x1 + (this.helperProportions.width / 2) // Right Half\r
                        \r
                },\r
                intersectsWithEdge: function(item) {    \r
-                       var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,\r
-                               y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;\r
+                       var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width,\r
+                               y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height;\r
                        var l = item.left, r = l + item.width, \r
                                t = item.top, b = t + item.height;\r
 \r
                        if(this.options.tolerance == "pointer") {\r
 \r
-                               if(!(y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < b && x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < r)) return false;\r
+                               if(!(y1 + this.offset.click.top > t && y1 + this.offset.click.top < b && x1 + this.offset.click.left > l && x1 + this.offset.click.left < r)) return false;\r
                                \r
                                if(this.floating) {\r
-                                       if(x1 + this.clickOffset.left > l && x1 + this.clickOffset.left < l + item.width/2) return 2;\r
-                                       if(x1 + this.clickOffset.left > l+item.width/2 && x1 + this.clickOffset.left < r) return 1;\r
+                                       if(x1 + this.offset.click.left > l && x1 + this.offset.click.left < l + item.width/2) return 2;\r
+                                       if(x1 + this.offset.click.left > l+item.width/2 && x1 + this.offset.click.left < r) return 1;\r
                                } else {\r
-                                       if(y1 + this.clickOffset.top > t && y1 + this.clickOffset.top < t + item.height/2) return 2;\r
-                                       if(y1 + this.clickOffset.top > t+item.height/2 && y1 + this.clickOffset.top < b) return 1;\r
+                                       if(y1 + this.offset.click.top > t && y1 + this.offset.click.top < t + item.height/2) return 2;\r
+                                       if(y1 + this.offset.click.top > t+item.height/2 && y1 + this.offset.click.top < b) return 1;\r
                                }\r
 \r
                        } else {\r
                                                if(this.currentContainer != this.containers[i]) {\r
                                                        \r
                                                        //When entering a new container, we will find the item with the least distance and append our item near it\r
-                                                       var dist = 10000; var itemWithLeastDistance = null; var base = this.position.absolute[this.containers[i].floating ? 'left' : 'top'];\r
+                                                       var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top'];\r
                                                        for (var j = this.items.length - 1; j >= 0; j--) {\r
                                                                if(!contains(this.containers[i].element[0], this.items[j].item[0])) continue;\r
                                                                var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];\r
 \r
                        this.refresh();\r
 \r
-                       //Create and append the visible helper\r
+                       //Create and append the visible helper                  \r
                        this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e, this.currentItem])) : this.currentItem.clone();\r
-                       if(!this.helper.parents('body').length) this.helper.appendTo(o.appendTo || this.currentItem[0].parentNode); //Add the helper to the DOM if that didn't happen already\r
+                       if(!this.helper.parents('body').length) this.helper.appendTo((o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)); //Add the helper to the DOM if that didn't happen already\r
                        this.helper.css({ position: 'absolute', clear: 'both' }).addClass('ui-sortable-helper'); //Position it absolutely and add a helper class\r
-                       \r
-                       //Prepare variables for position generation\r
-                       $.extend(this, {\r
-                               offsetParent: this.helper.offsetParent(),\r
-                               offsets: {\r
-                                       absolute: this.currentItem.offset()\r
-                               },\r
-                               mouse: {\r
-                                       start: { top: e.pageY, left: e.pageX }\r
-                               },\r
-                               margins: {\r
-                                       top: parseInt(this.currentItem.css("marginTop")) || 0,\r
-                                       left: parseInt(this.currentItem.css("marginLeft")) || 0\r
-                               }\r
-                       });\r
-                       \r
-                       //The relative click offset\r
-                       this.offsets.parent = this.offsetParent.offset();\r
-                       this.clickOffset = { left: e.pageX - this.offsets.absolute.left, top: e.pageY - this.offsets.absolute.top };\r
+\r
+                       /*\r
+                        * - Position generation -\r
+                        * This block generates everything position related - it's the core of draggables.\r
+                        */\r
+\r
+                       this.margins = {                                                                                                                                                                //Cache the margins\r
+                               left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),\r
+                               top: (parseInt(this.currentItem.css("marginTop"),10) || 0)\r
+                       };              \r
                \r
-                       this.originalPosition = {\r
-                               left: this.offsets.absolute.left - this.offsets.parent.left - this.margins.left,\r
-                               top: this.offsets.absolute.top - this.offsets.parent.top - this.margins.top\r
-                       }\r
+                       this.offset = this.currentItem.offset();                                                                                                                //The element's absolute position on the page\r
+                       this.offset = {                                                                                                                                                                 //Substract the margins from the element's absolute offset\r
+                               top: this.offset.top - this.margins.top,\r
+                               left: this.offset.left - this.margins.left\r
+                       };\r
                        \r
-                       //Generate a flexible offset that will later be subtracted from e.pageX/Y\r
-                       //I hate margins - they need to be removed before positioning the element absolutely..\r
-                       this.offset = {\r
-                               left: e.pageX - this.originalPosition.left,\r
-                               top: e.pageY - this.originalPosition.top\r
+                       this.offset.click = {                                                                                                                                                   //Where the click happened, relative to the element\r
+                               left: e.pageX - this.offset.left,\r
+                               top: e.pageY - this.offset.top\r
                        };\r
+                       \r
+                       this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();                    //Get the offsetParent and cache its position\r
 \r
-                       //Save the first time position\r
-                       $.extend(this, {\r
-                               position: {\r
-                                       current: { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left },\r
-                                       absolute: { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top },\r
-                                       dom: this.currentItem.prev()[0]\r
-                               }\r
-                       });\r
-\r
-                       //If o.placeholder is used, create a new element at the given position with the class\r
-                       if(o.placeholder) this.createPlaceholder();\r
+                       this.offset.parent = {                                                                                                                                                  //Store its position plus border\r
+                               top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),\r
+                               left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)\r
+                       };\r
+               \r
+                       this.originalPosition = this.generatePosition(e);                                                                                               //Generate the original position\r
+                       this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size\r
+                       \r
+                       if(o.cursorAt) {\r
+                               if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left;\r
+                               if(o.cursorAt.right != undefined) this.offset.click.left = this.helperProportions.width - o.cursorAt.right;\r
+                               if(o.cursorAt.top != undefined) this.offset.click.top = o.cursorAt.top;\r
+                               if(o.cursorAt.bottom != undefined) this.offset.click.top = this.helperProportions.height - o.cursorAt.bottom;\r
+                       }\r
 \r
-                       this.propagate("start", e); //Call plugins and callbacks\r
-                       this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; //Save and store the helper proportions\r
+                       this.domPosition = this.currentItem.prev()[0];                                                                                                  //Cache the former DOM position\r
 \r
-                       //If we have something in cursorAt, we'll use it\r
-                       if(o.cursorAt) {\r
-                               if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) {\r
-                                       this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));\r
-                                       this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));\r
-                               }\r
-                               if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) {\r
-                                       this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));\r
-                                       this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));\r
+                       /*\r
+                        * - Position constraining -\r
+                        * Here we prepare position constraining like grid and containment.\r
+                        */     \r
+                       \r
+                       if(o.containment) {\r
+                               if(o.containment == 'parent') o.containment = this.helper[0].parentNode;\r
+                               if(o.containment == 'document') this.containment = [0,0,$(document).width(), ($(document).height() || document.body.parentNode.scrollHeight)];\r
+                               if(!(/^(document|window|parent)$/).test(o.containment)) {\r
+                                       var ce = $(o.containment)[0];\r
+                                       var co = $(o.containment).offset();\r
+                                       \r
+                                       this.containment = [\r
+                                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left,\r
+                                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top,\r
+                                               co.left+Math.max(ce.scrollWidth,ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0),\r
+                                               co.top+Math.max(ce.scrollHeight,ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0)\r
+                                       ];\r
                                }\r
                        }\r
+                       \r
+                       //If o.placeholder is used, create a new element at the given position with the class\r
+                       if(o.placeholder) this.createPlaceholder();\r
+                       \r
+                       //Call plugins and callbacks\r
+                       this.propagate("start", e);\r
+                       this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size\r
 \r
-                       if(this.options.placeholder != 'clone') $(this.currentItem).css('visibility', 'hidden'); //Set the original element visibility to hidden to still fill out the white space\r
+                       if(this.options.placeholder != 'clone') this.currentItem.css('visibility', 'hidden'); //Set the original element visibility to hidden to still fill out the white space\r
                        for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i].propagate("activate", e, this); } //Post 'activate' events to possible containers\r
                        \r
                        //Prepare possible droppables\r
                        if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);\r
 \r
                        this.dragging = true;\r
-                       \r
+\r
+                       //this.mouseDrag(e); //Execute the drag once - this causes the helper not to be visible before getting its correct position\r
                        return true;\r
 \r
+\r
+               },\r
+               convertPositionTo: function(d, pos) {\r
+                       if(!pos) pos = this.position;\r
+                       var mod = d == "absolute" ? 1 : -1;\r
+                       return {\r
+                               top: (\r
+                                       pos.top                                                                                                                                 // the calculated relative position\r
+                                       + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)\r
+                                       - (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) * mod    // The offsetParent's scroll position\r
+                                       + this.margins.top * mod                                                                                                //Add the margin (you don't want the margin counting in intersection methods)\r
+                               ),\r
+                               left: (\r
+                                       pos.left                                                                                                                                // the calculated relative position\r
+                                       + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)\r
+                                       - (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft) * mod   // The offsetParent's scroll position\r
+                                       + this.margins.left * mod                                                                                               //Add the margin (you don't want the margin counting in intersection methods)\r
+                               )\r
+                       };\r
+               },\r
+               generatePosition: function(e) {\r
+                       \r
+                       var o = this.options;\r
+                       var position = {\r
+                               top: (\r
+                                       e.pageY                                                                                                                                 // The absolute mouse position\r
+                                       - this.offset.click.top                                                                                                 // Click offset (relative to the element)\r
+                                       - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)\r
+                                       + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)  // The offsetParent's scroll position, not if the element is fixed\r
+                               ),\r
+                               left: (\r
+                                       e.pageX                                                                                                                                 // The absolute mouse position\r
+                                       - this.offset.click.left                                                                                                // Click offset (relative to the element)\r
+                                       - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)\r
+                                       + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft) // The offsetParent's scroll position, not if the element is fixed\r
+                               )\r
+                       };\r
+                       \r
+                       if(!this.originalPosition) return position;                                                                             //If we are not dragging yet, we won't check for options\r
+                       \r
+                       /*\r
+                        * - Position constraining -\r
+                        * Constrain the position to a mix of grid, containment.\r
+                        */\r
+                       if(this.containment) {\r
+                               if(position.left < this.containment[0]) position.left = this.containment[0];\r
+                               if(position.top < this.containment[1]) position.top = this.containment[1];\r
+                               if(position.left > this.containment[2]) position.left = this.containment[2];\r
+                               if(position.top > this.containment[3]) position.top = this.containment[3];\r
+                       }\r
+                       \r
+                       if(o.grid) {\r
+                               var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];\r
+                               position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\r
+                               \r
+                               var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];\r
+                               position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\r
+                       }\r
+                       \r
+                       return position;\r
                },\r
                mouseDrag: function(e) {\r
 \r
+\r
                        //Compute the helpers position\r
-                       this.position.current = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left };\r
-                       this.position.absolute = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top };\r
+                       this.position = this.generatePosition(e);\r
+                       this.positionAbs = this.convertPositionTo("absolute");\r
 \r
                        //Rearrange\r
                        for (var i = this.items.length - 1; i >= 0; i--) {\r
                        //Post events to containers\r
                        this.contactContainers(e);\r
                        \r
+                        //Call plugins and callbacks\r
+                       this.propagate("sort", e);\r
+\r
+                       if(!this.options.axis || this.options.axis == "x") this.helper[0].style.left = this.position.left+'px';\r
+                       if(!this.options.axis || this.options.axis == "y") this.helper[0].style.top = this.position.top+'px';\r
+                       \r
                        //Interconnect with droppables\r
                        if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);\r
 \r
-                       this.propagate("sort", e); //Call plugins and callbacks\r
-                       this.helper.css({ left: this.position.current.left+'px', top: this.position.current.top+'px' }); // Stick the helper to the cursor\r
                        return false;\r
                        \r
                },\r
                mouseStop: function(e) {\r
 \r
-                       this.propagate("stop", e); //Call plugins and trigger callbacks\r
-                       if(this.position.dom != this.currentItem.prev()[0]) this.propagate("update", e); //Trigger update callback if the DOM position has changed\r
+                       //If we are using droppables, inform the manager about the drop\r
+                       if ($.ui.ddmanager && !this.options.dropBehaviour)\r
+                               $.ui.ddmanager.drop(this, e);\r
+                               \r
+                       if(this.options.revert) {\r
+                               var self = this;\r
+                               var cur = self.currentItem.offset();\r
+\r
+                               //Also animate the placeholder if we have one\r
+                               if(self.placeholder) self.placeholder.animate({ opacity: 'hide' }, (parseInt(this.options.revert, 10) || 500)-50);\r
+\r
+                               $(this.helper).animate({\r
+                                       left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),\r
+                                       top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)\r
+                               }, parseInt(this.options.revert, 10) || 500, function() {\r
+                                       self.propagate("stop", e);\r
+                                       self.clear(e);\r
+                               });\r
+                       } else {\r
+                               this.propagate("stop", e);\r
+                               this.clear(e);\r
+                       }\r
+\r
+                       return false;\r
+                       \r
+               },\r
+               clear: function(e) {\r
+                       \r
+                       if(this.domPosition != this.currentItem.prev()[0]) this.propagate("update", e); //Trigger update callback if the DOM position has changed\r
                        if(!contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element\r
                                this.propagate("remove", e);\r
                                for (var i = this.containers.length - 1; i >= 0; i--){\r
                                }\r
                        }\r
                        \r
-                       //If we are using droppables, inform the manager about the drop\r
-                       if ($.ui.ddmanager && !this.options.dropBehaviour) $.ui.ddmanager.drop(this, e);\r
-                       \r
                        this.dragging = false;\r
                        if(this.cancelHelperRemoval) return false;\r
                        $(this.currentItem).css('visibility', '');\r
                        if(this.placeholder) this.placeholder.remove();\r
                        this.helper.remove();\r
-\r
-                       return false;\r
+                       \r
+                       return true;\r
                        \r
                },\r
                rearrange: function(e, i, a) {\r
                        cancel: ":input,button",\r
                        items: '> *',\r
                        zIndex: 1000,\r
-                       dropOnEmpty: true\r
+                       dropOnEmpty: true,\r
+                       appendTo: "parent"\r
                }\r
        });\r
 \r
  * Sortable Extensions\r
  */\r
 \r
-       $.ui.plugin.add("sortable", "cursor", {\r
-               start: function(e, ui) {\r
-                       var t = $('body');\r
-                       if (t.css("cursor")) ui.options._cursor = t.css("cursor");\r
-                       t.css("cursor", ui.options.cursor);\r
-               },\r
-               stop: function(e, ui) {\r
-                       if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);\r
-               }\r
-       });\r
-\r
-       $.ui.plugin.add("sortable", "zIndex", {\r
-               start: function(e, ui) {\r
-                       var t = ui.helper;\r
-                       if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");\r
-                       t.css('zIndex', ui.options.zIndex);\r
-               },\r
-               stop: function(e, ui) {\r
-                       if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);\r
-               }\r
-       });\r
-\r
-       $.ui.plugin.add("sortable", "opacity", {\r
-               start: function(e, ui) {\r
-                       var t = ui.helper;\r
-                       if(t.css("opacity")) ui.options._opacity = t.css("opacity");\r
-                       t.css('opacity', ui.options.opacity);\r
-               },\r
-               stop: function(e, ui) {\r
-                       if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);\r
-               }\r
-       });\r
-\r
-\r
-       $.ui.plugin.add("sortable", "revert", {\r
-               stop: function(e, ui) {\r
-                       var self = this.data("sortable");\r
-                       self.cancelHelperRemoval = true;\r
-                       var cur = self.currentItem.offset();\r
-                       var op = self.helper.offsetParent().offset();\r
-                       if(self.options.zIndex) ui.helper.css('zIndex', self.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop\r
-\r
-                       //Also animate the placeholder if we have one\r
-                       if(self.placeholder) self.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500);\r
-                       \r
-                       \r
-                       ui.helper.animate({\r
-                               left: cur.left - op.left - self.margins.left,\r
-                               top: cur.top - op.top - self.margins.top\r
-                       }, parseInt(ui.options.revert, 10) || 500, function() {\r
-                               self.currentItem.css('visibility', 'visible');\r
-                               window.setTimeout(function() {\r
-                                       if(self.placeholder) self.placeholder.remove();\r
-                                       self.helper.remove();\r
-                                       if(ui.options._zIndex) ui.helper.css('zIndex', ui.options._zIndex);\r
-                               }, 50);\r
-                       });\r
-               }\r
-       });\r
-\r
+$.ui.plugin.add("sortable", "cursor", {\r
+       start: function(e, ui) {\r
+               var t = $('body');\r
+               if (t.css("cursor")) ui.options._cursor = t.css("cursor");\r
+               t.css("cursor", ui.options.cursor);\r
+       },\r
+       stop: function(e, ui) {\r
+               if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);\r
+       }\r
+});\r
+\r
+$.ui.plugin.add("sortable", "zIndex", {\r
+       start: function(e, ui) {\r
+               var t = ui.helper;\r
+               if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");\r
+               t.css('zIndex', ui.options.zIndex);\r
+       },\r
+       stop: function(e, ui) {\r
+               if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);\r
+       }\r
+});\r
+\r
+$.ui.plugin.add("sortable", "opacity", {\r
+       start: function(e, ui) {\r
+               var t = ui.helper;\r
+               if(t.css("opacity")) ui.options._opacity = t.css("opacity");\r
+               t.css('opacity', ui.options.opacity);\r
+       },\r
+       stop: function(e, ui) {\r
+               if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);\r
+       }\r
+});\r
+\r
+$.ui.plugin.add("sortable", "scroll", {\r
+       start: function(e, ui) {\r
+               var o = ui.options;\r
+               var i = $(this).data("sortable");\r
+               o.scrollSensitivity     = o.scrollSensitivity || 20;\r
+               o.scrollSpeed           = o.scrollSpeed || 20;\r
        \r
-       $.ui.plugin.add("sortable", "containment", {\r
-               start: function(e, ui) {\r
-\r
-                       var o = ui.options;\r
-                       if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return;\r
-                       if(!o._containment) o._containment = o.containment;\r
-\r
-                       if(o._containment == 'parent') o._containment = this[0].parentNode;\r
-                       if(o._containment == 'sortable') o._containment = this[0];\r
-                       if(o._containment == 'document') {\r
-                               o.containment = [\r
-                                       0,\r
-                                       0,\r
-                                       $(document).width(),\r
-                                       ($(document).height() || document.body.parentNode.scrollHeight)\r
-                               ];\r
-                       } else { //I'm a node, so compute top/left/right/bottom\r
-\r
-                               var ce = $(o._containment);\r
-                               var co = ce.offset();\r
-\r
-                               o.containment = [\r
-                                       co.left,\r
-                                       co.top,\r
-                                       co.left+(ce.outerWidth() || ce[0].scrollWidth),\r
-                                       co.top+(ce.outerHeight() || ce[0].scrollHeight)\r
-                               ];\r
-                       }\r
-\r
-               },\r
-               sort: function(e, ui) {\r
-\r
-                       var o = ui.options;\r
-                       var h = ui.helper;\r
-                       var c = o.containment;\r
-                       var self = this;\r
-                       var borderLeft = (parseInt(self.offsetParent.css("borderLeftWidth"), 10) || 0);\r
-                       var borderRight = (parseInt(self.offsetParent.css("borderRightWidth"), 10) || 0);\r
-                       var borderTop = (parseInt(self.offsetParent.css("borderTopWidth"), 10) || 0);\r
-                       var borderBottom = (parseInt(self.offsetParent.css("borderBottomWidth"), 10) || 0);\r
-                       \r
-                       if(c.constructor == Array) {\r
-                               if((self.position.absolute.left < c[0])) self.position.current.left = c[0] - self.offsets.parent.left - self.margins.left;\r
-                               if((self.position.absolute.top < c[1])) self.position.current.top = c[1] - self.offsets.parent.top - self.margins.top;\r
-                               if(self.position.absolute.left - c[2] + self.helperProportions.width >= 0) self.position.current.left = c[2] - self.offsets.parent.left - self.helperProportions.width - self.margins.left - borderLeft - borderRight;\r
-                               if(self.position.absolute.top - c[3] + self.helperProportions.height >= 0) self.position.current.top = c[3] - self.offsets.parent.top - self.helperProportions.height - self.margins.top - borderTop - borderBottom;\r
-                       } else {\r
-                               if((ui.position.left < c.left)) self.position.current.left = c.left;\r
-                               if((ui.position.top < c.top)) self.position.current.top = c.top;\r
-                               if(ui.position.left - self.offsetParent.innerWidth() + self.helperProportions.width + c.right + borderLeft + borderRight >= 0) self.position.current.left = self.offsetParent.innerWidth() - self.helperProportions.width - c.right - borderLeft - borderRight;\r
-                               if(ui.position.top - self.offsetParent.innerHeight() + self.helperProportions.height + c.bottom + borderTop + borderBottom >= 0) self.position.current.top = self.offsetParent.innerHeight() - self.helperProportions.height - c.bottom - borderTop - borderBottom;\r
-                       }\r
-\r
+               i.overflowY = function(el) {\r
+                       do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);\r
+                       return $(document);\r
+               }(i.currentItem);\r
+               i.overflowX = function(el) {\r
+                       do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);\r
+                       return $(document);\r
+               }(i.currentItem);\r
+               \r
+               if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') i.overflowYOffset = i.overflowY.offset();\r
+               if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') i.overflowXOffset = i.overflowX.offset();\r
+               \r
+       },\r
+       sort: function(e, ui) {\r
+               \r
+               var o = ui.options;\r
+               var i = $(this).data("sortable");\r
+               \r
+               if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {\r
+                       if((i.overflowYOffset.top + i.overflowY[0].offsetHeight) - e.pageY < o.scrollSensitivity)\r
+                               i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;\r
+                       if(e.pageY - i.overflowYOffset.top < o.scrollSensitivity)\r
+                               i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;\r
+               } else {\r
+                       if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)\r
+                               $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\r
+                       if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)\r
+                               $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\r
                }\r
-       });\r
-\r
-       $.ui.plugin.add("sortable", "axis", {\r
-               sort: function(e, ui) {\r
-                       var o = ui.options, inst = this.data("sortable");\r
-                       if(o.constraint) o.axis = o.constraint; //Legacy check\r
-                       o.axis == 'x' ? inst.position.current.top = inst.originalPosition.top : inst.position.current.left = inst.originalPosition.left;\r
+               \r
+               if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {\r
+                       if((i.overflowXOffset.left + i.overflowX[0].offsetWidth) - e.pageX < o.scrollSensitivity)\r
+                               i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;\r
+                       if(e.pageX - i.overflowXOffset.left < o.scrollSensitivity)\r
+                               i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;\r
+               } else {\r
+                       if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)\r
+                               $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\r
+                       if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)\r
+                               $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\r
                }\r
-       });\r
-\r
-       $.ui.plugin.add("sortable", "scroll", {\r
-               start: function(e, ui) {\r
-                       var o = ui.options, inst = this.data("sortable");\r
-                       o.scrollSensitivity     = o.scrollSensitivity || 20;\r
-                       o.scrollSpeed           = o.scrollSpeed || 20;\r
-\r
-                       inst.overflowY = function(el) {\r
-                               do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);\r
-                               return $(document);\r
-                       }(this);\r
-                       inst.overflowX = function(el) {\r
-                               do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);\r
-                               return $(document);\r
-                       }(this);\r
-                       \r
-                       if(inst.overflowY[0] != document && inst.overflowY[0].tagName != 'HTML') inst.overflowYstart = inst.overflowY[0].scrollTop;\r
-                       if(inst.overflowX[0] != document && inst.overflowX[0].tagName != 'HTML') inst.overflowXstart = inst.overflowX[0].scrollLeft;\r
-                       \r
-               },\r
-               sort: function(e, ui) {\r
-                       \r
-                       var o = ui.options;\r
-                       var i = this.data("sortable");\r
-\r
-                       if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {\r
-                               if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)\r
-                                       i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;\r
-                               if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)\r
-                                       i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;                            \r
-                       } else {\r
-                               //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>');\r
-                               if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)\r
-                                       $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\r
-                               if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)\r
-                                       $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\r
-                       }\r
-                       \r
-                       if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {\r
-                               if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)\r
-                                       i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;\r
-                               if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)\r
-                                       i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;                          \r
-                       } else {\r
-                               if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)\r
-                                       $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\r
-                               if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)\r
-                                       $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\r
-                       }\r
-                       \r
-                       i.offset = {\r
-                               left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0),\r
-                               top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0)\r
-                       };\r
+               \r
+       }\r
+});\r
 \r
-               }\r
-       });\r
 \r
 })(jQuery);\r