diff options
author | Richard Worth <rdworth@gmail.com> | 2008-11-21 04:01:33 +0000 |
---|---|---|
committer | Richard Worth <rdworth@gmail.com> | 2008-11-21 04:01:33 +0000 |
commit | fb94a4e34e25941443bdd7c52c41844e29f2db9f (patch) | |
tree | b54be3ceb6429136d862abc5cd9dd8310a4fc25b /ui | |
parent | 2192c024e2b8dd4b3a27170400107400dc5a72b4 (diff) | |
download | jquery-ui-fb94a4e34e25941443bdd7c52c41844e29f2db9f.tar.gz jquery-ui-fb94a4e34e25941443bdd7c52c41844e29f2db9f.zip |
draggable, droppable, resizable, selectable, sortable: formatting changes - moved some things around for consistency.
_init and destroy at the top, then _mouse methods. plugins, ui last. Sorted defaults and plugins alphabetically.
Diffstat (limited to 'ui')
-rw-r--r-- | ui/ui.draggable.js | 425 | ||||
-rw-r--r-- | ui/ui.droppable.js | 77 | ||||
-rw-r--r-- | ui/ui.resizable.js | 284 | ||||
-rw-r--r-- | ui/ui.selectable.js | 27 | ||||
-rw-r--r-- | ui/ui.sortable.js | 605 |
5 files changed, 731 insertions, 687 deletions
diff --git a/ui/ui.draggable.js b/ui/ui.draggable.js index ffa7dad08..30824552b 100644 --- a/ui/ui.draggable.js +++ b/ui/ui.draggable.js @@ -14,35 +14,6 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { - getHandle: function(event) { - - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; - $(this.options.handle, this.element) - .find("*") - .andSelf() - .each(function() { - if(this == event.target) handle = true; - }); - - return handle; - - }, - - createHelper: function(event) { - - var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); - - if(!helper.parents('body').length) - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); - - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) - helper.css("position", "absolute"); - - return helper; - - }, - _init: function() { if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) @@ -55,6 +26,12 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { }, + destroy: function() { + if(!this.element.data('draggable')) return; + this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled'); + this._mouseDestroy(); + }, + _mouseCapture: function(event) { var o = this.options; @@ -163,6 +140,72 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { return true; }, + _mouseDrag: function(event) { + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + //Call plugins and callbacks and use the resulting position if something is returned + this.position = this._propagate("drag", event) || this.position; + + if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; + if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; + if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); + + return false; + }, + + _mouseStop: function(event) { + + //If we are using droppables, inform the manager about the drop + var dropped = false; + if ($.ui.ddmanager && !this.options.dropBehaviour) + var dropped = $.ui.ddmanager.drop(this, event); + + if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { + var self = this; + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + self._propagate("stop", event); + self._clear(); + }); + } else { + this._propagate("stop", event); + this._clear(); + } + + return false; + }, + + getHandle: function(event) { + + var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; + $(this.options.handle, this.element) + .find("*") + .andSelf() + .each(function() { + if(this == event.target) handle = true; + }); + + return handle; + + }, + + createHelper: function(event) { + + var o = this.options; + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element); + + if(!helper.parents('body').length) + helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); + + if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) + helper.css("position", "absolute"); + + return helper; + + }, + cacheScrollParents: function() { this.scrollTopParent = function(el) { @@ -240,6 +283,7 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { ) }; }, + _generatePosition: function(event) { var o = this.options; @@ -285,41 +329,7 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { return position; }, - _mouseDrag: function(event) { - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - //Call plugins and callbacks and use the resulting position if something is returned - this.position = this._propagate("drag", event) || this.position; - - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - return false; - }, - _mouseStop: function(event) { - - //If we are using droppables, inform the manager about the drop - var dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) - var dropped = $.ui.ddmanager.drop(this, event); - - if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - var self = this; - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - self._propagate("stop", event); - self._clear(); - }); - } else { - this._propagate("stop", event); - this._clear(); - } - - return false; - }, _clear: function() { this.helper.removeClass("ui-draggable-dragging"); if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); @@ -329,7 +339,15 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { }, // From now on bulk stuff - mainly helpers + + _propagate: function(n, event) { + $.ui.plugin.call(this, n, [event, this.uiHash()]); + if(n == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins + return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [event, this.uiHash()], this.options[n]); + }, + plugins: {}, + uiHash: function(event) { return { helper: this.helper, @@ -337,17 +355,8 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { absolutePosition: this.positionAbs, options: this.options }; - }, - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.uiHash()]); - if(n == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins - return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [event, this.uiHash()], this.options[n]); - }, - destroy: function() { - if(!this.element.data('draggable')) return; - this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled'); - this._mouseDestroy(); } + })); $.extend($.ui.draggable, { @@ -355,14 +364,15 @@ $.extend($.ui.draggable, { defaults: { appendTo: "parent", axis: false, - handle: false, cancel: ":input", connectToSortable: false, containment: false, + cssNamespace: "ui", cursor: "default", delay: 0, distance: 1, grid: false, + handle: false, helper: "original", iframeFix: false, opacity: 1, @@ -376,41 +386,130 @@ $.extend($.ui.draggable, { snap: false, snapMode: "both", snapTolerance: 20, - stack: false, - cssNamespace: "ui" + stack: false } }); -$.ui.plugin.add("draggable", "cursor", { +$.ui.plugin.add("draggable", "connectToSortable", { start: function(event, ui) { - var t = $('body'); - if (t.css("cursor")) ui.options._cursor = t.css("cursor"); - t.css("cursor", ui.options.cursor); + + var inst = $(this).data("draggable"); + inst.sortables = []; + $(ui.options.connectToSortable).each(function() { + if($.data(this, 'sortable')) { + var sortable = $.data(this, 'sortable'); + inst.sortables.push({ + instance: sortable, + shouldRevert: sortable.options.revert + }); + sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache + sortable._propagate("activate", event, inst); + } + }); + }, stop: function(event, ui) { - if (ui.options._cursor) $('body').css("cursor", ui.options._cursor); - } -}); -$.ui.plugin.add("draggable", "zIndex", { - start: function(event, ui) { - var t = $(ui.helper); - if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex"); - t.css('zIndex', ui.options.zIndex); + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper + var inst = $(this).data("draggable"); + + $.each(inst.sortables, function() { + if(this.instance.isOver) { + this.instance.isOver = 0; + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) + if(this.shouldRevert) this.instance.options.revert = true; //revert here + this.instance._mouseStop(event); + + //Also propagate receive event, since the sortable is actually receiving a element + this.instance.element.triggerHandler("sortreceive", [event, $.extend(this.instance._ui(), { sender: inst.element })], this.instance.options["receive"]); + + this.instance.options.helper = this.instance.options._helper; + } else { + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance + this.instance._propagate("deactivate", event, inst); + } + + }); + }, - stop: function(event, ui) { - if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex); + drag: function(event, ui) { + + var inst = $(this).data("draggable"), self = this; + + var checkPos = function(o) { + var dyClick = this.offset.click.top, dxClick = this.offset.click.left; + var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; + var itemHeight = o.height, itemWidth = o.width; + var itemTop = o.top, itemLeft = o.left; + + return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); + }; + + $.each(inst.sortables, function(i) { + + if(checkPos.call(inst, this.instance.containerCache)) { + + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once + if(!this.instance.isOver) { + this.instance.isOver = 1; + //Now we fake the start of dragging for the sortable instance, + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem + //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) + this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it + this.instance.options.helper = function() { return ui.helper[0]; }; + + event.target = this.instance.currentItem[0]; + this.instance._mouseCapture(event, true); + this.instance._mouseStart(event, true, true); + + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes + this.instance.offset.click.top = inst.offset.click.top; + this.instance.offset.click.left = inst.offset.click.left; + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; + + inst._propagate("toSortable", event); + + } + + //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable + if(this.instance.currentItem) this.instance._mouseDrag(event); + + } else { + + //If it doesn't intersect with the sortable, and it intersected before, + //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval + if(this.instance.isOver) { + this.instance.isOver = 0; + this.instance.cancelHelperRemoval = true; + this.instance.options.revert = false; //No revert here + this.instance._mouseStop(event, true); + this.instance.options.helper = this.instance.options._helper; + + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size + this.instance.currentItem.remove(); + if(this.instance.placeholder) this.instance.placeholder.remove(); + + inst._propagate("fromSortable", event); + } + + }; + + }); + } }); -$.ui.plugin.add("draggable", "opacity", { +$.ui.plugin.add("draggable", "cursor", { start: function(event, ui) { - var t = $(ui.helper); - if(t.css("opacity")) ui.options._opacity = t.css("opacity"); - t.css('opacity', ui.options.opacity); + var t = $('body'); + if (t.css("cursor")) ui.options._cursor = t.css("cursor"); + t.css("cursor", ui.options.cursor); }, stop: function(event, ui) { - if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity); + if (ui.options._cursor) $('body').css("cursor", ui.options._cursor); } }); @@ -431,6 +530,17 @@ $.ui.plugin.add("draggable", "iframeFix", { } }); +$.ui.plugin.add("draggable", "opacity", { + start: function(event, ui) { + var t = $(ui.helper); + if(t.css("opacity")) ui.options._opacity = t.css("opacity"); + t.css('opacity', ui.options.opacity); + }, + stop: function(event, ui) { + if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity); + } +}); + $.ui.plugin.add("draggable", "scroll", { start: function(event, ui) { var o = ui.options; @@ -553,120 +663,8 @@ $.ui.plugin.add("draggable", "snap", { } }); -$.ui.plugin.add("draggable", "connectToSortable", { - start: function(event,ui) { - - var inst = $(this).data("draggable"); - inst.sortables = []; - $(ui.options.connectToSortable).each(function() { - if($.data(this, 'sortable')) { - var sortable = $.data(this, 'sortable'); - inst.sortables.push({ - instance: sortable, - shouldRevert: sortable.options.revert - }); - sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache - sortable._propagate("activate", event, inst); - } - }); - - }, - stop: function(event,ui) { - - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper - var inst = $(this).data("draggable"); - - $.each(inst.sortables, function() { - if(this.instance.isOver) { - this.instance.isOver = 0; - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) - if(this.shouldRevert) this.instance.options.revert = true; //revert here - this.instance._mouseStop(event); - - //Also propagate receive event, since the sortable is actually receiving a element - this.instance.element.triggerHandler("sortreceive", [event, $.extend(this.instance._ui(), { sender: inst.element })], this.instance.options["receive"]); - - this.instance.options.helper = this.instance.options._helper; - } else { - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance - this.instance._propagate("deactivate", event, inst); - } - - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("draggable"), self = this; - - var checkPos = function(o) { - var dyClick = this.offset.click.top, dxClick = this.offset.click.left; - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; - var itemHeight = o.height, itemWidth = o.width; - var itemTop = o.top, itemLeft = o.left; - - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); - }; - - $.each(inst.sortables, function(i) { - - if(checkPos.call(inst, this.instance.containerCache)) { - - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if(!this.instance.isOver) { - this.instance.isOver = 1; - //Now we fake the start of dragging for the sortable instance, - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true); - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; - - event.target = this.instance.currentItem[0]; - this.instance._mouseCapture(event, true); - this.instance._mouseStart(event, true, true); - - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes - this.instance.offset.click.top = inst.offset.click.top; - this.instance.offset.click.left = inst.offset.click.left; - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; - - inst._propagate("toSortable", event); - - } - - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if(this.instance.currentItem) this.instance._mouseDrag(event); - - } else { - - //If it doesn't intersect with the sortable, and it intersected before, - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval - if(this.instance.isOver) { - this.instance.isOver = 0; - this.instance.cancelHelperRemoval = true; - this.instance.options.revert = false; //No revert here - this.instance._mouseStop(event, true); - this.instance.options.helper = this.instance.options._helper; - - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size - this.instance.currentItem.remove(); - if(this.instance.placeholder) this.instance.placeholder.remove(); - - inst._propagate("fromSortable", event); - } - - }; - - }); - - } -}); - $.ui.plugin.add("draggable", "stack", { - start: function(event,ui) { + start: function(event, ui) { var group = $.makeArray($(ui.options.stack.group)).sort(function(a,b) { return (parseInt($(a).css("zIndex"),10) || ui.options.stack.min) - (parseInt($(b).css("zIndex"),10) || ui.options.stack.min); }); @@ -679,4 +677,15 @@ $.ui.plugin.add("draggable", "stack", { } }); +$.ui.plugin.add("draggable", "zIndex", { + start: function(event, ui) { + var t = $(ui.helper); + if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex"); + t.css('zIndex', ui.options.zIndex); + }, + stop: function(event, ui) { + if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex); + } +}); + })(jQuery); diff --git a/ui/ui.droppable.js b/ui/ui.droppable.js index b3e0299cf..e61883758 100644 --- a/ui/ui.droppable.js +++ b/ui/ui.droppable.js @@ -15,18 +15,6 @@ $.widget("ui.droppable", { - _setData: function(key, value) { - - if(key == 'accept') { - this.options.accept = value && $.isFunction(value) ? value : function(d) { - return d.is(accept); - }; - } else { - $.widget.prototype._setData.apply(this, arguments); - } - - }, - _init: function() { var o = this.options, accept = o.accept; @@ -46,17 +34,7 @@ $.widget("ui.droppable", { (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable")); }, - plugins: {}, - ui: function(c) { - return { - draggable: (c.currentItem || c.element), - helper: c.helper, - position: c.position, - absolutePosition: c.positionAbs, - options: this.options, - element: this.element - }; - }, + destroy: function() { var drop = $.ui.ddmanager.droppables[this.options.scope]; for ( var i = 0; i < drop.length; i++ ) @@ -68,6 +46,35 @@ $.widget("ui.droppable", { .removeData("droppable") .unbind(".droppable"); }, + + _setData: function(key, value) { + + if(key == 'accept') { + this.options.accept = value && $.isFunction(value) ? value : function(d) { + return d.is(accept); + }; + } else { + $.widget.prototype._setData.apply(this, arguments); + } + + }, + + _activate: function(event) { + + var draggable = $.ui.ddmanager.current; + $.ui.plugin.call(this, 'activate', [event, this.ui(draggable)]); + if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate); + + }, + + _deactivate: function(event) { + + var draggable = $.ui.ddmanager.current; + $.ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]); + if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate); + + }, + _over: function(event) { var draggable = $.ui.ddmanager.current; @@ -79,6 +86,7 @@ $.widget("ui.droppable", { } }, + _out: function(event) { var draggable = $.ui.ddmanager.current; @@ -90,6 +98,7 @@ $.widget("ui.droppable", { } }, + _drop: function(event,custom) { var draggable = custom || $.ui.ddmanager.current; @@ -113,20 +122,20 @@ $.widget("ui.droppable", { return false; }, - _activate: function(event) { - - var draggable = $.ui.ddmanager.current; - $.ui.plugin.call(this, 'activate', [event, this.ui(draggable)]); - if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate); - - }, - _deactivate: function(event) { - var draggable = $.ui.ddmanager.current; - $.ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]); - if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate); + plugins: {}, + ui: function(c) { + return { + draggable: (c.currentItem || c.element), + helper: c.helper, + position: c.position, + absolutePosition: c.positionAbs, + options: this.options, + element: this.element + }; } + }); $.extend($.ui.droppable, { diff --git a/ui/ui.resizable.js b/ui/ui.resizable.js index ada711340..e9f2782de 100644 --- a/ui/ui.resizable.js +++ b/ui/ui.resizable.js @@ -13,6 +13,7 @@ (function($) { $.widget("ui.resizable", $.extend({}, $.ui.mouse, { + _init: function() { var self = this, o = this.options; @@ -214,23 +215,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { this._mouseInit(); }, - plugins: {}, - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - options: this.options, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - }, - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.ui()]); - if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]); - }, + destroy: function() { var el = this.element, wrapped = el.children(".ui-resizable").get(0); @@ -322,6 +307,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { this._propagate("start", event); return true; }, + _mouseDrag: function(event) { //Increase performance, avoid regex @@ -358,6 +344,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { return false; }, + _mouseStop: function(event) { this.options.resizing = false; @@ -387,6 +374,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { return false; }, + _updateCache: function(data) { var o = this.options; this.offset = this.helper.offset(); @@ -395,6 +383,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { if (data.height) this.size.height = data.height; if (data.width) this.size.width = data.width; }, + _updateRatio: function(data, event) { var o = this.options, cpos = this.position, csize = this.size, a = this.axis; @@ -413,6 +402,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { return data; }, + _respectSize: function(data, event) { var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis, @@ -439,6 +429,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { return data; }, + _proportionallyResize: function() { var o = this.options; if (!o.proportionallyResize) return; @@ -458,6 +449,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px" }); }, + _renderProxy: function() { var el = this.element, o = this.options; this.elementOffset = el.offset(); @@ -487,6 +479,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { this.helper = el; } }, + _change: { e: function(event, dx, dy) { return { width: this.originalSize.width + dx }; @@ -514,7 +507,28 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { nw: function(event, dx, dy) { return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); } + }, + + _propagate: function(n, event) { + $.ui.plugin.call(this, n, [event, this.ui()]); + if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]); + }, + + plugins: {}, + + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + options: this.options, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; } + })); $.extend($.ui.resizable, { @@ -549,6 +563,100 @@ $.extend($.ui.resizable, { * Resizable Extensions */ +$.ui.plugin.add("resizable", "alsoResize", { + + start: function(event, ui) { + var o = ui.options, self = $(this).data("resizable"), + + _store = function(exp) { + $(exp).each(function() { + $(this).data("resizable-alsoresize", { + width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), + left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) + }); + }); + }; + + if (typeof(o.alsoResize) == 'object') { + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } + else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } + }else{ + _store(o.alsoResize); + } + }, + + resize: function(event, ui){ + var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition; + + var delta = { + height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, + top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 + }, + + _alsoResize = function(exp, c) { + $(exp).each(function() { + var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; + + $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { + var sum = (start[prop]||0) + (delta[prop]||0); + if (sum && sum >= 0) + style[prop] = sum || null; + }); + $(this).css(style); + }); + }; + + if (typeof(o.alsoResize) == 'object') { + $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); + }else{ + _alsoResize(o.alsoResize); + } + }, + + stop: function(event, ui){ + $(this).removeData("resizable-alsoresize-start"); + } +}); + +$.ui.plugin.add("resizable", "animate", { + + stop: function(event, ui) { + var o = ui.options, self = $(this).data("resizable"); + + var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), + soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, + soffsetw = ista ? 0 : self.sizeDiff.width; + + var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; + + self.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(self.element.css('width'), 10), + height: parseInt(self.element.css('height'), 10), + top: parseInt(self.element.css('top'), 10), + left: parseInt(self.element.css('left'), 10) + }; + + if (pr) pr.css({ width: data.width, height: data.height }); + + // propagating resize, and updating values for each animation step + self._updateCache(data); + self._propagate("animate", event); + + } + } + ); + } + +}); + $.ui.plugin.add("resizable", "containment", { start: function(event, ui) { @@ -632,76 +740,6 @@ $.ui.plugin.add("resizable", "containment", { } }); -$.ui.plugin.add("resizable", "grid", { - - resize: function(event, ui) { - var o = ui.options, self = $(this).data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; - var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); - - if (/^(se|s|e)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - } - else if (/^(ne)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.top = op.top - oy; - } - else if (/^(sw)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.left = op.left - ox; - } - else { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.top = op.top - oy; - self.position.left = op.left - ox; - } - } - -}); - -$.ui.plugin.add("resizable", "animate", { - - stop: function(event, ui) { - var o = ui.options, self = $(this).data("resizable"); - - var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), - soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, - soffsetw = ista ? 0 : self.sizeDiff.width; - - var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; - - self.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseInt(self.element.css('width'), 10), - height: parseInt(self.element.css('height'), 10), - top: parseInt(self.element.css('top'), 10), - left: parseInt(self.element.css('left'), 10) - }; - - if (pr) pr.css({ width: data.width, height: data.height }); - - // propagating resize, and updating values for each animation step - self._updateCache(data); - self._propagate("animate", event); - - } - } - ); - } - -}); - $.ui.plugin.add("resizable", "ghost", { start: function(event, ui) { @@ -733,59 +771,35 @@ $.ui.plugin.add("resizable", "ghost", { }); -$.ui.plugin.add("resizable", "alsoResize", { - - start: function(event, ui) { - var o = ui.options, self = $(this).data("resizable"), +$.ui.plugin.add("resizable", "grid", { - _store = function(exp) { - $(exp).each(function() { - $(this).data("resizable-alsoresize", { - width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), - left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10) - }); - }); - }; + resize: function(event, ui) { + var o = ui.options, self = $(this).data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; + o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; + var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); - if (typeof(o.alsoResize) == 'object') { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); } - }else{ - _store(o.alsoResize); + if (/^(se|s|e)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; } - }, - - resize: function(event, ui){ - var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition; - - var delta = { - height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, - top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 - }, - - _alsoResize = function(exp, c) { - $(exp).each(function() { - var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left']; - - $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) { - var sum = (start[prop]||0) + (delta[prop]||0); - if (sum && sum >= 0) - style[prop] = sum || null; - }); - $(this).css(style); - }); - }; - - if (typeof(o.alsoResize) == 'object') { - $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); - }else{ - _alsoResize(o.alsoResize); + else if (/^(ne)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.top = op.top - oy; + } + else if (/^(sw)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.left = op.left - ox; + } + else { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.top = op.top - oy; + self.position.left = op.left - ox; } - }, - - stop: function(event, ui){ - $(this).removeData("resizable-alsoresize-start"); } + }); })(jQuery); diff --git a/ui/ui.selectable.js b/ui/ui.selectable.js index 631289fd3..6c20692e8 100644 --- a/ui/ui.selectable.js +++ b/ui/ui.selectable.js @@ -13,6 +13,7 @@ (function($) { $.widget("ui.selectable", $.extend({}, $.ui.mouse, { + _init: function() { var self = this; @@ -51,13 +52,7 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { .css({border:'1px dotted black'}) .addClass("ui-selectable-helper"); }, - toggle: function() { - if(this.options.disabled){ - this.enable(); - } else { - this.disable(); - } - }, + destroy: function() { this.element .removeClass("ui-selectable ui-selectable-disabled") @@ -65,6 +60,7 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { .unbind(".selectable"); this._mouseDestroy(); }, + _mouseStart: function(event) { var self = this; @@ -121,6 +117,7 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { }); return this.options.keyboard ? !isSelectee : true; }, + _mouseDrag: function(event) { var self = this; this.dragged = true; @@ -210,6 +207,7 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { return false; }, + _mouseStop: function(event) { var self = this; @@ -248,17 +246,26 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { this.helper.remove(); return false; + }, + + toggle: function() { + if(this.options.disabled){ + this.enable(); + } else { + this.disable(); + } } + })); $.extend($.ui.selectable, { version: "@VERSION", defaults: { - distance: 1, - delay: 0, - cancel: ":input", appendTo: 'body', autoRefresh: true, + cancel: ":input", + delay: 0, + distance: 1, filter: '*', tolerance: 'touch' } diff --git a/ui/ui.sortable.js b/ui/ui.sortable.js index 9a39d165a..3986de235 100644 --- a/ui/ui.sortable.js +++ b/ui/ui.sortable.js @@ -13,6 +13,7 @@ (function($) { $.widget("ui.sortable", $.extend({}, $.ui.mouse, { + _init: function() { var o = this.options; @@ -32,17 +33,262 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { this._mouseInit(); }, - plugins: {}, - _ui: function(inst) { - var self = inst || this; - return { - helper: self.helper, - placeholder: self.placeholder || $([]), - position: self.position, - absolutePosition: self.positionAbs, - item: self.currentItem, - sender: inst ? inst.element : null + + destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled") + .removeData("sortable") + .unbind(".sortable"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) + this.items[i].item.removeData("sortable-item"); + }, + + _mouseCapture: function(event, overrideHandle) { + + if (this.reverting) { + return false; + } + + if(this.options.disabled || this.options.type == 'static') return false; + + //We have to refresh the items data once first + this._refreshItems(event); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { + if($.data(this, 'sortable-item') == self) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target); + + if(!currentItem) return false; + if(this.options.handle && !overrideHandle) { + var validHandle = false; + + $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); + if(!validHandle) return false; + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; + + }, + + _mouseStart: function(event, overrideHandle, noActivation) { + + var o = this.options; + this.currentContainer = this; + + //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + this.refreshPositions(); + + //Create and append the visible helper + this.helper = this.createHelper(event); + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + this.margins = { //Cache the margins + left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), + top: (parseInt(this.currentItem.css("marginTop"),10) || 0) }; + + this.offset = this.currentItem.offset(); //The element's absolute position on the page + this.offset = { //Substract the margins from the element's absolute offset + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + this.offset.click = { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }; + + this.offsetParent = this.helper.offsetParent(); //Get the offsetParent and cache its position + var po = this.offsetParent.offset(); + + this.offsetParentBorders = { + top: (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + this.offset.parent = { //Store its position plus border + top: po.top + this.offsetParentBorders.top, + left: po.left + this.offsetParentBorders.left + }; + + this.originalPosition = this._generatePosition(event); //Generate the original position + this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; //Cache the former DOM position + + //If o.placeholder is used, create a new element at the given position with the class + this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size + + if(o.helper == "original") { + this._storedCSS = { position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left"), clear: this.currentItem.css("clear") }; + } else { + this.currentItem.hide(); //Hide the original, won't cause anything bad this way + } + + //Position it absolutely and add a helper class + this.helper + .css({ position: 'absolute', clear: 'both' }) + .addClass('ui-sortable-helper'); + + //Create the placeholder + this._createPlaceholder(); + + //Call plugins and callbacks + this._propagate("start", event); + + //Recache the helper size + if(!this._preserveHelperProportions) + this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; + + if(o.cursorAt) { + if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left; + if(o.cursorAt.right != undefined) this.offset.click.left = this.helperProportions.width - o.cursorAt.right; + if(o.cursorAt.top != undefined) this.offset.click.top = o.cursorAt.top; + if(o.cursorAt.bottom != undefined) this.offset.click.top = this.helperProportions.height - o.cursorAt.bottom; + } + + /* + * - Position constraining - + * Here we prepare position constraining like grid and containment. + */ + + if(o.containment) { + if(o.containment == 'parent') o.containment = this.helper[0].parentNode; + if(o.containment == 'document' || o.containment == 'window') this.containment = [ + 0 - this.offset.parent.left, + 0 - this.offset.parent.top, + $(o.containment == 'document' ? document : window).width() - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0), + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0) + ]; + + if(!(/^(document|window|parent)$/).test(o.containment)) { + var ce = $(o.containment)[0]; + var co = $(o.containment).offset(); + var over = ($(ce).css("overflow") != 'hidden'); + + this.containment = [ + co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left, + co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top, + co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0), + co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0) + ]; + } + } + + //Post 'activate' events to possible containers + if(!noActivation) { + for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); } + } + + //Prepare possible droppables + if($.ui.ddmanager) + $.ui.ddmanager.current = this; + + if ($.ui.ddmanager && !o.dropBehaviour) + $.ui.ddmanager.prepareOffsets(this, event); + + this.dragging = true; + + this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + return true; + + }, + + _mouseDrag: function(event) { + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Call the internal plugins + $.ui.plugin.call(this, "sort", [event, this._ui()]); + + //Regenerate the absolute position used for position checks + this.positionAbs = this._convertPositionTo("absolute"); + + //Set the helper's position + if (this.helper) { + this.helper[0].style.left = this.position.left+'px'; + this.helper[0].style.top = this.position.top+'px'; + } + //Rearrange + for (var i = this.items.length - 1; i >= 0; i--) { + + var intersection = this._intersectsWithEdge(this.items[i]); + + if (!intersection) continue; + + var item = this.items[i].item[0]; + + if(item != this.currentItem[0] //cannot intersect with itself + && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != item //no useless actions that have been done before + && !$.ui.contains(this.placeholder[0], item) //no action if the item moved is the parent of the item checked + && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], item) : true) + ) { + + this.direction = intersection == 1 ? "down" : "up"; + this.options.sortIndicator.call(this, event, this.items[i]); + this._propagate("change", event); //Call plugins and callbacks + break; + } + } + + //Post events to containers + this._contactContainers(event); + + //Interconnect with droppables + if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); + + //Call callbacks + this.element.triggerHandler("sort", [event, this._ui()], this.options["sort"]); + + this.lastPositionAbs = this.positionAbs; + + return false; + + }, + + _mouseStop: function(event, noPropagation) { + + if(!event) return; + + //If we are using droppables, inform the manager about the drop + if ($.ui.ddmanager && !this.options.dropBehaviour) + $.ui.ddmanager.drop(this, event); + + if(this.options.revert) { + var self = this; + var cur = self.placeholder.offset(); + + self.reverting = true; + + $(this.helper).animate({ + left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), + top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) + }, parseInt(this.options.revert, 10) || 500, function() { + self._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + }, cancel: function() { @@ -88,12 +334,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, - _propagate: function(n, event, inst, noPropagation) { - $.ui.plugin.call(this, n, [event, this._ui(inst)]); - var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true; - if(dontCancel === false) this.cancel(); - }, - serialize: function(o) { var items = this._getItemsAsjQuery(o && o.connected); @@ -342,17 +582,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, - destroy: function() { - this.element - .removeClass("ui-sortable ui-sortable-disabled") - .removeData("sortable") - .unbind(".sortable"); - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) - this.items[i].item.removeData("sortable-item"); - }, - _createPlaceholder: function(that) { var self = that || this, o = self.options; @@ -438,40 +667,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }; }, - _mouseCapture: function(event, overrideHandle) { - - if (this.reverting) { - return false; - } - - if(this.options.disabled || this.options.type == 'static') return false; - - //We have to refresh the items data once first - this._refreshItems(event); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { - if($.data(this, 'sortable-item') == self) { - currentItem = $(this); - return false; - } - }); - if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target); - - if(!currentItem) return false; - if(this.options.handle && !overrideHandle) { - var validHandle = false; - - $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); - if(!validHandle) return false; - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - createHelper: function(event) { var o = this.options; @@ -484,131 +679,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, - _mouseStart: function(event, overrideHandle, noActivation) { - - var o = this.options; - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture - this.refreshPositions(); - - //Create and append the visible helper - this.helper = this.createHelper(event); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - this.margins = { //Cache the margins - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - - this.offset = this.currentItem.offset(); //The element's absolute position on the page - this.offset = { //Substract the margins from the element's absolute offset - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - this.offset.click = { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }; - - this.offsetParent = this.helper.offsetParent(); //Get the offsetParent and cache its position - var po = this.offsetParent.offset(); - - this.offsetParentBorders = { - top: (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - this.offset.parent = { //Store its position plus border - top: po.top + this.offsetParentBorders.top, - left: po.left + this.offsetParentBorders.left - }; - - this.originalPosition = this._generatePosition(event); //Generate the original position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; //Cache the former DOM position - - //If o.placeholder is used, create a new element at the given position with the class - this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size - - if(o.helper == "original") { - this._storedCSS = { position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left"), clear: this.currentItem.css("clear") }; - } else { - this.currentItem.hide(); //Hide the original, won't cause anything bad this way - } - - //Position it absolutely and add a helper class - this.helper - .css({ position: 'absolute', clear: 'both' }) - .addClass('ui-sortable-helper'); - - //Create the placeholder - this._createPlaceholder(); - - //Call plugins and callbacks - this._propagate("start", event); - - //Recache the helper size - if(!this._preserveHelperProportions) - this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; - - if(o.cursorAt) { - if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left; - if(o.cursorAt.right != undefined) this.offset.click.left = this.helperProportions.width - o.cursorAt.right; - if(o.cursorAt.top != undefined) this.offset.click.top = o.cursorAt.top; - if(o.cursorAt.bottom != undefined) this.offset.click.top = this.helperProportions.height - o.cursorAt.bottom; - } - - /* - * - Position constraining - - * Here we prepare position constraining like grid and containment. - */ - - if(o.containment) { - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; - if(o.containment == 'document' || o.containment == 'window') this.containment = [ - 0 - this.offset.parent.left, - 0 - this.offset.parent.top, - $(o.containment == 'document' ? document : window).width() - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0), - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0) - ]; - - if(!(/^(document|window|parent)$/).test(o.containment)) { - var ce = $(o.containment)[0]; - var co = $(o.containment).offset(); - var over = ($(ce).css("overflow") != 'hidden'); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0), - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0) - ]; - } - } - - //Post 'activate' events to possible containers - if(!noActivation) { - for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); } - } - - //Prepare possible droppables - if($.ui.ddmanager) - $.ui.ddmanager.current = this; - - if ($.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - - this.dragging = true; - - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; @@ -671,64 +741,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { return position; }, - _mouseDrag: function(event) { - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Call the internal plugins - $.ui.plugin.call(this, "sort", [event, this._ui()]); - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper's position - if (this.helper) { - this.helper[0].style.left = this.position.left+'px'; - this.helper[0].style.top = this.position.top+'px'; - } - //Rearrange - for (var i = this.items.length - 1; i >= 0; i--) { - - var intersection = this._intersectsWithEdge(this.items[i]); - - if (!intersection) continue; - - var item = this.items[i].item[0]; - - if(item != this.currentItem[0] //cannot intersect with itself - && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != item //no useless actions that have been done before - && !$.ui.contains(this.placeholder[0], item) //no action if the item moved is the parent of the item checked - && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], item) : true) - ) { - - this.direction = intersection == 1 ? "down" : "up"; - this.options.sortIndicator.call(this, event, this.items[i]); - this._propagate("change", event); //Call plugins and callbacks - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - //Call callbacks - this.element.triggerHandler("sort", [event, this._ui()], this.options["sort"]); - - this.lastPositionAbs = this.positionAbs; - - return false; - - }, - _rearrange: function(event, i, a, hardRefresh) { a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); @@ -747,34 +759,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, - _mouseStop: function(event, noPropagation) { - - if(!event) return; - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) - $.ui.ddmanager.drop(this, event); - - if(this.options.revert) { - var self = this; - var cur = self.placeholder.offset(); - - self.reverting = true; - - $(this.helper).animate({ - left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), - top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) - }, parseInt(this.options.revert, 10) || 500, function() { - self._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - _clear: function(event, noPropagation) { this.reverting = false; @@ -825,29 +809,50 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { return true; + }, + + _propagate: function(n, event, inst, noPropagation) { + $.ui.plugin.call(this, n, [event, this._ui(inst)]); + var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true; + if(dontCancel === false) this.cancel(); + }, + + plugins: {}, + + _ui: function(inst) { + var self = inst || this; + return { + helper: self.helper, + placeholder: self.placeholder || $([]), + position: self.position, + absolutePosition: self.positionAbs, + item: self.currentItem, + sender: inst ? inst.element : null + }; } + })); $.extend($.ui.sortable, { getter: "serialize toArray", version: "@VERSION", defaults: { - helper: "original", - tolerance: "guess", - distance: 1, + accurate: false, + appendTo: "parent", + cancel: ":input", delay: 0, + distance: 1, + dropOnEmpty: true, + forcePlaceholderSize: false, + helper: "original", + items: '> *', + scope: "default", scroll: true, scrollSensitivity: 20, scrollSpeed: 20, - cancel: ":input", - items: '> *', - zIndex: 1000, - dropOnEmpty: true, - appendTo: "parent", sortIndicator: $.ui.sortable.prototype._rearrange, - scope: "default", - forcePlaceholderSize: false, - accurate: false + tolerance: "guess", + zIndex: 1000 } }); @@ -855,6 +860,14 @@ $.extend($.ui.sortable, { * Sortable Extensions */ +$.ui.plugin.add("sortable", "axis", { + sort: function(event, ui) { + var i = $(this).data('sortable'), o = i.options; + if(o.axis == "y") i.position.left = i.originalPosition.left; + if(o.axis == "x") i.position.top = i.originalPosition.top; + } +}); + $.ui.plugin.add("sortable", "cursor", { start: function(event, ui) { var t = $('body'), i = $(this).data('sortable'); @@ -867,18 +880,6 @@ $.ui.plugin.add("sortable", "cursor", { } }); -$.ui.plugin.add("sortable", "zIndex", { - start: function(event, ui) { - var t = ui.helper, i = $(this).data('sortable'); - if(t.css("zIndex")) i.options._zIndex = t.css("zIndex"); - t.css('zIndex', i.options.zIndex); - }, - beforeStop: function(event, ui) { - var i = $(this).data('sortable'); - if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex); - } -}); - $.ui.plugin.add("sortable", "opacity", { start: function(event, ui) { var t = ui.helper, i = $(this).data('sortable'); @@ -939,11 +940,15 @@ $.ui.plugin.add("sortable", "scroll", { } }); -$.ui.plugin.add("sortable", "axis", { - sort: function(event, ui) { - var i = $(this).data('sortable'), o = i.options; - if(o.axis == "y") i.position.left = i.originalPosition.left; - if(o.axis == "x") i.position.top = i.originalPosition.top; +$.ui.plugin.add("sortable", "zIndex", { + start: function(event, ui) { + var t = ui.helper, i = $(this).data('sortable'); + if(t.css("zIndex")) i.options._zIndex = t.css("zIndex"); + t.css('zIndex', i.options.zIndex); + }, + beforeStop: function(event, ui) { + var i = $(this).data('sortable'); + if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex); } }); |