/* * jQuery UI 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI */ ;(function($) { var _remove = $.fn.remove, isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9); //Helper functions and ui object $.ui = { version: "1.6rc5", // $.ui.plugin is deprecated. Use the proxy pattern instead. plugin: { add: function(module, option, set) { var proto = $.ui[module].prototype; for(var i in set) { proto.plugins[i] = proto.plugins[i] || []; proto.plugins[i].push([option, set[i]]); } }, call: function(instance, name, args) { var set = instance.plugins[name]; if(!set) { return; } for (var i = 0; i < set.length; i++) { if (instance.options[set[i][0]]) { set[i][1].apply(instance.element, args); } } } }, contains: function(a, b) { return document.compareDocumentPosition ? a.compareDocumentPosition(b) & 16 : a !== b && a.contains(b); }, cssCache: {}, css: function(name) { if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; } var tmp = $('
').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body'); //if (!$.browser.safari) //tmp.appendTo('body'); //Opera and Safari set width and height to 0px instead of auto //Safari returns rgba(0,0,0,0) when bgcolor is not set $.ui.cssCache[name] = !!( (!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) || !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor'))) ); try { $('body').get(0).removeChild(tmp.get(0)); } catch(e){} return $.ui.cssCache[name]; }, hasScroll: function(el, a) { //If overflow is hidden, the element might have extra content, but the user wants to hide it if ($(el).css('overflow') == 'hidden') { return false; } var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop', has = false; if (el[scroll] > 0) { return true; } // TODO: determine which cases actually cause this to happen // if the element doesn't have the scroll set, see if it's possible to // set the scroll el[scroll] = 1; has = (el[scroll] > 0); el[scroll] = 0; return has; }, isOverAxis: function(x, reference, size) { //Determines when x coordinate is over "b" element axis return (x > reference) && (x < (reference + size)); }, isOver: function(y, x, top, left, height, width) { //Determines when x, y coordinates is over "b" element return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width); }, keyCode: { BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108, NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38 } }; // WAI-ARIA normalization if (isFF2) { var attr = $.attr, removeAttr = $.fn.removeAttr, ariaNS = "http://www.w3.org/2005/07/aaa", ariaState = /^aria-/, ariaRole = /^wairole:/; $.attr = function(elem, name, value) { var set = value !== undefined; return (name == 'role' ? (set ? attr.call(this, elem, name, "wairole:" + value) : (attr.apply(this, arguments) || "").replace(ariaRole, "")) : (ariaState.test(name) ? (set ? elem.setAttributeNS(ariaNS, name.replace(ariaState, "aaa:"), value) : attr.call(this, elem, name.replace(ariaState, "aaa:"))) : attr.apply(this, arguments))); }; $.fn.removeAttr = function(name) { return (ariaState.test(name) ? this.each(function() { this.removeAttributeNS(ariaNS, name.replace(ariaState, "")); }) : removeAttr.call(this, name)); }; } //jQuery plugins $.fn.extend({ remove: function() { // Safari has a native remove event which actually removes DOM elements, // so we have to use triggerHandler instead of trigger (#3037). $("*", this).add(this).each(function() { $(this).triggerHandler("remove"); }); return _remove.apply(this, arguments ); }, enableSelection: function() { return this .attr('unselectable', 'off') .css('MozUserSelect', '') .unbind('selectstart.ui'); }, disableSelection: function() { return this .attr('unselectable', 'on') .css('MozUserSelect', 'none') .bind('selectstart.ui', function() { return false; }); }, scrollParent: function() { var scrollParent; if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { scrollParent = this.parents().filter(function() { return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); }).eq(0); } else { scrollParent = this.parents().filter(function() { return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); }).eq(0); } return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; } }); //Additional selectors $.extend($.expr[':'], { data: function(elem, i, match) { return !!$.data(elem, match[3]); }, // TODO: add support for object, area tabbable: function(elem) { var nodeName = elem.nodeName.toLowerCase(); function isVisible(element) { return !($(element).is(':hidden') || $(element).parents(':hidden').length); } return ( // in tab order elem.tabIndex >= 0 && ( // filter node types that participate in the tab order // anchor tag ('a' == nodeName && elem.href) || // enabled form element (/input|select|textarea|button/.test(nodeName) && 'hidden' != elem.type && !elem.disabled) ) && // visible on page isVisible(elem) ); } }); // $.widget is a factory to create jQuery plugins // taking some boilerplate code out of the plugin code function getter(namespace, plugin, method, args) { function getMethods(type) { var methods = $[namespace][plugin][type] || []; return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods); } var methods = getMethods('getter'); if (args.length == 1 && typeof args[0] == 'string') { methods = methods.concat(getMethods('getterSetter')); } return ($.inArray(method, methods) != -1); } $.widget = function(name, prototype) { var namespace = name.split(".")[0]; name = name.split(".")[1]; // create plugin method $.fn[name] = function(options) { var isMethodCall = (typeof options == 'string'), args = Array.prototype.slice.call(arguments, 1); // prevent calls to internal methods if (isMethodCall && options.substring(0, 1) == '_') { return this; } // handle getter methods if (isMethodCall && getter(namespace, name, options, args)) { var instance = $.data(this[0], name); return (instance ? instance[options].apply(instance, args) : undefined); } // handle initialization and non-getter methods return this.each(function() { var instance = $.data(this, name); // constructor (!instance && !isMethodCall && $.data(this, name, new $[namespace][name](this, options))); // method call (instance && isMethodCall && $.isFunction(instance[options]) && instance[options].apply(instance, args)); }); }; // create widget constructor $[namespace] = $[namespace] || {}; $[namespace][name] = function(element, options) { var self = this; this.namespace = namespace; this.widgetName = name; this.widgetEventPrefix = $[namespace][name].eventPrefix || name; this.widgetBaseClass = namespace + '-' + name; this.options = $.extend({}, $.widget.defaults, $[namespace][name].defaults, $.metadata && $.metadata.get(element)[name], options); this.element = $(element) .bind('setData.' + name, function(event, key, value) { if (event.target == element) { return self._setData(key, value); } }) .bind('getData.' + name, function(event, key) { if (event.target == element) { return self._getData(key); } }) .bind('remove', function() { return self.destroy(); }); this._init(); }; // add widget prototype $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype); // TODO: merge getter and getterSetter properties from widget prototype // and plugin prototype $[namespace][name].getterSetter = 'option'; }; $.widget.prototype = { _init: function() {}, destroy: function() { this.element.removeData(this.widgetName) .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled') .removeAttr('aria-disabled'); }, option: function(key, value) { var options = key, self = this; if (typeof key == "string") { if (value === undefined) { return this._getData(key); } options = {}; options[key] = value; } $.each(options, function(key, value) { self._setData(key, value); }); }, _getData: function(key) { return this.options[key]; }, _setData: function(key, value) { this.options[key] = value; if (key == 'disabled') { this.element [value ? 'addClass' : 'removeClass']( this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled') .attr("aria-disabled", value); } }, enable: function() { this._setData('disabled', false); }, disable: function() { this._setData('disabled', true); }, _trigger: function(type, event, data) { var callback = this.options[type], eventName = (type == this.widgetEventPrefix ? type : this.widgetEventPrefix + type); event = $.Event(event); event.type = eventName; this.element.trigger(event, data); return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false || event.isDefaultPrevented()); } }; $.widget.defaults = { disabled: false }; /** Mouse Interaction Plugin **/ $.ui.mouse = { _mouseInit: function() { var self = this; this.element .bind('mousedown.'+this.widgetName, function(event) { return self._mouseDown(event); }) .bind('click.'+this.widgetName, function(event) { if(self._preventClickEvent) { self._preventClickEvent = false; return false; } }); // Prevent text selection in IE if ($.browser.msie) { this._mouseUnselectable = this.element.attr('unselectable'); this.element.attr('unselectable', 'on'); } this.started = false; }, // TODO: make sure destroying one instance of mouse doesn't mess with // other instances of mouse _mouseDestroy: function() { this.element.unbind('.'+this.widgetName); // Restore text selection in IE ($.browser.msie && this.element.attr('unselectable', this._mouseUnselectable)); }, _mouseDown: function(event) { // we may have missed mouseup (out of window) (this._mouseStarted && this._mouseUp(event)); this._mouseDownEvent = event; var self = this, btnIsLeft = (event.which == 1), elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false); if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { return true; } this.mouseDelayMet = !this.options.delay; if (!this.mouseDelayMet) { this._mouseDelayTimer = setTimeout(function() { self.mouseDelayMet = true; }, this.options.delay); } if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { this._mouseStarted = (this._mouseStart(event) !== false); if (!this._mouseStarted) { event.preventDefault(); return true; } } // these delegates are required to keep context this._mouseMoveDelegate = function(event) { return self._mouseMove(event); }; this._mouseUpDelegate = function(event) { return self._mouseUp(event); }; $(document) .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); // preventDefault() is used to prevent the selection of text here - // however, in Safari, this causes select boxes not to be selectable // anymore, so this fix is needed ($.browser.safari || event.preventDefault()); return true; }, _mouseMove: function(event) { // IE mouseup check - mouseup happened when mouse was out of window if ($.browser.msie && !event.button) { return this._mouseUp(event); } if (this._mouseStarted) { this._mouseDrag(event); return event.preventDefault(); } if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { this._mouseStarted = (this._mouseStart(this._mouseDownEvent, event) !== false); (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); } return !this._mouseStarted; }, _mouseUp: function(event) { $(document) .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); if (this._mouseStarted) { this._mouseStarted = false; this._preventClickEvent = true; this._mouseStop(event); } return false; }, _mouseDistanceMet: function(event) { return (Math.max( Math.abs(this._mouseDownEvent.pageX - event.pageX), Math.abs(this._mouseDownEvent.pageY - event.pageY) ) >= this.options.distance ); }, _mouseDelayMet: function(event) { return this.mouseDelayMet; }, // These are placeholder methods, to be overriden by extending plugin _mouseStart: function(event) {}, _mouseDrag: function(event) {}, _mouseStop: function(event) {}, _mouseCapture: function(event) { return true; } }; $.ui.mouse.defaults = { cancel: null, distance: 1, delay: 0 }; })(jQuery); /* * jQuery UI Draggable 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Draggables * * Depends: * ui.core.js */ (function($) { $.widget("ui.draggable", $.extend({}, $.ui.mouse, { _init: function() { if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) this.element[0].style.position = 'relative'; (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-draggable")); (this.options.disabled && this.element.addClass(this.options.cssNamespace+'-draggable-disabled')); this._mouseInit(); }, destroy: function() { if(!this.element.data('draggable')) return; this.element.removeData("draggable").unbind(".draggable").removeClass(this.options.cssNamespace+'-draggable '+this.options.cssNamespace+'-draggable-dragging '+this.options.cssNamespace+'-draggable-disabled'); this._mouseDestroy(); }, _mouseCapture: function(event) { var o = this.options; if (this.helper || o.disabled || $(event.target).is('.'+this.options.cssNamespace+'-resizable-handle')) return false; //Quit if we're not on a valid handle this.handle = this._getHandle(event); if (!this.handle) return false; return true; }, _mouseStart: function(event) { var o = this.options; //Create and append the visible helper this.helper = this._createHelper(event); //Cache the helper size this._cacheHelperProportions(); //If ddmanager is used for droppables, set the global draggable if($.ui.ddmanager) $.ui.ddmanager.current = this; /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Store the helper's css position this.cssPosition = this.helper.css("position"); this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.element.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); //Generate the original position this.originalPosition = this._generatePosition(event); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied if(o.cursorAt) this._adjustOffsetFromHelper(o.cursorAt); //Set a containment if given in the options if(o.containment) this._setContainment(); //Call plugins and callbacks this._trigger("start", event); //Recache the helper size this._cacheHelperProportions(); //Prepare the droppable offsets if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); this.helper.addClass(o.cssNamespace+"-draggable-dragging"); this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position return true; }, _mouseDrag: function(event, noPropagation) { //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 if (!noPropagation) { var ui = this._uiHash(); this._trigger('drag', event, ui); this.position = ui.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) dropped = $.ui.ddmanager.drop(this, event); //if a drop comes from outside (a sortable) if(this.dropped) { dropped = this.dropped; this.dropped = false; } 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._trigger("stop", event); self._clear(); }); } else { this._trigger("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; }, _adjustOffsetFromHelper: function(obj) { if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } if((this.offsetParent[0] == document.body && $.browser.mozilla) //Ugly FF3 fix || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix po = { top: 0, left: 0 }; return { top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) }; }, _getRelativeOffset: function() { if(this.cssPosition == "relative") { var p = this.element.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: (parseInt(this.element.css("marginLeft"),10) || 0), top: (parseInt(this.element.css("marginTop"),10) || 0) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; 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.margins.left, co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.margins.top, co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.helperProportions.width - this.margins.left, co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.helperProportions.height - this.margins.top ]; } }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; 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); return { top: ( pos.top // The absolute mouse position + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ), left: ( pos.left // The absolute mouse position + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod ) }; }, _generatePosition: function(event) { 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); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative // 2. and the scroll parent is the document or similar to the offset parent // we have to refresh the relative offset during the scroll so there are no jumps if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { this.offset.relative = this._getRelativeOffset(); } var pageX = event.pageX; var pageY = event.pageY; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options if(this.containment) { if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; } if(o.grid) { var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 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; var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 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; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) }; }, _clear: function() { this.helper.removeClass(this.options.cssNamespace+"-draggable-dragging"); if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); //if($.ui.ddmanager) $.ui.ddmanager.current = null; this.helper = null; this.cancelHelperRemoval = false; }, // From now on bulk stuff - mainly helpers _trigger: function(type, event, ui) { ui = ui || this._uiHash(); $.ui.plugin.call(this, type, [event, ui]); if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins return $.widget.prototype._trigger.call(this, type, event, ui); }, plugins: {}, _uiHash: function(event) { return { helper: this.helper, position: this.position, absolutePosition: this.positionAbs, options: this.options }; } })); $.extend($.ui.draggable, { version: "1.6rc5", eventPrefix: "drag", defaults: { appendTo: "parent", axis: false, cancel: ":input,option", connectToSortable: false, containment: false, cssNamespace: "ui", cursor: "default", cursorAt: null, delay: 0, distance: 1, grid: false, handle: false, helper: "original", iframeFix: false, opacity: null, refreshPositions: false, revert: false, revertDuration: 500, scope: "default", scroll: true, scrollSensitivity: 20, scrollSpeed: 20, snap: false, snapMode: "both", snapTolerance: 20, stack: false, zIndex: null } }); $.ui.plugin.add("draggable", "connectToSortable", { start: function(event, ui) { var inst = $(this).data("draggable"); inst.sortables = []; $(ui.options.connectToSortable).each(function() { // 'this' points to a string, and should therefore resolved as query, but instead, if the string is assigned to a variable, it loops through the strings properties, // so we have to append '' to make it anonymous again $(this+'').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._trigger("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) //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' if(this.shouldRevert) this.instance.options.revert = true; //Trigger the stop of the sortable 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._uiHash(), { sender: inst.element })], this.instance.options["receive"]); this.instance.options.helper = this.instance.options._helper; //If the helper has been the original item, restore properties in the sortable if(inst.options.helper == 'original') this.instance.currentItem.css({ top: 'auto', left: 'auto' }); } else { this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance this.instance._trigger("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._trigger("toSortable", event); inst.dropped = this.instance.element; //draggable revert needs that this.instance.fromOutside = true; //Little hack so receive/update callbacks work } //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._trigger("fromSortable", event); inst.dropped = false; //draggable revert needs that } }; }); } }); $.ui.plugin.add("draggable", "cursor", { start: function(event, ui) { 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._cursor) $('body').css("cursor", ui.options._cursor); } }); $.ui.plugin.add("draggable", "iframeFix", { start: function(event, ui) { $(ui.options.iframeFix === true ? "iframe" : ui.options.iframeFix).each(function() { $('') .css({ width: this.offsetWidth+"px", height: this.offsetHeight+"px", position: "absolute", opacity: "0.001", zIndex: 1000 }) .css($(this).offset()) .appendTo("body"); }); }, stop: function(event, ui) { $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers } }); $.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; var i = $(this).data("draggable"); if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); }, drag: function(event, ui) { var o = ui.options, scrolled = false; var i = $(this).data("draggable"); if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; } else { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(i, event); } }); $.ui.plugin.add("draggable", "snap", { start: function(event, ui) { var inst = $(this).data("draggable"); inst.snapElements = []; $(ui.options.snap.constructor != String ? ( ui.options.snap.items || ':data(draggable)' ) : ui.options.snap).each(function() { var $t = $(this); var $o = $t.offset(); if(this != inst.element[0]) inst.snapElements.push({ item: this, width: $t.outerWidth(), height: $t.outerHeight(), top: $o.top, left: $o.left }); }); }, drag: function(event, ui) { var inst = $(this).data("draggable"); var d = ui.options.snapTolerance; var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width, y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height; for (var i = inst.snapElements.length - 1; i >= 0; i--){ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; //Yes, I know, this is insane ;) if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = false; continue; } if(ui.options.snapMode != 'inner') { var ts = Math.abs(t - y2) <= d; var bs = Math.abs(b - y1) <= d; var ls = Math.abs(l - x2) <= d; var rs = Math.abs(r - x1) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; } var first = (ts || bs || ls || rs); if(ui.options.snapMode != 'outer') { var ts = Math.abs(t - y1) <= d; var bs = Math.abs(b - y2) <= d; var ls = Math.abs(l - x1) <= d; var rs = Math.abs(r - x2) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; } if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = (ts || bs || ls || rs || first); }; } }); $.ui.plugin.add("draggable", "stack", { 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); }); $(group).each(function(i) { this.style.zIndex = ui.options.stack.min + i; }); this[0].style.zIndex = ui.options.stack.min + group.length; } }); $.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); /* * jQuery UI Droppable 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Droppables * * Depends: * ui.core.js * ui.draggable.js */ (function($) { $.widget("ui.droppable", { _init: function() { var o = this.options, accept = o.accept; this.isover = 0; this.isout = 1; this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) { return d.is(accept); }; //Store the droppable's proportions this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; // Add the reference and positions to the manager $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || []; $.ui.ddmanager.droppables[this.options.scope].push(this); (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable")); }, destroy: function() { var drop = $.ui.ddmanager.droppables[this.options.scope]; for ( var i = 0; i < drop.length; i++ ) if ( drop[i] == this ) drop.splice(i, 1); this.element .removeClass(this.options.cssNamespace+"-droppable "+this.options.cssNamespace+"-droppable-disabled") .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)]); (draggable && this._trigger('activate', event, this.ui(draggable))); }, _deactivate: function(event) { var draggable = $.ui.ddmanager.current; $.ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]); (draggable && this._trigger('deactivate', event, this.ui(draggable))); }, _over: function(event) { var draggable = $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { $.ui.plugin.call(this, 'over', [event, this.ui(draggable)]); this._trigger('over', event, this.ui(draggable)); } }, _out: function(event) { var draggable = $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { $.ui.plugin.call(this, 'out', [event, this.ui(draggable)]); this._trigger('out', event, this.ui(draggable)); } }, _drop: function(event,custom) { var draggable = custom || $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element var childrenIntersection = false; this.element.find(":data(droppable)").not("."+draggable.options.cssNamespace+"-draggable-dragging").each(function() { var inst = $.data(this, 'droppable'); if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) { childrenIntersection = true; return false; } }); if(childrenIntersection) return false; if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { $.ui.plugin.call(this, 'drop', [event, this.ui(draggable)]); this._trigger('drop', event, this.ui(draggable)); return this.element; } return false; }, 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, { version: "1.6rc5", eventPrefix: 'drop', defaults: { accept: '*', activeClass: null, cssNamespace: 'ui', greedy: false, hoverClass: null, scope: 'default', tolerance: 'intersect' } }); $.ui.intersect = function(draggable, droppable, toleranceMode) { if (!droppable.offset) return false; var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; var l = droppable.offset.left, r = l + droppable.proportions.width, t = droppable.offset.top, b = t + droppable.proportions.height; switch (toleranceMode) { case 'fit': return (l < x1 && x2 < r && t < y1 && y2 < b); break; case 'intersect': return (l < x1 + (draggable.helperProportions.width / 2) // Right Half && x2 - (draggable.helperProportions.width / 2) < r // Left Half && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half break; case 'pointer': var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); return isOver; break; case 'touch': return ( (y1 >= t && y1 <= b) || // Top edge touching (y2 >= t && y2 <= b) || // Bottom edge touching (y1 < t && y2 > b) // Surrounded vertically ) && ( (x1 >= l && x1 <= r) || // Left edge touching (x2 >= l && x2 <= r) || // Right edge touching (x1 < l && x2 > r) // Surrounded horizontally ); break; default: return false; break; } }; /* This manager tracks offsets of draggables and droppables */ $.ui.ddmanager = { current: null, droppables: { 'default': [] }, prepareOffsets: function(t, event) { var m = $.ui.ddmanager.droppables[t.options.scope]; var type = event ? event.type : null; // workaround for #2317 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); droppablesLoop: for (var i = 0; i < m.length; i++) { if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue; //No disabled and non-accepted for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue m[i].offset = m[i].element.offset(); m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; if(type == "dragstart" || type == "sortactivate") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables } }, drop: function(draggable, event) { var dropped = false; $.each($.ui.ddmanager.droppables[draggable.options.scope], function() { if(!this.options) return; if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) dropped = this._drop.call(this, event); if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) { this.isout = 1; this.isover = 0; this._deactivate.call(this, event); } }); return dropped; }, drag: function(draggable, event) { //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); //Run through all droppables and check their positions based on specific tolerance options $.each($.ui.ddmanager.droppables[draggable.options.scope], function() { if(this.options.disabled || this.greedyChild || !this.visible) return; var intersects = $.ui.intersect(draggable, this, this.options.tolerance); var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); if(!c) return; var parentInstance; if (this.options.greedy) { var parent = this.element.parents(':data(droppable):eq(0)'); if (parent.length) { parentInstance = $.data(parent[0], 'droppable'); parentInstance.greedyChild = (c == 'isover' ? 1 : 0); } } // we just moved into a greedy child if (parentInstance && c == 'isover') { parentInstance['isover'] = 0; parentInstance['isout'] = 1; parentInstance._out.call(parentInstance, event); } this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; this[c == "isover" ? "_over" : "_out"].call(this, event); // we just moved out of a greedy child if (parentInstance && c == 'isout') { parentInstance['isout'] = 0; parentInstance['isover'] = 1; parentInstance._over.call(parentInstance, event); } }); } }; /* * Droppable Extensions */ $.ui.plugin.add("droppable", "activeClass", { activate: function(event, ui) { $(this).addClass(ui.options.activeClass); }, deactivate: function(event, ui) { $(this).removeClass(ui.options.activeClass); }, drop: function(event, ui) { $(this).removeClass(ui.options.activeClass); } }); $.ui.plugin.add("droppable", "hoverClass", { over: function(event, ui) { $(this).addClass(ui.options.hoverClass); }, out: function(event, ui) { $(this).removeClass(ui.options.hoverClass); }, drop: function(event, ui) { $(this).removeClass(ui.options.hoverClass); } }); })(jQuery); /* * jQuery UI Resizable 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Resizables * * Depends: * ui.core.js */ (function($) { $.widget("ui.resizable", $.extend({}, $.ui.mouse, { _init: function() { var self = this, o = this.options; var elpos = this.element.css('position'); this.originalElement = this.element; // simulate .ui-resizable { position: relative; } this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos }); $.extend(o, { _aspectRatio: !!(o.aspectRatio), helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null, knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles }); //Default Theme var aBorder = '1px solid #DEDEDE'; o.defaultTheme = { 'ui-resizable': { display: 'block' }, 'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' }, 'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder }, 'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder }, 'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder }, 'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder }, 'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder }, 'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder }, 'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder }, 'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder } }; o.knobTheme = { 'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' }, 'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' }, 'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' }, 'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' }, 'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' }, 'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' }, 'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' }, 'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' }, 'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' } }; o._nodeName = this.element[0].nodeName; //Wrap the element if it cannot hold child nodes if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) { var el = this.element; //Opera fixing relative position if (/relative/.test(el.css('position')) && $.browser.opera) el.css({ position: 'relative', top: 'auto', left: 'auto' }); //Create a wrapper element and set the wrapper to the new current internal element el.wrap( $('').css( { position: el.css('position'), width: el.outerWidth(), height: el.outerHeight(), top: el.css('top'), left: el.css('left') }) ); var oel = this.element; this.element = this.element.parent(); // store instance on wrapper this.element.data('resizable', this); //Move margins to the wrapper this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"), marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom") }); oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); //Prevent Safari textarea resize if ($.browser.safari && o.preventDefault) oel.css('resize', 'none'); o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' }); // avoid IE jump this.element.css({ margin: oel.css('margin') }); // fix handlers offset this._proportionallyResize(); } if(!o.handles) o.handles = !$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }; if(o.handles.constructor == String) { o.zIndex = o.zIndex || 1000; if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw'; var n = o.handles.split(","); o.handles = {}; // insertions are applied when don't have theme loaded var insertionsDefault = { handle: 'position: absolute; display: none; overflow:hidden;', n: 'top: 0pt; width:100%;', e: 'right: 0pt; height:100%;', s: 'bottom: 0pt; width:100%;', w: 'left: 0pt; height:100%;', se: 'bottom: 0pt; right: 0px;', sw: 'bottom: 0pt; left: 0px;', ne: 'top: 0pt; right: 0px;', nw: 'top: 0pt; left: 0px;' }; for(var i = 0; i < n.length; i++) { var handle = $.trim(n[i]), dt = o.defaultTheme, hname = 'ui-resizable-'+handle, loadDefault = !$.ui.css(hname) && !o.knobHandles, userKnobClass = $.ui.css('ui-resizable-knob-handle'), allDefTheme = $.extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = $.extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {}); // increase zIndex of sw, se, ne, nw axis var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {}; var defCss = (loadDefault ? insertionsDefault[handle] : ''), axis = $([''].join('')).css( applyZIndex ); if ('se' == handle) { axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); }; o.handles[handle] = '.ui-resizable-'+handle; this.element.append( //Theme detection, if not loaded, load o.defaultTheme axis.css( loadDefault ? allDefTheme : {} ) // Load the knobHandle css, fix width, height, top, left... .css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles) ); } if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !$.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} ); } this._renderAxis = function(target) { target = target || this.element; for(var i in o.handles) { if(o.handles[i].constructor == String) o.handles[i] = $(o.handles[i], this.element).show(); if (o.transparent) o.handles[i].css({opacity:0}); //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) if (this.element.is('.ui-wrapper') && o._nodeName.match(/textarea|input|select|button/i)) { var axis = $(o.handles[i], this.element), padWrapper = 0; //Checking the correct pad and border padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); //The padding type i have to apply... var padPos = [ 'padding', /ne|nw|n/.test(i) ? 'Top' : /se|sw|s/.test(i) ? 'Bottom' : /^e$/.test(i) ? 'Right' : 'Left' ].join(""); if (!o.transparent) target.css(padPos, padWrapper); this._proportionallyResize(); } if(!$(o.handles[i]).length) continue; } }; this._renderAxis(this.element); o._handles = $('.ui-resizable-handle', self.element); if (o.disableSelection) o._handles.disableSelection(); //Matching axis name o._handles.mouseover(function() { if (!o.resizing) { if (this.className) var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); //Axis, default = se self.axis = o.axis = axis && axis[1] ? axis[1] : 'se'; } }); //If we want to auto hide the elements if (o.autoHide) { o._handles.hide(); $(self.element).addClass("ui-resizable-autohide").hover(function() { $(this).removeClass("ui-resizable-autohide"); o._handles.show(); }, function(){ if (!o.resizing) { $(this).addClass("ui-resizable-autohide"); o._handles.hide(); } }); } this._mouseInit(); }, destroy: function() { var el = this.element, wrapped = el.children(".ui-resizable").get(0); this._mouseDestroy(); var _destroy = function(exp) { $(exp).removeClass("ui-resizable ui-resizable-disabled") .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); }; _destroy(el); if (el.is('.ui-wrapper') && wrapped) { el.parent().append( $(wrapped).css({ position: el.css('position'), width: el.outerWidth(), height: el.outerHeight(), top: el.css('top'), left: el.css('left') }) ).end().remove(); _destroy(wrapped); } }, _mouseCapture: function(event) { if(this.options.disabled) return false; var handle = false; for(var i in this.options.handles) { if($(this.options.handles[i])[0] == event.target) handle = true; } if (!handle) return false; return true; }, _mouseStart: function(event) { var o = this.options, iniPos = this.element.position(), el = this.element, num = function(v) { return parseInt(v, 10) || 0; }, ie6 = $.browser.msie && $.browser.version < 7; o.resizing = true; o.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; // bugfix #1749 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { // sOffset decides if document scrollOffset will be added to the top/left of the resizable element var sOffset = $.browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position')); var dscrollt = sOffset ? o.documentScroll.top : 0, dscrolll = sOffset ? o.documentScroll.left : 0; el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) }); } //Opera fixing relative position if ($.browser.opera && (/relative/).test(el.css('position'))) el.css({ position: 'relative', top: 'auto', left: 'auto' }); this._renderProxy(); var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); if (o.containment) { curleft += $(o.containment).scrollLeft()||0; curtop += $(o.containment).scrollTop()||0; } //Store needed variables this.offset = this.helper.offset(); this.position = { left: curleft, top: curtop }; this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; this.originalPosition = { left: curleft, top: curtop }; this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; this.originalMousePosition = { left: event.pageX, top: event.pageY }; //Aspect Ratio o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height)||1); if (o.preserveCursor) { var cursor = $('.ui-resizable-' + this.axis).css('cursor'); $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); } this._propagate("start", event); return true; }, _mouseDrag: function(event) { //Increase performance, avoid regex var el = this.helper, o = this.options, props = {}, self = this, smp = this.originalMousePosition, a = this.axis; var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; var trigger = this._change[a]; if (!trigger) return false; // Calculate the attrs that will be change var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; if (o._aspectRatio || event.shiftKey) data = this._updateRatio(data, event); data = this._respectSize(data, event); // plugins callbacks need to be called first this._propagate("resize", event); el.css({ top: this.position.top + "px", left: this.position.left + "px", width: this.size.width + "px", height: this.size.height + "px" }); if (!o.helper && o.proportionallyResize) this._proportionallyResize(); this._updateCache(data); // calling the user callback at the end this._trigger('resize', event, this.ui()); return false; }, _mouseStop: function(event) { this.options.resizing = false; var o = this.options, num = function(v) { return parseInt(v, 10) || 0; }, self = this; if(o.helper) { 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 s = { 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; if (!o.animate) this.element.css($.extend(s, { top: top, left: left })); if (o.helper && !o.animate) this._proportionallyResize(); } if (o.preserveCursor) $('body').css('cursor', 'auto'); this._propagate("stop", event); if (o.helper) this.helper.remove(); return false; }, _updateCache: function(data) { var o = this.options; this.offset = this.helper.offset(); if (data.left) this.position.left = data.left; if (data.top) this.position.top = data.top; 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; if (data.height) data.width = (csize.height * o.aspectRatio); else if (data.width) data.height = (csize.width / o.aspectRatio); if (a == 'sw') { data.left = cpos.left + (csize.width - data.width); data.top = null; } if (a == 'nw') { data.top = cpos.top + (csize.height - data.height); data.left = cpos.left + (csize.width - data.width); } return data; }, _respectSize: function(data, event) { var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis, ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height, isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height; if (isminw) data.width = o.minWidth; if (isminh) data.height = o.minHeight; if (ismaxw) data.width = o.maxWidth; if (ismaxh) data.height = o.maxHeight; var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); if (isminw && cw) data.left = dw - o.minWidth; if (ismaxw && cw) data.left = dw - o.maxWidth; if (isminh && ch) data.top = dh - o.minHeight; if (ismaxh && ch) data.top = dh - o.maxHeight; // fixing jump error on top/left - bug #2330 var isNotwh = !data.width && !data.height; if (isNotwh && !data.left && data.top) data.top = null; else if (isNotwh && !data.top && data.left) data.left = null; return data; }, _proportionallyResize: function() { var o = this.options; if (!o.proportionallyResize) return; var prel = o.proportionallyResize, el = this.helper || this.element; if (!o.borderDif) { var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; o.borderDif = $.map(b, function(v, i) { var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; return border + padding; }); } if ($.browser.msie && !isVisible(el)) return; prel.css({ height: (el.height() - o.borderDif[0] - o.borderDif[2]) || 0, width: (el.width() - o.borderDif[1] - o.borderDif[3]) || 0 }); }, _renderProxy: function() { var el = this.element, o = this.options; this.elementOffset = el.offset(); if(o.helper) { this.helper = this.helper || $(''); // fix ie6 offset var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), pxyoffset = ( ie6 ? 2 : -1 ); this.helper.addClass(o.helper).css({ width: el.outerWidth() + pxyoffset, height: el.outerHeight() + pxyoffset, position: 'absolute', left: this.elementOffset.left - ie6offset +'px', top: this.elementOffset.top - ie6offset +'px', zIndex: ++o.zIndex }); this.helper.appendTo("body"); if (o.disableSelection) this.helper.disableSelection(); } else { this.helper = el; } }, _change: { e: function(event, dx, dy) { return { width: this.originalSize.width + dx }; }, w: function(event, dx, dy) { var o = this.options, cs = this.originalSize, sp = this.originalPosition; return { left: sp.left + dx, width: cs.width - dx }; }, n: function(event, dx, dy) { var o = this.options, cs = this.originalSize, sp = this.originalPosition; return { top: sp.top + dy, height: cs.height - dy }; }, s: function(event, dx, dy) { return { height: this.originalSize.height + dy }; }, se: function(event, dx, dy) { return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); }, sw: function(event, dx, dy) { return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); }, ne: function(event, dx, dy) { return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); }, 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()]); (n != "resize" && this._trigger(n, event, this.ui())); }, 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, { version: "1.6rc5", eventPrefix: "resize", defaults: { alsoResize: false, animate: false, animateDuration: "slow", animateEasing: "swing", aspectRatio: false, autoHide: false, cancel: ":input,option", containment: false, delay: 0, disableSelection: true, distance: 1, ghost: false, grid: false, knobHandles: false, maxHeight: null, maxWidth: null, minHeight: 10, minWidth: 10, preserveCursor: true, preventDefault: true, proportionallyResize: false, transparent: false } }); /* * 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' && !o.alsoResize.parentNode) { 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 el = $(this), 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; }); //Opera fixing relative position if (/relative/.test(el.css('position')) && $.browser.opera) { self._revertToRelativePosition = true; el.css({ position: 'absolute', top: 'auto', left: 'auto' }); } el.css(style); }); }; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); }); }else{ _alsoResize(o.alsoResize); } }, stop: function(event, ui){ var self = $(this).data("resizable"); //Opera fixing relative position if (self._revertToRelativePosition && $.browser.opera) { self._revertToRelativePosition = false; el.css({ position: 'relative' }); } $(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("resize", event); } } ); } }); $.ui.plugin.add("resizable", "containment", { start: function(event, ui) { var o = ui.options, self = $(this).data("resizable"), el = self.element; var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; if (!ce) return; self.containerElement = $(ce); if (/document/.test(oc) || oc == document) { self.containerOffset = { left: 0, top: 0 }; self.containerPosition = { left: 0, top: 0 }; self.parentData = { element: $(document), left: 0, top: 0, width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight }; } // i'm a node, so compute top, left, right, bottom else{ self.containerOffset = $(ce).offset(); self.containerPosition = $(ce).position(); self.containerSize = { height: $(ce).innerHeight(), width: $(ce).innerWidth() }; var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); self.parentData = { element: ce, left: co.left, top: co.top, width: width, height: height }; } }, resize: function(event, ui) { var o = ui.options, self = $(this).data("resizable"), ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; if (ce[0] != document && (/static/).test(ce.css('position'))) cop = self.containerPosition; if (cp.left < (o.helper ? co.left : 0)) { self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left)); if (pRatio) self.size.height = self.size.width / o.aspectRatio; self.position.left = o.helper ? co.left : 0; } if (cp.top < (o.helper ? co.top : 0)) { self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top); if (pRatio) self.size.width = self.size.height * o.aspectRatio; self.position.top = o.helper ? co.top : 0; } var woset = Math.abs( (o.helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), hoset = Math.abs( (o.helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); if (woset + self.size.width >= self.parentData.width) { self.size.width = self.parentData.width - woset; if (pRatio) self.size.height = self.size.width / o.aspectRatio; } if (hoset + self.size.height >= self.parentData.height) { self.size.height = self.parentData.height - hoset; if (pRatio) self.size.width = self.size.height * o.aspectRatio; } }, stop: function(event, ui){ var o = ui.options, self = $(this).data("resizable"), cp = self.position, co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; if (o.helper && !o.animate && (/relative/).test(ce.css('position'))) $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); if (o.helper && !o.animate && (/static/).test(ce.css('position'))) $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); } }); $.ui.plugin.add("resizable", "ghost", { start: function(event, ui) { var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize, cs = self.size; if (!pr) self.ghost = self.element.clone(); else self.ghost = pr.clone(); self.ghost.css( { opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 } ) .addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : ''); self.ghost.appendTo(self.helper); }, resize: function(event, ui){ var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize; if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); }, stop: function(event, ui){ var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize; if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); } }); $.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; } } }); function isVisible(element) { return !($(element).is(':hidden') || $(element).parents(':hidden').length); } })(jQuery); /* * jQuery UI Selectable 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Selectables * * Depends: * ui.core.js */ (function($) { $.widget("ui.selectable", $.extend({}, $.ui.mouse, { _init: function() { var self = this; this.element.addClass("ui-selectable"); this.dragged = false; // cache selectee children based on filter var selectees; this.refresh = function() { selectees = $(self.options.filter, self.element[0]); selectees.each(function() { var $this = $(this); var pos = $this.offset(); $.data(this, "selectable-item", { element: this, $element: $this, left: pos.left, top: pos.top, right: pos.left + $this.outerWidth(), bottom: pos.top + $this.outerHeight(), startselected: false, selected: $this.hasClass('ui-selected'), selecting: $this.hasClass('ui-selecting'), unselecting: $this.hasClass('ui-unselecting') }); }); }; this.refresh(); this.selectees = selectees.addClass("ui-selectee"); this._mouseInit(); this.helper = $(document.createElement('div')) .css({border:'1px dotted black'}) .addClass("ui-selectable-helper"); }, destroy: function() { this.element .removeClass("ui-selectable ui-selectable-disabled") .removeData("selectable") .unbind(".selectable"); this._mouseDestroy(); }, _mouseStart: function(event) { var self = this; this.opos = [event.pageX, event.pageY]; if (this.options.disabled) return; var options = this.options; this.selectees = $(options.filter, this.element[0]); this._trigger("start", event); $('body').append(this.helper); // position helper (lasso) this.helper.css({ "z-index": 100, "position": "absolute", "left": event.clientX, "top": event.clientY, "width": 0, "height": 0 }); if (options.autoRefresh) { this.refresh(); } this.selectees.filter('.ui-selected').each(function() { var selectee = $.data(this, "selectable-item"); selectee.startselected = true; if (!event.metaKey) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } }); $(event.target).parents().andSelf().each(function() { var selectee = $.data(this, "selectable-item"); if (selectee) { selectee.$element.removeClass("ui-unselecting").addClass('ui-selecting'); selectee.unselecting = false; selectee.selecting = true; selectee.selected = true; // selectable SELECTING callback self._trigger("selecting", event, { selecting: selectee.element }); return false; } }); }, _mouseDrag: function(event) { var self = this; this.dragged = true; if (this.options.disabled) return; var options = this.options; var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); this.selectees.each(function() { var selectee = $.data(this, "selectable-item"); //prevent helper from being selected if appendTo: selectable if (!selectee || selectee.element == self.element[0]) return; var hit = false; if (options.tolerance == 'touch') { hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); } else if (options.tolerance == 'fit') { hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); } if (hit) { // SELECT if (selectee.selected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; } if (selectee.unselecting) { selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; } if (!selectee.selecting) { selectee.$element.addClass('ui-selecting'); selectee.selecting = true; // selectable SELECTING callback self._trigger("selecting", event, { selecting: selectee.element }); } } else { // UNSELECT if (selectee.selecting) { if (event.metaKey && selectee.startselected) { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; selectee.$element.addClass('ui-selected'); selectee.selected = true; } else { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; if (selectee.startselected) { selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; } // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } if (selectee.selected) { if (!event.metaKey && !selectee.startselected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } } }); return false; }, _mouseStop: function(event) { var self = this; this.dragged = false; var options = this.options; $('.ui-unselecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; selectee.startselected = false; self._trigger("unselected", event, { unselected: selectee.element }); }); $('.ui-selecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); selectee.selecting = false; selectee.selected = true; selectee.startselected = true; self._trigger("selected", event, { selected: selectee.element }); }); this._trigger("stop", event); this.helper.remove(); return false; } })); $.extend($.ui.selectable, { version: "1.6rc5", defaults: { appendTo: 'body', autoRefresh: true, cancel: ":input,option", delay: 0, distance: 0, filter: '*', tolerance: 'touch' } }); })(jQuery); /* * jQuery UI Sortable 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Sortables * * Depends: * ui.core.js */ (function($) { $.widget("ui.sortable", $.extend({}, $.ui.mouse, { _init: function() { var o = this.options; this.containerCache = {}; (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-sortable")); //Get the items this.refresh(); //Let's determine if the items are floating this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false; //Let's determine the parent's offset this.offset = this.element.offset(); //Initialize mouse events for interaction this._mouseInit(); }, destroy: function() { this.element .removeClass(this.options.cssNamespace+"-sortable "+this.options.cssNamespace+"-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); //Cache the helper size this._cacheHelperProportions(); /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Get the next scrolling parent this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.currentItem.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible this.helper.css("position", "absolute"); this.cssPosition = this.helper.css("position"); $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); //Generate the original position this.originalPosition = this._generatePosition(event); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied if(o.cursorAt) this._adjustOffsetFromHelper(o.cursorAt); //Cache the former DOM position this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; //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 if(this.helper[0] != this.currentItem[0]) { this.currentItem.hide(); } //Create the placeholder this._createPlaceholder(); //Set a containment if given in the options if(o.containment) this._setContainment(); //Call plugins and callbacks this._trigger("start", event); //Recache the helper size if(!this._preserveHelperProportions) this._cacheHelperProportions(); //Post 'activate' events to possible containers if(!noActivation) { for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("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.helper.addClass(o.cssNamespace+'-sortable-helper'); 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._uiHash()]); //Regenerate the absolute position used for position checks this.positionAbs = this._convertPositionTo("absolute"); //Set the helper 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'; //Rearrange for (var i = this.items.length - 1; i >= 0; i--) { //Cache variables and intersection, continue if no intersection var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); if (!intersection) continue; if(itemElement != this.currentItem[0] //cannot intersect with itself && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) ) { this.direction = intersection == 1 ? "down" : "up"; if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { this.options.sortIndicator.call(this, event, item); } else { break; } this._trigger("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._trigger('sort', event); 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() { if(this.dragging) { this._mouseUp(); if(this.options.helper == "original") this.currentItem.css(this._storedCSS).removeClass(this.options.cssNamespace+"-sortable-helper"); else this.currentItem.show(); //Post deactivating events to containers for (var i = this.containers.length - 1; i >= 0; i--){ this.containers[i]._trigger("deactivate", null, this); if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", null, this); this.containers[i].containerCache.over = 0; } } } //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); $.extend(this, { helper: null, dragging: false, reverting: false, _noFinalSort: null }); if(this.domPosition.prev) { $(this.domPosition.prev).after(this.currentItem); } else { $(this.domPosition.parent).prepend(this.currentItem); } return true; }, serialize: function(o) { var items = this._getItemsAsjQuery(o && o.connected); var str = []; o = o || {}; $(items).each(function() { var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); }); return str.join('&'); }, toArray: function(o) { var items = this._getItemsAsjQuery(o && o.connected); var ret = []; o = o || {}; items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); return ret; }, /* Be careful with the following core functions */ _intersectsWith: function(item) { var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width, y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height; var l = item.left, r = l + item.width, t = item.top, b = t + item.height; var dyClick = this.offset.click.top, dxClick = this.offset.click.left; var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; if( this.options.tolerance == "pointer" || this.options.forcePointerForContainers || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) ) { return isOverElement; } else { return (l < x1 + (this.helperProportions.width / 2) // Right Half && x2 - (this.helperProportions.width / 2) < r // Left Half && t < y1 + (this.helperProportions.height / 2) // Bottom Half && y2 - (this.helperProportions.height / 2) < b ); // Top Half } }, _intersectsWithPointer: function(item) { var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), isOverElement = isOverElementHeight && isOverElementWidth, verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if (!isOverElement) return false; return this.floating ? ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); }, _intersectsWithSides: function(item) { var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if (this.floating && horizontalDirection) { return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); } else { return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); } }, _getDragVerticalDirection: function() { var delta = this.positionAbs.top - this.lastPositionAbs.top; return delta != 0 && (delta > 0 ? "down" : "up"); }, _getDragHorizontalDirection: function() { var delta = this.positionAbs.left - this.lastPositionAbs.left; return delta != 0 && (delta > 0 ? "right" : "left"); }, refresh: function(event) { this._refreshItems(event); this.refreshPositions(); }, _getItemsAsjQuery: function(connected) { var self = this; var items = []; var queries = []; if(this.options.connectWith && connected) { for (var i = this.options.connectWith.length - 1; i >= 0; i--){ var cur = $(this.options.connectWith[i]); for (var j = cur.length - 1; j >= 0; j--){ var inst = $.data(cur[j], 'sortable'); if(inst && inst != this && !inst.options.disabled) { queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not("."+inst.options.cssNamespace+"-sortable-helper"), inst]); } }; }; } queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not("."+this.options.cssNamespace+"-sortable-helper"), this]); for (var i = queries.length - 1; i >= 0; i--){ queries[i][0].each(function() { items.push(this); }); }; return $(items); }, _removeCurrentsFromItems: function() { var list = this.currentItem.find(":data(sortable-item)"); for (var i=0; i < this.items.length; i++) { for (var j=0; j < list.length; j++) { if(list[j] == this.items[i].item[0]) this.items.splice(i,1); }; }; }, _refreshItems: function(event) { this.items = []; this.containers = [this]; var items = this.items; var self = this; var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; if(this.options.connectWith) { for (var i = this.options.connectWith.length - 1; i >= 0; i--){ var cur = $(this.options.connectWith[i]); for (var j = cur.length - 1; j >= 0; j--){ var inst = $.data(cur[j], 'sortable'); if(inst && inst != this && !inst.options.disabled) { queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); this.containers.push(inst); } }; }; } for (var i = queries.length - 1; i >= 0; i--) { var targetData = queries[i][1]; var _queries = queries[i][0]; for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { var item = $(_queries[j]); item.data('sortable-item', targetData); // Data for target checking (mouse manager) items.push({ item: item, instance: targetData, width: 0, height: 0, left: 0, top: 0 }); }; }; }, refreshPositions: function(fast) { //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change if(this.offsetParent && this.helper) { this.offset.parent = this._getParentOffset(); } for (var i = this.items.length - 1; i >= 0; i--){ var item = this.items[i]; //We ignore calculating positions of all connected containers when we're not over them if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) continue; var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; if (!fast) { if (this.options.accurateIntersection) { item.width = t.outerWidth(); item.height = t.outerHeight(); } else { item.width = t[0].offsetWidth; item.height = t[0].offsetHeight; } } var p = t.offset(); item.left = p.left; item.top = p.top; }; if(this.options.custom && this.options.custom.refreshContainers) { this.options.custom.refreshContainers.call(this); } else { for (var i = this.containers.length - 1; i >= 0; i--){ var p = this.containers[i].element.offset(); this.containers[i].containerCache.left = p.left; this.containers[i].containerCache.top = p.top; this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); }; } }, _createPlaceholder: function(that) { var self = that || this, o = self.options; if(!o.placeholder || o.placeholder.constructor == String) { var className = o.placeholder; o.placeholder = { element: function() { var el = $(document.createElement(self.currentItem[0].nodeName)) .addClass(className || self.currentItem[0].className+" "+self.options.cssNamespace+"-sortable-placeholder") .removeClass(self.options.cssNamespace+'-sortable-helper')[0]; if(!className) el.style.visibility = "hidden"; return el; }, update: function(container, p) { // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified if(className && !o.forcePlaceholderSize) return; //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 if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); }; if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); }; } }; } //Create the placeholder self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)); //Append it after the actual current item self.currentItem.after(self.placeholder); //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) o.placeholder.update(self, self.placeholder); }, _contactContainers: function(event) { for (var i = this.containers.length - 1; i >= 0; i--){ if(this._intersectsWith(this.containers[i].containerCache)) { if(!this.containers[i].containerCache.over) { if(this.currentContainer != this.containers[i]) { //When entering a new container, we will find the item with the least distance and append our item near it var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top']; for (var j = this.items.length - 1; j >= 0; j--) { if(!$.ui.contains(this.containers[i].element[0], this.items[j].item[0])) continue; var cur = this.items[j][this.containers[i].floating ? 'left' : 'top']; if(Math.abs(cur - base) < dist) { dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; } } if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled continue; this.currentContainer = this.containers[i]; itemWithLeastDistance ? this.options.sortIndicator.call(this, event, itemWithLeastDistance, null, true) : this.options.sortIndicator.call(this, event, null, this.containers[i].element, true); this._trigger("change", event); //Call plugins and callbacks this.containers[i]._trigger("change", event, this); //Call plugins and callbacks //Update the placeholder this.options.placeholder.update(this.currentContainer, this.placeholder); } this.containers[i]._trigger("over", event, this); this.containers[i].containerCache.over = 1; } } else { if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", event, this); this.containers[i].containerCache.over = 0; } } }; }, _createHelper: function(event) { var o = this.options; var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); if(helper[0] == this.currentItem[0]) this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); return helper; }, _adjustOffsetFromHelper: function(obj) { if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left; if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top; if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } if((this.offsetParent[0] == document.body && $.browser.mozilla) //Ugly FF3 fix || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix po = { top: 0, left: 0 }; return { top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) }; }, _getRelativeOffset: function() { if(this.cssPosition == "relative") { var p = this.currentItem.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), top: (parseInt(this.currentItem.css("marginTop"),10) || 0) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; 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.margins.left, co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.margins.top, co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.helperProportions.width - this.margins.left, co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.helperProportions.height - this.margins.top ]; } }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; 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); return { top: ( pos.top // The absolute mouse position + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ), left: ( pos.left // The absolute mouse position + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod ) }; }, _generatePosition: function(event) { 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); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative // 2. and the scroll parent is the document or similar to the offset parent // we have to refresh the relative offset during the scroll so there are no jumps if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { this.offset.relative = this._getRelativeOffset(); } var pageX = event.pageX; var pageY = event.pageY; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options if(this.containment) { if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; } if(o.grid) { var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; 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; var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; 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; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) }; }, _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)); //Various things done here to improve the performance: // 1. we create a setTimeout, that calls refreshPositions // 2. on the instance, we have a counter variable, that get's higher after every append // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same // 4. this lets only the last addition to the timeout stack through this.counter = this.counter ? ++this.counter : 1; var self = this, counter = this.counter; window.setTimeout(function() { if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove },0); }, _clear: function(event, noPropagation) { this.reverting = false; //We first have to update the dom position of the actual currentItem if(!this._noFinalSort) this.placeholder.before(this.currentItem); this._noFinalSort = null; if(this.helper[0] == this.currentItem[0]) { for(var i in this._storedCSS) { if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; } this.currentItem.css(this._storedCSS).removeClass(this.options.cssNamespace+"-sortable-helper"); } else { this.currentItem.show(); } if(this.fromOutside) this._trigger("receive", event, this, noPropagation); if(this.fromOutside || this.domPosition.prev != this.currentItem.prev().not("."+this.options.cssNamespace+"-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) this._trigger("update", event, null, noPropagation); //Trigger update callback if the DOM position has changed if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element this._trigger("remove", event, null, noPropagation); for (var i = this.containers.length - 1; i >= 0; i--){ if($.ui.contains(this.containers[i].element[0], this.currentItem[0])) { this.containers[i]._trigger("receive", event, this, noPropagation); this.containers[i]._trigger("update", event, this, noPropagation); } }; }; //Post events to containers for (var i = this.containers.length - 1; i >= 0; i--){ this.containers[i]._trigger("deactivate", event, this, noPropagation); if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", event, this); this.containers[i].containerCache.over = 0; } } this.dragging = false; if(this.cancelHelperRemoval) { this._trigger("beforeStop", event, null, noPropagation); this._trigger("stop", event, null, noPropagation); return false; } this._trigger("beforeStop", event, null, noPropagation); //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! this.placeholder[0].parentNode.removeChild(this.placeholder[0]); if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; this._trigger("stop", event, null, noPropagation); this.fromOutside = false; return true; }, _trigger: function(type, event, inst, noPropagation) { $.ui.plugin.call(this, type, [event, this._uiHash(inst)]); if(!noPropagation) { if ($.widget.prototype._trigger.call(this, type, event, this._uiHash(inst)) === false) { this.cancel(); } } }, plugins: {}, _uiHash: 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: "1.6rc5", defaults: { accurateIntersection: true, appendTo: "parent", cancel: ":input,option", cssNamespace: 'ui', delay: 0, distance: 1, dropOnEmpty: true, forcePlaceholderSize: false, forceHelperSize: false, helper: "original", items: '> *', scope: "default", scroll: true, scrollSensitivity: 20, scrollSpeed: 20, sortIndicator: $.ui.sortable.prototype._rearrange, tolerance: "default", zIndex: 1000 } }); /* * Sortable Extensions */ $.ui.plugin.add("sortable", "cursor", { start: function(event, ui) { var t = $('body'), i = $(this).data('sortable'); if (t.css("cursor")) i.options._cursor = t.css("cursor"); t.css("cursor", i.options.cursor); }, beforeStop: function(event, ui) { var i = $(this).data('sortable'); if (i.options._cursor) $('body').css("cursor", i.options._cursor); } }); $.ui.plugin.add("sortable", "opacity", { start: function(event, ui) { var t = ui.helper, i = $(this).data('sortable'); if(t.css("opacity")) i.options._opacity = t.css("opacity"); t.css('opacity', i.options.opacity); }, beforeStop: function(event, ui) { var i = $(this).data('sortable'); if(i.options._opacity) $(ui.helper).css('opacity', i.options._opacity); } }); $.ui.plugin.add("sortable", "scroll", { start: function(event, ui) { var i = $(this).data("sortable"), o = i.options; if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); }, sort: function(event, ui) { var i = $(this).data("sortable"), o = i.options, scrolled = false; if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; } else { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(i, event); } }); $.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 == 'auto' ? '' : i.options._zIndex); } }); })(jQuery); /* * jQuery UI Effects 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/ */ ;(function($) { $.effects = $.effects || {}; //Add the 'effects' scope $.extend($.effects, { version: "1.6rc5", // Saves a set of properties in a data storage save: function(element, set) { for(var i=0; i < set.length; i++) { if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]); } }, // Restores a set of previously saved properties from a data storage restore: function(element, set) { for(var i=0; i < set.length; i++) { if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i])); } }, setMode: function(el, mode) { if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle return mode; }, getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value // this should be a little more flexible in the future to handle a string & hash var y, x; switch (origin[0]) { case 'top': y = 0; break; case 'middle': y = 0.5; break; case 'bottom': y = 1; break; default: y = origin[0] / original.height; }; switch (origin[1]) { case 'left': x = 0; break; case 'center': x = 0.5; break; case 'right': x = 1; break; default: x = origin[1] / original.width; }; return {x: x, y: y}; }, // Wraps the element around a wrapper that copies position properties createWrapper: function(element) { //if the element is already wrapped, return it if (element.parent().is('.ui-effects-wrapper')) return element.parent(); //Cache width,height and float properties of the element, and create a wrapper around it var props = { width: element.outerWidth(true), height: element.outerHeight(true), 'float': element.css('float') }; element.wrap(''); var wrapper = element.parent(); //Transfer the positioning of the element to the wrapper if (element.css('position') == 'static') { wrapper.css({ position: 'relative' }); element.css({ position: 'relative'} ); } else { var top = element.css('top'); if(isNaN(parseInt(top,10))) top = 'auto'; var left = element.css('left'); if(isNaN(parseInt(left,10))) left = 'auto'; wrapper.css({ position: element.css('position'), top: top, left: left, zIndex: element.css('z-index') }).show(); element.css({position: 'relative', top: 0, left: 0 }); } wrapper.css(props); return wrapper; }, removeWrapper: function(element) { if (element.parent().is('.ui-effects-wrapper')) return element.parent().replaceWith(element); return element; }, setTransition: function(element, list, factor, value) { value = value || {}; $.each(list, function(i, x){ unit = element.cssUnit(x); if (unit[0] > 0) value[x] = unit[0] * factor + unit[1]; }); return value; }, //Base function to animate from one class to another in a seamless transition animateClass: function(value, duration, easing, callback) { var cb = (typeof easing == "function" ? easing : (callback ? callback : null)); var ea = (typeof easing == "string" ? easing : null); return this.each(function() { var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || ''; if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */ if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; } //Let's get a style offset var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle)); if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove); var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle)); if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove); // The main function to form the object for animation for(var n in newStyle) { if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */ && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */ && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */ && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */ && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */ ) offset[n] = newStyle[n]; } that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object // Change style attribute back to original. For stupid IE, we need to clear the damn object. if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr); if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove); if(cb) cb.apply(this, arguments); }); }); } }); //Extend the methods of jQuery $.fn.extend({ //Save old methods _show: $.fn.show, _hide: $.fn.hide, __toggle: $.fn.toggle, _addClass: $.fn.addClass, _removeClass: $.fn.removeClass, _toggleClass: $.fn.toggleClass, // New effect methods effect: function(fx, options, speed, callback) { return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: options || {}, duration: speed, callback: callback }) : null; }, show: function() { if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0]))) return this._show.apply(this, arguments); else { var o = arguments[1] || {}; o['mode'] = 'show'; return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); } }, hide: function() { if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0]))) return this._hide.apply(this, arguments); else { var o = arguments[1] || {}; o['mode'] = 'hide'; return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); } }, toggle: function(){ if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) || (arguments[0].constructor == Function)) return this.__toggle.apply(this, arguments); else { var o = arguments[1] || {}; o['mode'] = 'toggle'; return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]); } }, addClass: function(classNames, speed, easing, callback) { return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); }, removeClass: function(classNames,speed,easing,callback) { return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); }, toggleClass: function(classNames,speed,easing,callback) { return speed ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames); }, morph: function(remove,add,speed,easing,callback) { return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); }, switchClass: function() { return this.morph.apply(this, arguments); }, // helper functions cssUnit: function(key) { var style = this.css(key), val = []; $.each( ['em','px','%','pt'], function(i, unit){ if(style.indexOf(unit) > 0) val = [parseFloat(style), unit]; }); return val; } }); /* * jQuery Color Animations * Copyright 2007 John Resig * Released under the MIT and GPL licenses. */ // We override the animation for all of these color styles $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){ $.fx.step[attr] = function(fx) { if ( fx.state == 0 ) { fx.start = getColor( fx.elem, attr ); fx.end = getRGB( fx.end ); } fx.elem.style[attr] = "rgb(" + [ Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0],10), 255), 0), Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1],10), 255), 0), Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2],10), 255), 0) ].join(",") + ")"; }; }); // Color Conversion functions from highlightFade // By Blair Mitchelmore // http://jquery.offput.ca/highlightFade/ // Parse strings looking for color tuples [255,255,255] function getRGB(color) { var result; // Check if we're already dealing with an array of colors if ( color && color.constructor == Array && color.length == 3 ) return color; // Look for rgb(num,num,num) if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; // Look for rgb(num%,num%,num%) if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; // Look for #a0b1c2 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; // Look for #fff if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return colors['transparent']; // Otherwise, we're most likely dealing with a named color return colors[$.trim(color).toLowerCase()]; } function getColor(elem, attr) { var color; do { color = $.curCSS(elem, attr); // Keep going until we find an element that has color, or we hit the body if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) break; attr = "backgroundColor"; } while ( elem = elem.parentNode ); return getRGB(color); }; // Some named colors to work with // From Interface by Stefan Petre // http://interface.eyecon.ro/ var colors = { aqua:[0,255,255], azure:[240,255,255], beige:[245,245,220], black:[0,0,0], blue:[0,0,255], brown:[165,42,42], cyan:[0,255,255], darkblue:[0,0,139], darkcyan:[0,139,139], darkgrey:[169,169,169], darkgreen:[0,100,0], darkkhaki:[189,183,107], darkmagenta:[139,0,139], darkolivegreen:[85,107,47], darkorange:[255,140,0], darkorchid:[153,50,204], darkred:[139,0,0], darksalmon:[233,150,122], darkviolet:[148,0,211], fuchsia:[255,0,255], gold:[255,215,0], green:[0,128,0], indigo:[75,0,130], khaki:[240,230,140], lightblue:[173,216,230], lightcyan:[224,255,255], lightgreen:[144,238,144], lightgrey:[211,211,211], lightpink:[255,182,193], lightyellow:[255,255,224], lime:[0,255,0], magenta:[255,0,255], maroon:[128,0,0], navy:[0,0,128], olive:[128,128,0], orange:[255,165,0], pink:[255,192,203], purple:[128,0,128], violet:[128,0,128], red:[255,0,0], silver:[192,192,192], white:[255,255,255], yellow:[255,255,0], transparent: [255,255,255] }; /* * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ * * Uses the built in easing capabilities added In jQuery 1.1 * to offer multiple easing options * * TERMS OF USE - jQuery Easing * * Open source under the BSD License. * * Copyright © 2008 George McGinley Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the author nor the names of contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ // t: current time, b: begInnIng value, c: change In value, d: duration $.easing.jswing = $.easing.swing; $.extend($.easing, { def: 'easeOutQuad', swing: function (x, t, b, c, d) { //alert($.easing.default); return $.easing[$.easing.def](x, t, b, c, d); }, easeInQuad: function (x, t, b, c, d) { return c*(t/=d)*t + b; }, easeOutQuad: function (x, t, b, c, d) { return -c *(t/=d)*(t-2) + b; }, easeInOutQuad: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; }, easeInCubic: function (x, t, b, c, d) { return c*(t/=d)*t*t + b; }, easeOutCubic: function (x, t, b, c, d) { return c*((t=t/d-1)*t*t + 1) + b; }, easeInOutCubic: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t + b; return c/2*((t-=2)*t*t + 2) + b; }, easeInQuart: function (x, t, b, c, d) { return c*(t/=d)*t*t*t + b; }, easeOutQuart: function (x, t, b, c, d) { return -c * ((t=t/d-1)*t*t*t - 1) + b; }, easeInOutQuart: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t*t + b; return -c/2 * ((t-=2)*t*t*t - 2) + b; }, easeInQuint: function (x, t, b, c, d) { return c*(t/=d)*t*t*t*t + b; }, easeOutQuint: function (x, t, b, c, d) { return c*((t=t/d-1)*t*t*t*t + 1) + b; }, easeInOutQuint: function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; return c/2*((t-=2)*t*t*t*t + 2) + b; }, easeInSine: function (x, t, b, c, d) { return -c * Math.cos(t/d * (Math.PI/2)) + c + b; }, easeOutSine: function (x, t, b, c, d) { return c * Math.sin(t/d * (Math.PI/2)) + b; }, easeInOutSine: function (x, t, b, c, d) { return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; }, easeInExpo: function (x, t, b, c, d) { return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; }, easeOutExpo: function (x, t, b, c, d) { return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; }, easeInOutExpo: function (x, t, b, c, d) { if (t==0) return b; if (t==d) return b+c; if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; }, easeInCirc: function (x, t, b, c, d) { return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; }, easeOutCirc: function (x, t, b, c, d) { return c * Math.sqrt(1 - (t=t/d-1)*t) + b; }, easeInOutCirc: function (x, t, b, c, d) { if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; }, easeInElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; }, easeOutElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; }, easeInOutElastic: function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; }, easeInBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c*(t/=d)*t*((s+1)*t - s) + b; }, easeOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; }, easeInOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; }, easeInBounce: function (x, t, b, c, d) { return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b; }, easeOutBounce: function (x, t, b, c, d) { if ((t/=d) < (1/2.75)) { return c*(7.5625*t*t) + b; } else if (t < (2/2.75)) { return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; } else if (t < (2.5/2.75)) { return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; } else { return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; } }, easeInOutBounce: function (x, t, b, c, d) { if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; } }); /* * * TERMS OF USE - EASING EQUATIONS * * Open source under the BSD License. * * Copyright © 2001 Robert Penner * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the author nor the names of contributors may be used to endorse * or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ })(jQuery); /* * jQuery UI Effects Blind 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Blind * * Depends: * effects.core.js */ (function($) { $.effects.blind = function(o) { return this.queue(function() { // Create element var el = $(this), props = ['position','top','left']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode var direction = o.options.direction || 'vertical'; // Default direction // Adjust $.effects.save(el, props); el.show(); // Save & Show var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper var ref = (direction == 'vertical') ? 'height' : 'width'; var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width(); if(mode == 'show') wrapper.css(ref, 0); // Shift // Animation var animation = {}; animation[ref] = mode == 'show' ? distance : 0; // Animate wrapper.animate(animation, o.duration, o.options.easing, function() { if(mode == 'hide') el.hide(); // Hide $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(el[0], arguments); // Callback el.dequeue(); }); }); }; })(jQuery); /* * jQuery UI Effects Bounce 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Bounce * * Depends: * effects.core.js */ (function($) { $.effects.bounce = function(o) { return this.queue(function() { // Create element var el = $(this), props = ['position','top','left']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode var direction = o.options.direction || 'up'; // Default direction var distance = o.options.distance || 20; // Default distance var times = o.options.times || 5; // Default # of times var speed = o.duration || 250; // Default speed per bounce if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE // Adjust $.effects.save(el, props); el.show(); // Save & Show $.effects.createWrapper(el); // Create Wrapper var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3); if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift if (mode == 'hide') distance = distance / (times * 2); if (mode != 'hide') times--; // Animate if (mode == 'show') { // Show Bounce var animation = {opacity: 1}; animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance; el.animate(animation, speed / 2, o.options.easing); distance = distance / 2; times--; }; for (var i = 0; i < times; i++) { // Bounces var animation1 = {}, animation2 = {}; animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing); distance = (mode == 'hide') ? distance * 2 : distance / 2; }; if (mode == 'hide') { // Last Bounce var animation = {opacity: 0}; animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; el.animate(animation, speed / 2, o.options.easing, function(){ el.hide(); // Hide $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(this, arguments); // Callback }); } else { var animation1 = {}, animation2 = {}; animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(this, arguments); // Callback }); }; el.queue('fx', function() { el.dequeue(); }); el.dequeue(); }); }; })(jQuery); /* * jQuery UI Effects Clip 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Clip * * Depends: * effects.core.js */ (function($) { $.effects.clip = function(o) { return this.queue(function() { // Create element var el = $(this), props = ['position','top','left','height','width']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode var direction = o.options.direction || 'vertical'; // Default direction // Adjust $.effects.save(el, props); el.show(); // Save & Show var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper var animate = el[0].tagName == 'IMG' ? wrapper : el; var ref = { size: (direction == 'vertical') ? 'height' : 'width', position: (direction == 'vertical') ? 'top' : 'left' }; var distance = (direction == 'vertical') ? animate.height() : animate.width(); if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift // Animation var animation = {}; animation[ref.size] = mode == 'show' ? distance : 0; animation[ref.position] = mode == 'show' ? 0 : distance / 2; // Animate animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { if(mode == 'hide') el.hide(); // Hide $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(el[0], arguments); // Callback el.dequeue(); }}); }); }; })(jQuery); /* * jQuery UI Effects Drop 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Drop * * Depends: * effects.core.js */ (function($) { $.effects.drop = function(o) { return this.queue(function() { // Create element var el = $(this), props = ['position','top','left','opacity']; // Set options var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode var direction = o.options.direction || 'left'; // Default Direction // Adjust $.effects.save(el, props); el.show(); // Save & Show $.effects.createWrapper(el); // Create Wrapper var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2); if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift // Animation var animation = {opacity: mode == 'show' ? 1 : 0}; animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; // Animate el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { if(mode == 'hide') el.hide(); // Hide $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(this, arguments); // Callback el.dequeue(); }}); }); }; })(jQuery); /* * jQuery UI Effects Explode 1.6rc5 * * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Explode * * Depends: * effects.core.js */ (function($) { $.effects.explode = function(o) { return this.queue(function() { var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode; var el = $(this).show().css('visibility', 'hidden'); var offset = el.offset(); //Substract the margins - not fixing the problem yet. offset.top -= parseInt(el.css("marginTop")) || 0; offset.left -= parseInt(el.css("marginLeft")) || 0; var width = el.outerWidth(true); var height = el.outerHeight(true); for(var i=0;i= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + '' + dayNamesMin[day] + ' | '; } calender += thead + '
---|
' + // actions (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months (unselectable ? '' + printDate.getDate() + '' : '' + printDate.getDate() + '')) + ' | '; // display for this month printDate.setDate(printDate.getDate() + 1); printDate = this._daylightSavingAdjust(printDate); } calender += tbody + '