app/jquery/jquery-ui.sortable.js
changeset 2749 4e2789b8e86d
parent 2420 645f4de26f99
equal deleted inserted replaced
2748:7fbc98f3adde 2749:4e2789b8e86d
     1 /*
     1 /*
     2  * jQuery UI Sortable 1.6
     2  * jQuery UI Sortable 1.7.2
     3  *
     3  *
     4  * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
     4  * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
     5  * Dual licensed under the MIT (MIT-LICENSE.txt)
     5  * Dual licensed under the MIT (MIT-LICENSE.txt)
     6  * and GPL (GPL-LICENSE.txt) licenses.
     6  * and GPL (GPL-LICENSE.txt) licenses.
     7  *
     7  *
     8  * http://docs.jquery.com/UI/Sortables
     8  * http://docs.jquery.com/UI/Sortables
     9  *
     9  *
    78 
    78 
    79 	},
    79 	},
    80 
    80 
    81 	_mouseStart: function(event, overrideHandle, noActivation) {
    81 	_mouseStart: function(event, overrideHandle, noActivation) {
    82 
    82 
    83 		var o = this.options;
    83 		var o = this.options, self = this;
    84 		this.currentContainer = this;
    84 		this.currentContainer = this;
    85 
    85 
    86 		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
    86 		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
    87 		this.refreshPositions();
    87 		this.refreshPositions();
    88 
    88 
   103 		//Get the next scrolling parent
   103 		//Get the next scrolling parent
   104 		this.scrollParent = this.helper.scrollParent();
   104 		this.scrollParent = this.helper.scrollParent();
   105 
   105 
   106 		//The element's absolute position on the page minus margins
   106 		//The element's absolute position on the page minus margins
   107 		this.offset = this.currentItem.offset();
   107 		this.offset = this.currentItem.offset();
   108 
       
   109 		this.offset = {
   108 		this.offset = {
   110 			top: this.offset.top - this.margins.top,
   109 			top: this.offset.top - this.margins.top,
   111 			left: this.offset.left - this.margins.left
   110 			left: this.offset.left - this.margins.left
   112 		};
   111 		};
   113 
   112 
   123 			},
   122 			},
   124 			parent: this._getParentOffset(),
   123 			parent: this._getParentOffset(),
   125 			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
   124 			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
   126 		});
   125 		});
   127 
   126 
       
   127 		//Generate the original position
       
   128 		this.originalPosition = this._generatePosition(event);
       
   129 		this.originalPageX = event.pageX;
       
   130 		this.originalPageY = event.pageY;
       
   131 
   128 		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
   132 		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
   129 		if(o.cursorAt)
   133 		if(o.cursorAt)
   130 			this._adjustOffsetFromHelper(o.cursorAt);
   134 			this._adjustOffsetFromHelper(o.cursorAt);
   131 
   135 
   132 		//Generate the original position
       
   133 		this.originalPosition = this._generatePosition(event);
       
   134 
       
   135 		//Cache the former DOM position
   136 		//Cache the former DOM position
   136 		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
   137 		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
   137 
   138 
   138 		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
   139 		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
   139 		if(this.helper[0] != this.currentItem[0]) {
   140 		if(this.helper[0] != this.currentItem[0]) {
   145 
   146 
   146 		//Set a containment if given in the options
   147 		//Set a containment if given in the options
   147 		if(o.containment)
   148 		if(o.containment)
   148 			this._setContainment();
   149 			this._setContainment();
   149 
   150 
   150 		//Call plugins and callbacks
   151 		if(o.cursor) { // cursor option
   151 		this._propagate("start", event);
   152 			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
       
   153 			$('body').css("cursor", o.cursor);
       
   154 		}
       
   155 
       
   156 		if(o.opacity) { // opacity option
       
   157 			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
       
   158 			this.helper.css("opacity", o.opacity);
       
   159 		}
       
   160 
       
   161 		if(o.zIndex) { // zIndex option
       
   162 			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
       
   163 			this.helper.css("zIndex", o.zIndex);
       
   164 		}
       
   165 
       
   166 		//Prepare scrolling
       
   167 		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
       
   168 			this.overflowOffset = this.scrollParent.offset();
       
   169 
       
   170 		//Call callbacks
       
   171 		this._trigger("start", event, this._uiHash());
   152 
   172 
   153 		//Recache the helper size
   173 		//Recache the helper size
   154 		if(!this._preserveHelperProportions)
   174 		if(!this._preserveHelperProportions)
   155 			this._cacheHelperProportions();
   175 			this._cacheHelperProportions();
   156 
   176 
   157 
   177 
   158 		//Post 'activate' events to possible containers
   178 		//Post 'activate' events to possible containers
   159 		if(!noActivation) {
   179 		if(!noActivation) {
   160 			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); }
   180 			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
   161 		}
   181 		}
   162 
   182 
   163 		//Prepare possible droppables
   183 		//Prepare possible droppables
   164 		if($.ui.ddmanager)
   184 		if($.ui.ddmanager)
   165 			$.ui.ddmanager.current = this;
   185 			$.ui.ddmanager.current = this;
   167 		if ($.ui.ddmanager && !o.dropBehaviour)
   187 		if ($.ui.ddmanager && !o.dropBehaviour)
   168 			$.ui.ddmanager.prepareOffsets(this, event);
   188 			$.ui.ddmanager.prepareOffsets(this, event);
   169 
   189 
   170 		this.dragging = true;
   190 		this.dragging = true;
   171 
   191 
   172 		this.helper.addClass('ui-sortable-helper');
   192 		this.helper.addClass("ui-sortable-helper");
   173 		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
   193 		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
   174 		return true;
   194 		return true;
   175 
   195 
   176 	},
   196 	},
   177 
   197 
   183 
   203 
   184 		if (!this.lastPositionAbs) {
   204 		if (!this.lastPositionAbs) {
   185 			this.lastPositionAbs = this.positionAbs;
   205 			this.lastPositionAbs = this.positionAbs;
   186 		}
   206 		}
   187 
   207 
   188 		//Call the internal plugins
   208 		//Do scrolling
   189 		$.ui.plugin.call(this, "sort", [event, this._ui()]);
   209 		if(this.options.scroll) {
       
   210 			var o = this.options, scrolled = false;
       
   211 			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
       
   212 
       
   213 				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
       
   214 					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
       
   215 				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
       
   216 					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
       
   217 
       
   218 				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
       
   219 					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
       
   220 				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
       
   221 					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
       
   222 
       
   223 			} else {
       
   224 
       
   225 				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
       
   226 					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
       
   227 				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
       
   228 					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
       
   229 
       
   230 				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
       
   231 					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
       
   232 				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
       
   233 					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
       
   234 
       
   235 			}
       
   236 
       
   237 			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
       
   238 				$.ui.ddmanager.prepareOffsets(this, event);
       
   239 		}
   190 
   240 
   191 		//Regenerate the absolute position used for position checks
   241 		//Regenerate the absolute position used for position checks
   192 		this.positionAbs = this._convertPositionTo("absolute");
   242 		this.positionAbs = this._convertPositionTo("absolute");
   193 
   243 
   194 		//Set the helper position
   244 		//Set the helper position
   209 			) {
   259 			) {
   210 
   260 
   211 				this.direction = intersection == 1 ? "down" : "up";
   261 				this.direction = intersection == 1 ? "down" : "up";
   212 
   262 
   213 				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
   263 				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
   214 					this.options.sortIndicator.call(this, event, item);
   264 					this._rearrange(event, item);
   215 				} else {
   265 				} else {
   216 					break;
   266 					break;
   217 				}
   267 				}
   218 
   268 
   219 				this._propagate("change", event); //Call plugins and callbacks
   269 				this._trigger("change", event, this._uiHash());
   220 				break;
   270 				break;
   221 			}
   271 			}
   222 		}
   272 		}
   223 
   273 
   224 		//Post events to containers
   274 		//Post events to containers
   226 
   276 
   227 		//Interconnect with droppables
   277 		//Interconnect with droppables
   228 		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
   278 		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
   229 
   279 
   230 		//Call callbacks
   280 		//Call callbacks
   231 		this._trigger('sort', event, this._ui());
   281 		this._trigger('sort', event, this._uiHash());
   232 
   282 
   233 		this.lastPositionAbs = this.positionAbs;
   283 		this.lastPositionAbs = this.positionAbs;
   234 		return false;
   284 		return false;
   235 
   285 
   236 	},
   286 	},
   263 
   313 
   264 	},
   314 	},
   265 
   315 
   266 	cancel: function() {
   316 	cancel: function() {
   267 
   317 
       
   318 		var self = this;
       
   319 
   268 		if(this.dragging) {
   320 		if(this.dragging) {
   269 
   321 
   270 			this._mouseUp();
   322 			this._mouseUp();
   271 
   323 
   272 			if(this.options.helper == "original")
   324 			if(this.options.helper == "original")
   274 			else
   326 			else
   275 				this.currentItem.show();
   327 				this.currentItem.show();
   276 
   328 
   277 			//Post deactivating events to containers
   329 			//Post deactivating events to containers
   278 			for (var i = this.containers.length - 1; i >= 0; i--){
   330 			for (var i = this.containers.length - 1; i >= 0; i--){
   279 				this.containers[i]._propagate("deactivate", null, this);
   331 				this.containers[i]._trigger("deactivate", null, self._uiHash(this));
   280 				if(this.containers[i].containerCache.over) {
   332 				if(this.containers[i].containerCache.over) {
   281 					this.containers[i]._propagate("out", null, this);
   333 					this.containers[i]._trigger("out", null, self._uiHash(this));
   282 					this.containers[i].containerCache.over = 0;
   334 					this.containers[i].containerCache.over = 0;
   283 				}
   335 				}
   284 			}
   336 			}
   285 
   337 
   286 		}
   338 		}
   408 	refresh: function(event) {
   460 	refresh: function(event) {
   409 		this._refreshItems(event);
   461 		this._refreshItems(event);
   410 		this.refreshPositions();
   462 		this.refreshPositions();
   411 	},
   463 	},
   412 
   464 
       
   465 	_connectWith: function() {
       
   466 		var options = this.options;
       
   467 		return options.connectWith.constructor == String
       
   468 			? [options.connectWith]
       
   469 			: options.connectWith;
       
   470 	},
       
   471 	
   413 	_getItemsAsjQuery: function(connected) {
   472 	_getItemsAsjQuery: function(connected) {
   414 
   473 
   415 		var self = this;
   474 		var self = this;
   416 		var items = [];
   475 		var items = [];
   417 		var queries = [];
   476 		var queries = [];
   418 
   477 		var connectWith = this._connectWith();
   419 		if(this.options.connectWith && connected) {
   478 
   420 			for (var i = this.options.connectWith.length - 1; i >= 0; i--){
   479 		if(connectWith && connected) {
   421 				var cur = $(this.options.connectWith[i]);
   480 			for (var i = connectWith.length - 1; i >= 0; i--){
       
   481 				var cur = $(connectWith[i]);
   422 				for (var j = cur.length - 1; j >= 0; j--){
   482 				for (var j = cur.length - 1; j >= 0; j--){
   423 					var inst = $.data(cur[j], 'sortable');
   483 					var inst = $.data(cur[j], 'sortable');
   424 					if(inst && inst != this && !inst.options.disabled) {
   484 					if(inst && inst != this && !inst.options.disabled) {
   425 						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]);
   485 						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]);
   426 					}
   486 					}
   460 		this.items = [];
   520 		this.items = [];
   461 		this.containers = [this];
   521 		this.containers = [this];
   462 		var items = this.items;
   522 		var items = this.items;
   463 		var self = this;
   523 		var self = this;
   464 		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
   524 		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
   465 
   525 		var connectWith = this._connectWith();
   466 		if(this.options.connectWith) {
   526 
   467 			for (var i = this.options.connectWith.length - 1; i >= 0; i--){
   527 		if(connectWith) {
   468 				var cur = $(this.options.connectWith[i]);
   528 			for (var i = connectWith.length - 1; i >= 0; i--){
       
   529 				var cur = $(connectWith[i]);
   469 				for (var j = cur.length - 1; j >= 0; j--){
   530 				for (var j = cur.length - 1; j >= 0; j--){
   470 					var inst = $.data(cur[j], 'sortable');
   531 					var inst = $.data(cur[j], 'sortable');
   471 					if(inst && inst != this && !inst.options.disabled) {
   532 					if(inst && inst != this && !inst.options.disabled) {
   472 						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
   533 						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
   473 						this.containers.push(inst);
   534 						this.containers.push(inst);
   511 				continue;
   572 				continue;
   512 
   573 
   513 			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
   574 			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
   514 
   575 
   515 			if (!fast) {
   576 			if (!fast) {
   516 				if (this.options.accurateIntersection) {
   577 				item.width = t.outerWidth();
   517 					item.width = t.outerWidth();
   578 				item.height = t.outerHeight();
   518 					item.height = t.outerHeight();
       
   519 				}
       
   520 				else {
       
   521 					item.width = t[0].offsetWidth;
       
   522 					item.height = t[0].offsetHeight;
       
   523 				}
       
   524 			}
   579 			}
   525 
   580 
   526 			var p = t.offset();
   581 			var p = t.offset();
   527 			item.left = p.left;
   582 			item.left = p.left;
   528 			item.top = p.top;
   583 			item.top = p.top;
   551 			o.placeholder = {
   606 			o.placeholder = {
   552 				element: function() {
   607 				element: function() {
   553 
   608 
   554 					var el = $(document.createElement(self.currentItem[0].nodeName))
   609 					var el = $(document.createElement(self.currentItem[0].nodeName))
   555 						.addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
   610 						.addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
   556 						.removeClass('ui-sortable-helper')[0];
   611 						.removeClass("ui-sortable-helper")[0];
   557 
   612 
   558 					if(!className) {
   613 					if(!className)
   559 						el.style.visibility = "hidden";
   614 						el.style.visibility = "hidden";
   560 						document.body.appendChild(el);
       
   561 						// Name attributes are removed, otherwice causes elements to be unchecked
       
   562 						// Expando attributes also have to be removed because of stupid IE (no condition, doesn't hurt in other browsers)
       
   563 						el.innerHTML = self.currentItem[0].innerHTML.replace(/name\=\"[^\"\']+\"/g, '').replace(/jQuery[0-9]+\=\"[^\"\']+\"/g, '');
       
   564 						document.body.removeChild(el);
       
   565 					};
       
   566 
   615 
   567 					return el;
   616 					return el;
   568 				},
   617 				},
   569 				update: function(container, p) {
   618 				update: function(container, p) {
       
   619 
       
   620 					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
       
   621 					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
   570 					if(className && !o.forcePlaceholderSize) return;
   622 					if(className && !o.forcePlaceholderSize) return;
       
   623 
       
   624 					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
   571 					if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
   625 					if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
   572 					if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
   626 					if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
   573 				}
   627 				}
   574 			};
   628 			};
   575 		}
   629 		}
   605 
   659 
   606 						if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
   660 						if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
   607 							continue;
   661 							continue;
   608 
   662 
   609 						this.currentContainer = this.containers[i];
   663 						this.currentContainer = this.containers[i];
   610 						itemWithLeastDistance ? this.options.sortIndicator.call(this, event, itemWithLeastDistance, null, true) : this.options.sortIndicator.call(this, event, null, this.containers[i].element, true);
   664 						itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[i].element, true);
   611 						this._propagate("change", event); //Call plugins and callbacks
   665 						this._trigger("change", event, this._uiHash());
   612 						this.containers[i]._propagate("change", event, this); //Call plugins and callbacks
   666 						this.containers[i]._trigger("change", event, this._uiHash(this));
   613 
   667 
   614 						//Update the placeholder
   668 						//Update the placeholder
   615 						this.options.placeholder.update(this.currentContainer, this.placeholder);
   669 						this.options.placeholder.update(this.currentContainer, this.placeholder);
   616 
   670 
   617 					}
   671 					}
   618 
   672 
   619 					this.containers[i]._propagate("over", event, this);
   673 					this.containers[i]._trigger("over", event, this._uiHash(this));
   620 					this.containers[i].containerCache.over = 1;
   674 					this.containers[i].containerCache.over = 1;
   621 				}
   675 				}
   622 			} else {
   676 			} else {
   623 				if(this.containers[i].containerCache.over) {
   677 				if(this.containers[i].containerCache.over) {
   624 					this.containers[i]._propagate("out", event, this);
   678 					this.containers[i]._trigger("out", event, this._uiHash(this));
   625 					this.containers[i].containerCache.over = 0;
   679 					this.containers[i].containerCache.over = 0;
   626 				}
   680 				}
   627 			}
   681 			}
   628 
   682 
   629 		};
   683 		};
   654 		if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
   708 		if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
   655 	},
   709 	},
   656 
   710 
   657 	_getParentOffset: function() {
   711 	_getParentOffset: function() {
   658 
   712 
       
   713 
   659 		//Get the offsetParent and cache its position
   714 		//Get the offsetParent and cache its position
   660 		this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();
   715 		this.offsetParent = this.helper.offsetParent();
   661 
   716 		var po = this.offsetParent.offset();
   662 		if((this.offsetParent[0] == document.body && $.browser.mozilla)	//Ugly FF3 fix
   717 
       
   718 		// This is a special case where we need to modify a offset calculated on start, since the following happened:
       
   719 		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
       
   720 		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
       
   721 		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
       
   722 		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
       
   723 			po.left += this.scrollParent.scrollLeft();
       
   724 			po.top += this.scrollParent.scrollTop();
       
   725 		}
       
   726 
       
   727 		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
   663 		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
   728 		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
   664 			po = { top: 0, left: 0 };
   729 			po = { top: 0, left: 0 };
   665 
   730 
   666 		return {
   731 		return {
   667 			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
   732 			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
   703 		var o = this.options;
   768 		var o = this.options;
   704 		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
   769 		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
   705 		if(o.containment == 'document' || o.containment == 'window') this.containment = [
   770 		if(o.containment == 'document' || o.containment == 'window') this.containment = [
   706 			0 - this.offset.relative.left - this.offset.parent.left,
   771 			0 - this.offset.relative.left - this.offset.parent.left,
   707 			0 - this.offset.relative.top - this.offset.parent.top,
   772 			0 - this.offset.relative.top - this.offset.parent.top,
   708 			$(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0),
   773 			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
   709 			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0)
   774 			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
   710 		];
   775 		];
   711 
   776 
   712 		if(!(/^(document|window|parent)$/).test(o.containment)) {
   777 		if(!(/^(document|window|parent)$/).test(o.containment)) {
   713 			var ce = $(o.containment)[0];
   778 			var ce = $(o.containment)[0];
   714 			var co = $(o.containment).offset();
   779 			var co = $(o.containment).offset();
   715 			var over = ($(ce).css("overflow") != 'hidden');
   780 			var over = ($(ce).css("overflow") != 'hidden');
   716 
   781 
   717 			this.containment = [
   782 			this.containment = [
   718 				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
   783 				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
   719 				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top,
   784 				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
   720 				co.left + (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
   785 				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
   721 				co.top + (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top
   786 				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
   722 			];
   787 			];
   723 		}
   788 		}
   724 
   789 
   725 	},
   790 	},
   726 
   791 
   727 	_convertPositionTo: function(d, pos) {
   792 	_convertPositionTo: function(d, pos) {
   728 
   793 
   729 		if(!pos) pos = this.position;
   794 		if(!pos) pos = this.position;
   730 		var mod = d == "absolute" ? 1 : -1;
   795 		var mod = d == "absolute" ? 1 : -1;
   731 		var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   796 		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   732 
   797 
   733 		return {
   798 		return {
   734 			top: (
   799 			top: (
   735 				pos.top																	// the calculated relative position
   800 				pos.top																	// The absolute mouse position
   736 				+ this.offset.relative.top	* mod										// Only for relative positioned nodes: Relative offset from element to offset parent
   801 				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
   737 				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
   802 				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
   738 				+ ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
   803 				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
   739 				+ this.margins.top * mod												//Add the margin (you don't want the margin counting in intersection methods)
       
   740 			),
   804 			),
   741 			left: (
   805 			left: (
   742 				pos.left																// the calculated relative position
   806 				pos.left																// The absolute mouse position
   743 				+ this.offset.relative.left	* mod										// Only for relative positioned nodes: Relative offset from element to offset parent
   807 				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
   744 				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
   808 				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
   745 				+ ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod
   809 				- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
   746 				+ this.margins.left * mod												//Add the margin (you don't want the margin counting in intersection methods)
       
   747 			)
   810 			)
   748 		};
   811 		};
       
   812 
   749 	},
   813 	},
   750 
   814 
   751 	_generatePosition: function(event) {
   815 	_generatePosition: function(event) {
   752 
   816 
   753 		var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   817 		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
   754 
   818 
   755 		var position = {
   819 		// This is another very weird special case that only happens for relative elements:
   756 			top: (
   820 		// 1. If the css position is relative
   757 				event.pageY																// The absolute mouse position
   821 		// 2. and the scroll parent is the document or similar to the offset parent
   758 				- this.offset.click.top													// Click offset (relative to the element)
   822 		// we have to refresh the relative offset during the scroll so there are no jumps
   759 				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
   823 		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
   760 				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
   824 			this.offset.relative = this._getRelativeOffset();
   761 				+ ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
   825 		}
   762 			),
   826 
   763 			left: (
   827 		var pageX = event.pageX;
   764 				event.pageX																// The absolute mouse position
   828 		var pageY = event.pageY;
   765 				- this.offset.click.left												// Click offset (relative to the element)
       
   766 				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
       
   767 				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
       
   768 				+ ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
       
   769 			)
       
   770 		};
       
   771 
       
   772 		if(!this.originalPosition) return position;										//If we are not dragging yet, we won't check for options
       
   773 
   829 
   774 		/*
   830 		/*
   775 		 * - Position constraining -
   831 		 * - Position constraining -
   776 		 * Constrain the position to a mix of grid, containment.
   832 		 * Constrain the position to a mix of grid, containment.
   777 		 */
   833 		 */
   778 		if(this.containment) {
   834 
   779 			if(position.left < this.containment[0]) position.left = this.containment[0];
   835 		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
   780 			if(position.top < this.containment[1]) position.top = this.containment[1];
   836 
   781 			if(position.left + this.helperProportions.width > this.containment[2]) position.left = this.containment[2] - this.helperProportions.width;
   837 			if(this.containment) {
   782 			if(position.top + this.helperProportions.height > this.containment[3]) position.top = this.containment[3] - this.helperProportions.height;
   838 				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
   783 		}
   839 				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
   784 
   840 				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
   785 		if(o.grid) {
   841 				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
   786 			var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
   842 			}
   787 			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;
   843 
   788 
   844 			if(o.grid) {
   789 			var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
   845 				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
   790 			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;
   846 				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
   791 		}
   847 
   792 
   848 				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
   793 		return position;
   849 				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
       
   850 			}
       
   851 
       
   852 		}
       
   853 
       
   854 		return {
       
   855 			top: (
       
   856 				pageY																// The absolute mouse position
       
   857 				- this.offset.click.top													// Click offset (relative to the element)
       
   858 				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
       
   859 				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
       
   860 				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
       
   861 			),
       
   862 			left: (
       
   863 				pageX																// The absolute mouse position
       
   864 				- this.offset.click.left												// Click offset (relative to the element)
       
   865 				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
       
   866 				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
       
   867 				+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
       
   868 			)
       
   869 		};
       
   870 
   794 	},
   871 	},
   795 
   872 
   796 	_rearrange: function(event, i, a, hardRefresh) {
   873 	_rearrange: function(event, i, a, hardRefresh) {
   797 
   874 
   798 		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));
   875 		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));
   812 	},
   889 	},
   813 
   890 
   814 	_clear: function(event, noPropagation) {
   891 	_clear: function(event, noPropagation) {
   815 
   892 
   816 		this.reverting = false;
   893 		this.reverting = false;
   817 
   894 		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
   818 		//We first have to update the dom position of the actual currentItem
   895 		// everything else normalized again
   819 		if(!this._noFinalSort) this.placeholder.before(this.currentItem);
   896 		var delayedTriggers = [], self = this;
       
   897 
       
   898 		// We first have to update the dom position of the actual currentItem
       
   899 		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
       
   900 		if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
   820 		this._noFinalSort = null;
   901 		this._noFinalSort = null;
   821 
   902 
   822 		if(this.helper[0] == this.currentItem[0]) {
   903 		if(this.helper[0] == this.currentItem[0]) {
   823 			for(var i in this._storedCSS) {
   904 			for(var i in this._storedCSS) {
   824 				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
   905 				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
   826 			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
   907 			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
   827 		} else {
   908 		} else {
   828 			this.currentItem.show();
   909 			this.currentItem.show();
   829 		}
   910 		}
   830 
   911 
   831 		if(this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) this._propagate("update", event, null, noPropagation); //Trigger update callback if the DOM position has changed
   912 		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
       
   913 		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
   832 		if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
   914 		if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
   833 			this._propagate("remove", event, null, noPropagation);
   915 			if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
   834 			for (var i = this.containers.length - 1; i >= 0; i--){
   916 			for (var i = this.containers.length - 1; i >= 0; i--){
   835 				if($.ui.contains(this.containers[i].element[0], this.currentItem[0])) {
   917 				if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
   836 					this.containers[i]._propagate("update", event, this, noPropagation);
   918 					delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
   837 					this.containers[i]._propagate("receive", event, this, noPropagation);
   919 					delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
   838 				}
   920 				}
   839 			};
   921 			};
   840 		};
   922 		};
   841 
   923 
   842 		//Post events to containers
   924 		//Post events to containers
   843 		for (var i = this.containers.length - 1; i >= 0; i--){
   925 		for (var i = this.containers.length - 1; i >= 0; i--){
   844 			this.containers[i]._propagate("deactivate", event, this, noPropagation);
   926 			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
   845 			if(this.containers[i].containerCache.over) {
   927 			if(this.containers[i].containerCache.over) {
   846 				this.containers[i]._propagate("out", event, this);
   928 				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
   847 				this.containers[i].containerCache.over = 0;
   929 				this.containers[i].containerCache.over = 0;
   848 			}
   930 			}
   849 		}
   931 		}
   850 
   932 
       
   933 		//Do what was originally in plugins
       
   934 		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
       
   935 		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset cursor
       
   936 		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
       
   937 
   851 		this.dragging = false;
   938 		this.dragging = false;
   852 		if(this.cancelHelperRemoval) {
   939 		if(this.cancelHelperRemoval) {
   853 			this._propagate("beforeStop", event, null, noPropagation);
   940 			if(!noPropagation) {
   854 			this._propagate("stop", event, null, noPropagation);
   941 				this._trigger("beforeStop", event, this._uiHash());
       
   942 				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
       
   943 				this._trigger("stop", event, this._uiHash());
       
   944 			}
   855 			return false;
   945 			return false;
   856 		}
   946 		}
   857 
   947 
   858 		this._propagate("beforeStop", event, null, noPropagation);
   948 		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
   859 
   949 
   860 		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
   950 		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
   861 		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
   951 		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
   862 
   952 
   863 		if(this.options.helper != "original") this.helper.remove(); this.helper = null;
   953 		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
   864 		this._propagate("stop", event, null, noPropagation);
   954 
   865 
   955 		if(!noPropagation) {
       
   956 			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
       
   957 			this._trigger("stop", event, this._uiHash());
       
   958 		}
       
   959 
       
   960 		this.fromOutside = false;
   866 		return true;
   961 		return true;
   867 
   962 
   868 	},
   963 	},
   869 
   964 
   870 	_propagate: function(n, event, inst, noPropagation) {
   965 	_trigger: function() {
   871 		$.ui.plugin.call(this, n, [event, this._ui(inst)]);
   966 		if ($.widget.prototype._trigger.apply(this, arguments) === false) {
   872 		var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true;
   967 			this.cancel();
   873 		if(dontCancel === false) this.cancel();
   968 		}
   874 	},
   969 	},
   875 
   970 
   876 	plugins: {},
   971 	_uiHash: function(inst) {
   877 
       
   878 	_ui: function(inst) {
       
   879 		var self = inst || this;
   972 		var self = inst || this;
   880 		return {
   973 		return {
   881 			helper: self.helper,
   974 			helper: self.helper,
   882 			placeholder: self.placeholder || $([]),
   975 			placeholder: self.placeholder || $([]),
   883 			position: self.position,
   976 			position: self.position,
   884 			absolutePosition: self.positionAbs,
   977 			absolutePosition: self.positionAbs, //deprecated
       
   978 			offset: self.positionAbs,
   885 			item: self.currentItem,
   979 			item: self.currentItem,
   886 			sender: inst ? inst.element : null
   980 			sender: inst ? inst.element : null
   887 		};
   981 		};
   888 	}
   982 	}
   889 
   983 
   890 }));
   984 }));
   891 
   985 
   892 $.extend($.ui.sortable, {
   986 $.extend($.ui.sortable, {
   893 	getter: "serialize toArray",
   987 	getter: "serialize toArray",
   894 	version: "1.6",
   988 	version: "1.7.2",
       
   989 	eventPrefix: "sort",
   895 	defaults: {
   990 	defaults: {
   896 		accurateIntersection: true,
       
   897 		appendTo: "parent",
   991 		appendTo: "parent",
   898 		cancel: ":input",
   992 		axis: false,
       
   993 		cancel: ":input,option",
       
   994 		connectWith: false,
       
   995 		containment: false,
       
   996 		cursor: 'auto',
       
   997 		cursorAt: false,
   899 		delay: 0,
   998 		delay: 0,
   900 		distance: 1,
   999 		distance: 1,
   901 		dropOnEmpty: true,
  1000 		dropOnEmpty: true,
   902 		forcePlaceholderSize: false,
  1001 		forcePlaceholderSize: false,
   903 		forceHelperSize: false,
  1002 		forceHelperSize: false,
       
  1003 		grid: false,
       
  1004 		handle: false,
   904 		helper: "original",
  1005 		helper: "original",
   905 		items: '> *',
  1006 		items: '> *',
   906 		scope: "default",
  1007 		opacity: false,
       
  1008 		placeholder: false,
       
  1009 		revert: false,
   907 		scroll: true,
  1010 		scroll: true,
   908 		scrollSensitivity: 20,
  1011 		scrollSensitivity: 20,
   909 		scrollSpeed: 20,
  1012 		scrollSpeed: 20,
   910 		sortIndicator: $.ui.sortable.prototype._rearrange,
  1013 		scope: "default",
   911 		tolerance: "default",
  1014 		tolerance: "intersect",
   912 		zIndex: 1000
  1015 		zIndex: 1000
   913 	}
  1016 	}
   914 });
  1017 });
   915 
  1018 
   916 /*
       
   917  * Sortable Extensions
       
   918  */
       
   919 
       
   920 $.ui.plugin.add("sortable", "cursor", {
       
   921 	start: function(event, ui) {
       
   922 		var t = $('body'), i = $(this).data('sortable');
       
   923 		if (t.css("cursor")) i.options._cursor = t.css("cursor");
       
   924 		t.css("cursor", i.options.cursor);
       
   925 	},
       
   926 	beforeStop: function(event, ui) {
       
   927 		var i = $(this).data('sortable');
       
   928 		if (i.options._cursor) $('body').css("cursor", i.options._cursor);
       
   929 	}
       
   930 });
       
   931 
       
   932 $.ui.plugin.add("sortable", "opacity", {
       
   933 	start: function(event, ui) {
       
   934 		var t = ui.helper, i = $(this).data('sortable');
       
   935 		if(t.css("opacity")) i.options._opacity = t.css("opacity");
       
   936 		t.css('opacity', i.options.opacity);
       
   937 	},
       
   938 	beforeStop: function(event, ui) {
       
   939 		var i = $(this).data('sortable');
       
   940 		if(i.options._opacity) $(ui.helper).css('opacity', i.options._opacity);
       
   941 	}
       
   942 });
       
   943 
       
   944 $.ui.plugin.add("sortable", "scroll", {
       
   945 	start: function(event, ui) {
       
   946 		var i = $(this).data("sortable"), o = i.options;
       
   947 		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
       
   948 	},
       
   949 	sort: function(event, ui) {
       
   950 
       
   951 		var i = $(this).data("sortable"), o = i.options, scrolled = false;
       
   952 
       
   953 		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
       
   954 
       
   955 			if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
       
   956 				i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
       
   957 			else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
       
   958 				i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
       
   959 
       
   960 			if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
       
   961 				i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
       
   962 			else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
       
   963 				i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
       
   964 
       
   965 		} else {
       
   966 
       
   967 			if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
       
   968 				scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
       
   969 			else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
       
   970 				scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
       
   971 
       
   972 			if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
       
   973 				scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
       
   974 			else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
       
   975 				scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
       
   976 
       
   977 		}
       
   978 
       
   979 		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
       
   980 			$.ui.ddmanager.prepareOffsets(i, event);
       
   981 
       
   982 
       
   983 
       
   984 		//This is a special case where we need to modify a offset calculated on start, since the following happened:
       
   985 		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
       
   986 		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
       
   987 		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
       
   988 		if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && $.ui.contains(i.scrollParent[0], i.offsetParent[0])) {
       
   989 			i.offset.parent = i._getParentOffset();
       
   990 		}
       
   991 		
       
   992 		// This is another very weird special case that only happens for relative elements:
       
   993 		// 1. If the css position is relative
       
   994 		// 2. and the scroll parent is the document or similar to the offset parent
       
   995 		// we have to refresh the relative offset during the scroll so there are no jumps
       
   996 		if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) {
       
   997 			i.offset.relative = i._getRelativeOffset();
       
   998 		}
       
   999 
       
  1000 	}
       
  1001 });
       
  1002 
       
  1003 $.ui.plugin.add("sortable", "zIndex", {
       
  1004 	start: function(event, ui) {
       
  1005 		var t = ui.helper, i = $(this).data('sortable');
       
  1006 		if(t.css("zIndex")) i.options._zIndex = t.css("zIndex");
       
  1007 		t.css('zIndex', i.options.zIndex);
       
  1008 	},
       
  1009 	beforeStop: function(event, ui) {
       
  1010 		var i = $(this).data('sortable');
       
  1011 		if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex == 'auto' ? '' : i.options._zIndex);
       
  1012 	}
       
  1013 });
       
  1014 
       
  1015 })(jQuery);
  1019 })(jQuery);