diff options
Diffstat (limited to 'libs/jquery/original lib/jquery-ui.js')
-rw-r--r-- | libs/jquery/original lib/jquery-ui.js | 5586 |
1 files changed, 3750 insertions, 1836 deletions
diff --git a/libs/jquery/original lib/jquery-ui.js b/libs/jquery/original lib/jquery-ui.js index fc3a87fabe..5b1595b3f2 100644 --- a/libs/jquery/original lib/jquery-ui.js +++ b/libs/jquery/original lib/jquery-ui.js @@ -1,20 +1,26 @@ -/* - * jQuery UI 1.7.2 +/*! + * jQuery UI 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI */ -;jQuery.ui || (function($) { -var _remove = $.fn.remove, - isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9); +(function($) { + +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ($.ui.version) { + return; +} //Helper functions and ui object -$.ui = { - version: "1.7.2", +$.extend($.ui, { + version: "1.8.2", // $.ui.plugin is deprecated. Use the proxy pattern instead. plugin: { @@ -73,9 +79,13 @@ $.ui = { }, keyCode: { + ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, + COMMAND: 91, + COMMAND_LEFT: 91, // COMMAND + COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, @@ -85,6 +95,7 @@ $.ui = { HOME: 36, INSERT: 45, LEFT: 37, + MENU: 93, // COMMAND_RIGHT NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, @@ -98,64 +109,36 @@ $.ui = { SHIFT: 16, SPACE: 32, TAB: 9, - UP: 38 + UP: 38, + WINDOWS: 91 // COMMAND } -}; - -// 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 ); + _focus: $.fn.focus, + focus: function(delay, fn) { + return typeof delay === 'number' + ? this.each(function() { + var elem = this; + setTimeout(function() { + $(elem).focus(); + (fn && fn.call(elem)); + }, delay); + }) + : this._focus.apply(this, arguments); }, - + enableSelection: function() { return this .attr('unselectable', 'off') - .css('MozUserSelect', '') - .unbind('selectstart.ui'); + .css('MozUserSelect', ''); }, disableSelection: function() { return this .attr('unselectable', 'on') - .css('MozUserSelect', 'none') - .bind('selectstart.ui', function() { return false; }); + .css('MozUserSelect', 'none'); }, scrollParent: function() { @@ -171,6 +154,36 @@ $.fn.extend({ } return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function(zIndex) { + if (zIndex !== undefined) { + return this.css('zIndex', zIndex); + } + + if (this.length) { + var elem = $(this[0]), position, value; + while (elem.length && elem[0] !== document) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css('position'); + if (position == 'absolute' || position == 'relative' || position == 'fixed') + { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt(elem.css('zIndex')); + if (!isNaN(value) && value != 0) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; } }); @@ -200,176 +213,263 @@ $.extend($.expr[':'], { } }); +})(jQuery); +/*! + * jQuery UI Widget 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Widget + */ +(function( $ ) { -// $.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 _remove = $.fn.remove; - var methods = getMethods('getter'); - if (args.length == 1 && typeof args[0] == 'string') { - methods = methods.concat(getMethods('getterSetter')); - } - return ($.inArray(method, methods) != -1); -} +$.fn.remove = function( selector, keepData ) { + return this.each(function() { + if ( !keepData ) { + if ( !selector || $.filter( selector, [ this ] ).length ) { + $( "*", this ).add( this ).each(function() { + $( this ).triggerHandler( "remove" ); + }); + } + } + return _remove.call( $(this), selector, keepData ); + }); +}; -$.widget = function(name, prototype) { - var namespace = name.split(".")[0]; - name = name.split(".")[1]; +$.widget = function( name, base, prototype ) { + var namespace = name.split( "." )[ 0 ], + fullName; + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; - // create plugin method - $.fn[name] = function(options) { - var isMethodCall = (typeof options == 'string'), - args = Array.prototype.slice.call(arguments, 1); + if ( !prototype ) { + prototype = base; + base = $.Widget; + } - // prevent calls to internal methods - if (isMethodCall && options.substring(0, 1) == '_') { - return this; - } + // create selector for plugin + $.expr[ ":" ][ fullName ] = function( elem ) { + return !!$.data( elem, name ); + }; - // handle getter methods - if (isMethodCall && getter(namespace, name, options, args)) { - var instance = $.data(this[0], name); - return (instance ? instance[options].apply(instance, args) - : undefined); + $[ namespace ] = $[ namespace ] || {}; + $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without initializing for simple inheritance + if ( arguments.length ) { + this._createWidget( options, element ); } + }; - // handle initialization and non-getter methods - return this.each(function() { - var instance = $.data(this, name); + var basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from +// $.each( basePrototype, function( key, val ) { +// if ( $.isPlainObject(val) ) { +// basePrototype[ key ] = $.extend( {}, val ); +// } +// }); + basePrototype.options = $.extend( {}, basePrototype.options ); + $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { + namespace: namespace, + widgetName: name, + widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, + widgetBaseClass: fullName + }, prototype ); + + $.widget.bridge( name, $[ namespace ][ name ] ); +}; - // constructor - (!instance && !isMethodCall && - $.data(this, name, new $[namespace][name](this, options))._init()); +$.widget.bridge = function( name, object ) { + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = Array.prototype.slice.call( arguments, 1 ), + returnValue = this; - // 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; + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.extend.apply( null, [ true, options ].concat(args) ) : + options; - 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); + // prevent calls to internal methods + if ( isMethodCall && options.substring( 0, 1 ) === "_" ) { + return returnValue; + } + + if ( isMethodCall ) { + this.each(function() { + var instance = $.data( this, name ), + methodValue = instance && $.isFunction( instance[options] ) ? + instance[ options ].apply( instance, args ) : + instance; + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue; + return false; } - }) - .bind('getData.' + name, function(event, key) { - if (event.target == element) { - return self._getData(key); + }); + } else { + this.each(function() { + var instance = $.data( this, name ); + if ( instance ) { + if ( options ) { + instance.option( options ); + } + instance._init(); + } else { + $.data( this, name, new object( options, this ) ); } - }) - .bind('remove', function() { - return self.destroy(); }); - }; + } - // add widget prototype - $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype); + return returnValue; + }; +}; - // TODO: merge getter and getterSetter properties from widget prototype - // and plugin prototype - $[namespace][name].getterSetter = 'option'; +$.Widget = function( options, element ) { + // allow instantiation without initializing for simple inheritance + if ( arguments.length ) { + this._createWidget( options, element ); + } }; -$.widget.prototype = { +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + options: { + disabled: false + }, + _createWidget: function( options, element ) { + // $.widget.bridge stores the plugin instance, but we do it anyway + // so that it's stored even before the _create function runs + this.element = $( element ).data( this.widgetName, this ); + this.options = $.extend( true, {}, + this.options, + $.metadata && $.metadata.get( element )[ this.widgetName ], + options ); + + var self = this; + this.element.bind( "remove." + this.widgetName, function() { + self.destroy(); + }); + + this._create(); + this._init(); + }, + _create: function() {}, _init: function() {}, + destroy: function() { - this.element.removeData(this.widgetName) - .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled') - .removeAttr('aria-disabled'); + this.element + .unbind( "." + this.widgetName ) + .removeData( this.widgetName ); + this.widget() + .unbind( "." + this.widgetName ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetBaseClass + "-disabled " + + "ui-state-disabled" ); + }, + + widget: function() { + return this.element; }, - option: function(key, value) { + option: function( key, value ) { var options = key, self = this; - if (typeof key == "string") { - if (value === undefined) { - return this._getData(key); + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.extend( {}, self.options ); + } + + if (typeof key === "string" ) { + if ( value === undefined ) { + return this.options[ key ]; } options = {}; - options[key] = value; + options[ key ] = value; } - $.each(options, function(key, value) { - self._setData(key, value); + $.each( options, function( key, value ) { + self._setOption( key, value ); }); + + return self; }, - _getData: function(key) { - return this.options[key]; - }, - _setData: function(key, value) { - this.options[key] = value; + _setOption: 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); + if ( key === "disabled" ) { + this.widget() + [ value ? "addClass" : "removeClass"]( + this.widgetBaseClass + "-disabled" + " " + + "ui-state-disabled" ) + .attr( "aria-disabled", value ); } + + return this; }, enable: function() { - this._setData('disabled', false); + return this._setOption( "disabled", false ); }, disable: function() { - this._setData('disabled', true); + return this._setOption( "disabled", true ); }, - _trigger: function(type, event, data) { - var callback = this.options[type], - eventName = (type == this.widgetEventPrefix - ? type : this.widgetEventPrefix + type); + _trigger: function( type, event, data ) { + var callback = this.options[ type ]; - event = $.Event(event); - event.type = eventName; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + data = data || {}; // copy original event properties over to the new event // this would happen if we could call $.event.fix instead of $.Event // but we don't have a way to force an event to be fixed multiple times - if (event.originalEvent) { - for (var i = $.event.props.length, prop; i;) { - prop = $.event.props[--i]; - event[prop] = event.originalEvent[prop]; + if ( event.originalEvent ) { + for ( var i = $.event.props.length, prop; i; ) { + prop = $.event.props[ --i ]; + event[ prop ] = event.originalEvent[ prop ]; } } - this.element.trigger(event, data); + this.element.trigger( event, data ); - return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false - || event.isDefaultPrevented()); + return !( $.isFunction(callback) && + callback.call( this.element[0], event, data ) === false || + event.isDefaultPrevented() ); } }; -$.widget.defaults = { - disabled: false -}; - - -/** Mouse Interaction Plugin **/ +})( jQuery ); +/*! + * jQuery UI Mouse 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function($) { -$.ui.mouse = { +$.widget("ui.mouse", { + options: { + cancel: ':input,option', + distance: 1, + delay: 0 + }, _mouseInit: function() { var self = this; @@ -385,12 +485,6 @@ $.ui.mouse = { } }); - // Prevent text selection in IE - if ($.browser.msie) { - this._mouseUnselectable = this.element.attr('unselectable'); - this.element.attr('unselectable', 'on'); - } - this.started = false; }, @@ -398,10 +492,6 @@ $.ui.mouse = { // 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) { @@ -508,32 +598,54 @@ $.ui.mouse = { _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.7.2 + * jQuery UI Draggable 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js */ (function($) { -$.widget("ui.draggable", $.extend({}, $.ui.mouse, { - - _init: function() { +$.widget("ui.draggable", $.ui.mouse, { + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false + }, + _create: function() { if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) this.element[0].style.position = 'relative'; @@ -554,12 +666,15 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { + " ui-draggable-dragging" + " ui-draggable-disabled"); this._mouseDestroy(); + + return this; }, _mouseCapture: function(event) { var o = this.options; + // among others, prevent a drag on a resizable-handle if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) return false; @@ -599,7 +714,7 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins - this.offset = this.element.offset(); + this.offset = this.positionAbs = this.element.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left @@ -615,20 +730,22 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { }); //Generate the original position - this.originalPosition = this._generatePosition(event); + this.originalPosition = this.position = 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); + (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); + //Trigger event + callbacks + if(this._trigger("start", event) === false) { + this._clear(); + return false; + } //Recache the helper size this._cacheHelperProportions(); @@ -651,7 +768,10 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { //Call plugins and callbacks and use the resulting position if something is returned if (!noPropagation) { var ui = this._uiHash(); - this._trigger('drag', event, ui); + if(this._trigger('drag', event, ui) === false) { + this._mouseUp({}); + return false; + } this.position = ui.position; } @@ -674,20 +794,38 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { dropped = this.dropped; this.dropped = false; } + + //if the original element is removed, don't bother to continue + if(!this.element[0] || !this.element[0].parentNode) + return 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(); + if(self._trigger("stop", event) !== false) { + self._clear(); + } }); } else { - this._trigger("stop", event); - this._clear(); + if(this._trigger("stop", event) !== false) { + this._clear(); + } } return false; }, + + cancel: function() { + + if(this.helper.is(".ui-draggable-dragging")) { + this._mouseUp({}); + } else { + this._clear(); + } + + return this; + + }, _getHandle: function(event) { @@ -719,10 +857,24 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { }, _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; + if (typeof obj == 'string') { + obj = obj.split(' '); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ('left' in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ('right' in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ('top' in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ('bottom' in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } }, _getParentOffset: function() { @@ -818,13 +970,13 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { 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) - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( 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) - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) ) }; @@ -833,15 +985,6 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { _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; @@ -875,14 +1018,14 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { - 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) - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( 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) - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) ) }; @@ -902,7 +1045,7 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { 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); + return $.Widget.prototype._trigger.call(this, type, event, ui); }, plugins: {}, @@ -911,45 +1054,15 @@ $.widget("ui.draggable", $.extend({}, $.ui.mouse, { return { helper: this.helper, position: this.position, - absolutePosition: this.positionAbs, //deprecated + originalPosition: this.originalPosition, offset: this.positionAbs }; } -})); +}); $.extend($.ui.draggable, { - version: "1.7.2", - eventPrefix: "drag", - defaults: { - addClasses: true, - appendTo: "parent", - axis: false, - cancel: ":input,option", - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - delay: 0, - distance: 1, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false - } + version: "1.8.2" }); $.ui.plugin.add("draggable", "connectToSortable", { @@ -1019,12 +1132,12 @@ $.ui.plugin.add("draggable", "connectToSortable", { }; $.each(inst.sortables, function(i) { - + //Copy over some variables to allow calling the sortable's native _intersectsWith this.instance.positionAbs = inst.positionAbs; this.instance.helperProportions = inst.helperProportions; this.instance.offset.click = inst.offset.click; - + if(this.instance._intersectsWith(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 @@ -1067,13 +1180,13 @@ $.ui.plugin.add("draggable", "connectToSortable", { this.instance.isOver = 0; this.instance.cancelHelperRemoval = true; - + //Prevent reverting on this forced stop this.instance.options.revert = false; - + // The out event needs to be triggered independently this.instance._trigger('out', event, this.instance._uiHash(this.instance)); - + this.instance._mouseStop(event, true); this.instance.options.helper = this.instance.options._helper; @@ -1257,15 +1370,17 @@ $.ui.plugin.add("draggable", "stack", { var o = $(this).data("draggable").options; - var group = $.makeArray($(o.stack.group)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min); + var group = $.makeArray($(o.stack)).sort(function(a,b) { + return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); }); - + if (!group.length) { return; } + + var min = parseInt(group[0].style.zIndex) || 0; $(group).each(function(i) { - this.style.zIndex = o.stack.min + i; + this.style.zIndex = min + i; }); - this[0].style.zIndex = o.stack.min + group.length; + this[0].style.zIndex = min + group.length; } }); @@ -1284,28 +1399,39 @@ $.ui.plugin.add("draggable", "zIndex", { })(jQuery); /* - * jQuery UI Droppable 1.7.2 + * jQuery UI Droppable 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.mouse.js + * jquery.ui.draggable.js */ (function($) { $.widget("ui.droppable", { - - _init: function() { + widgetEventPrefix: "drop", + options: { + accept: '*', + activeClass: false, + addClasses: true, + greedy: false, + hoverClass: false, + scope: 'default', + tolerance: 'intersect' + }, + _create: 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) { + this.accept = $.isFunction(accept) ? accept : function(d) { return d.is(accept); }; @@ -1313,10 +1439,10 @@ $.widget("ui.droppable", { 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); + $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; + $.ui.ddmanager.droppables[o.scope].push(this); - (this.options.addClasses && this.element.addClass("ui-droppable")); + (o.addClasses && this.element.addClass("ui-droppable")); }, @@ -1330,18 +1456,18 @@ $.widget("ui.droppable", { .removeClass("ui-droppable ui-droppable-disabled") .removeData("droppable") .unbind(".droppable"); + + return this; }, - _setData: function(key, value) { + _setOption: function(key, value) { if(key == 'accept') { - this.options.accept = value && $.isFunction(value) ? value : function(d) { + this.accept = $.isFunction(value) ? value : function(d) { return d.is(value); }; - } else { - $.widget.prototype._setData.apply(this, arguments); } - + $.Widget.prototype._setOption.apply(this, arguments); }, _activate: function(event) { @@ -1361,7 +1487,7 @@ $.widget("ui.droppable", { 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[0],(draggable.currentItem || draggable.element))) { + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); this._trigger('over', event, this.ui(draggable)); } @@ -1373,7 +1499,7 @@ $.widget("ui.droppable", { 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[0],(draggable.currentItem || draggable.element))) { + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); this._trigger('out', event, this.ui(draggable)); } @@ -1388,13 +1514,17 @@ $.widget("ui.droppable", { var childrenIntersection = false; this.element.find(":data(droppable)").not(".ui-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( + inst.options.greedy + && !inst.options.disabled + && inst.options.scope == draggable.options.scope + && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) + && $.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[0],(draggable.currentItem || draggable.element))) { + if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.activeClass) this.element.removeClass(this.options.activeClass); if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); this._trigger('drop', event, this.ui(draggable)); @@ -1410,7 +1540,6 @@ $.widget("ui.droppable", { draggable: (c.currentItem || c.element), helper: c.helper, position: c.position, - absolutePosition: c.positionAbs, //deprecated offset: c.positionAbs }; } @@ -1418,17 +1547,7 @@ $.widget("ui.droppable", { }); $.extend($.ui.droppable, { - version: "1.7.2", - eventPrefix: 'drop', - defaults: { - accept: '*', - activeClass: false, - addClasses: true, - greedy: false, - hoverClass: false, - scope: 'default', - tolerance: 'intersect' - } + version: "1.8.2" }); $.ui.intersect = function(draggable, droppable, toleranceMode) { @@ -1483,13 +1602,13 @@ $.ui.ddmanager = { droppables: { 'default': [] }, prepareOffsets: function(t, event) { - var m = $.ui.ddmanager.droppables[t.options.scope]; + 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[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted + if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(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 @@ -1504,13 +1623,13 @@ $.ui.ddmanager = { drop: function(draggable, event) { var dropped = false; - $.each($.ui.ddmanager.droppables[draggable.options.scope], function() { + $.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); + dropped = dropped || this._drop.call(this, event); - if (!this.options.disabled && this.visible && this.options.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { this.isout = 1; this.isover = 0; this._deactivate.call(this, event); } @@ -1525,8 +1644,7 @@ $.ui.ddmanager = { 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() { + $.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); @@ -1566,22 +1684,42 @@ $.ui.ddmanager = { })(jQuery); /* - * jQuery UI Resizable 1.7.2 + * jQuery UI Resizable 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js */ (function($) { -$.widget("ui.resizable", $.extend({}, $.ui.mouse, { - - _init: function() { +$.widget("ui.resizable", $.ui.mouse, { + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + zIndex: 1000 + }, + _create: function() { var self = this, o = this.options; this.element.addClass("ui-resizable"); @@ -1752,7 +1890,7 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { if (this.elementIsWrapper) { _destroy(this.element); var wrapper = this.element; - wrapper.parent().append( + wrapper.after( this.originalElement.css({ position: wrapper.css('position'), width: wrapper.outerWidth(), @@ -1760,23 +1898,24 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { top: wrapper.css('top'), left: wrapper.css('left') }) - ).end().remove(); + ).remove(); } this.originalElement.css('resize', this.originalResizeStyle); _destroy(this.originalElement); + return this; }, _mouseCapture: function(event) { - var handle = false; - for(var i in this.handles) { - if($(this.handles[i])[0] == event.target) handle = true; + for (var i in this.handles) { + if ($(this.handles[i])[0] == event.target) { + handle = true; + } } - return this.options.disabled || !!handle; - + return !this.options.disabled && handle; }, _mouseStart: function(event) { @@ -2062,32 +2201,10 @@ $.widget("ui.resizable", $.extend({}, $.ui.mouse, { }; } -})); +}); $.extend($.ui.resizable, { - version: "1.7.2", - eventPrefix: "resize", - defaults: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - cancel: ":input,option", - containment: false, - delay: 0, - distance: 1, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - zIndex: 1000 - } + version: "1.8.2" }); /* @@ -2100,7 +2217,7 @@ $.ui.plugin.add("resizable", "alsoResize", { var self = $(this).data("resizable"), o = self.options; - _store = function(exp) { + var _store = function(exp) { $(exp).each(function() { $(this).data("resizable-alsoresize", { width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10), @@ -2365,23 +2482,32 @@ var isNumber = function(value) { }; })(jQuery); + /* - * jQuery UI Selectable 1.7.2 + * jQuery UI Selectable 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js */ (function($) { -$.widget("ui.selectable", $.extend({}, $.ui.mouse, { - - _init: function() { +$.widget("ui.selectable", $.ui.mouse, { + options: { + appendTo: 'body', + autoRefresh: true, + distance: 0, + filter: '*', + tolerance: 'touch' + }, + _create: function() { var self = this; this.element.addClass("ui-selectable"); @@ -2415,17 +2541,20 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { this._mouseInit(); - this.helper = $(document.createElement('div')) - .css({border:'1px dotted black'}) - .addClass("ui-selectable-helper"); + this.helper = $("<div class='ui-selectable-helper'></div>"); }, destroy: function() { + this.selectees + .removeClass("ui-selectee") + .removeData("selectable-item"); this.element .removeClass("ui-selectable ui-selectable-disabled") .removeData("selectable") .unbind(".selectable"); this._mouseDestroy(); + + return this; }, _mouseStart: function(event) { @@ -2475,14 +2604,23 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { $(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 - }); + var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + // selectable (UN)SELECTING callback + if (doSelect) { + self._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } return false; } }); @@ -2606,38 +2744,56 @@ $.widget("ui.selectable", $.extend({}, $.ui.mouse, { return false; } -})); +}); $.extend($.ui.selectable, { - version: "1.7.2", - defaults: { - appendTo: 'body', - autoRefresh: true, - cancel: ":input,option", - delay: 0, - distance: 0, - filter: '*', - tolerance: 'touch' - } + version: "1.8.2" }); })(jQuery); /* - * jQuery UI Sortable 1.7.2 + * jQuery UI Sortable 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js */ (function($) { -$.widget("ui.sortable", $.extend({}, $.ui.mouse, { - _init: function() { +$.widget("ui.sortable", $.ui.mouse, { + widgetEventPrefix: "sort", + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: 'auto', + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: '> *', + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000 + }, + _create: function() { var o = this.options; this.containerCache = {}; @@ -2666,6 +2822,20 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { for ( var i = this.items.length - 1; i >= 0; i-- ) this.items[i].item.removeData("sortable-item"); + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget() + [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" ); + } else { + // Don't call widget base _setOption for disable as it adds ui-state-disabled class + $.Widget.prototype._setOption.apply(this, arguments); + } }, _mouseCapture: function(event, overrideHandle) { @@ -2754,8 +2924,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied - if(o.cursorAt) - this._adjustOffsetFromHelper(o.cursorAt); + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Cache the former DOM position this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; @@ -2880,6 +3049,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { && 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) + //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container ) { this.direction = intersection == 1 ? "down" : "up"; @@ -2978,7 +3148,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { $(this.domPosition.parent).prepend(this.currentItem); } - return true; + return this; }, @@ -3084,6 +3254,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { refresh: function(event) { this._refreshItems(event); this.refreshPositions(); + return this; }, _connectWith: function() { @@ -3092,7 +3263,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { ? [options.connectWith] : options.connectWith; }, - + _getItemsAsjQuery: function(connected) { var self = this; @@ -3106,13 +3277,13 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { 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(".ui-sortable-helper"), inst]); + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), 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(".ui-sortable-helper"), this]); + 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(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); for (var i = queries.length - 1; i >= 0; i--){ queries[i][0].each(function() { @@ -3191,10 +3362,6 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { 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) { @@ -3219,6 +3386,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }; } + return this; }, _createPlaceholder: function(that) { @@ -3264,47 +3432,71 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, _contactContainers: function(event) { + + // get innermost container that intersects with item + var innermostContainer = null, innermostIndex = null; + + 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._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[i].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[i]._trigger("change", event, this._uiHash(this)); + // never consider a container that's located within the item itself + if($.ui.contains(this.currentItem[0], this.containers[i].element[0])) + continue; - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); + if(this._intersectsWith(this.containers[i].containerCache)) { - } + // if we've already found a container and it's more "inner" than this, then continue + if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])) + continue; - this.containers[i]._trigger("over", event, this._uiHash(this)); - this.containers[i].containerCache.over = 1; - } + innermostContainer = this.containers[i]; + innermostIndex = i; + } else { + // container doesn't intersect. trigger "out" event if necessary if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", event, this._uiHash(this)); this.containers[i].containerCache.over = 0; } } - }; + } + + // if no intersecting containers found, return + if(!innermostContainer) return; + + // move the item into the container if it's not there already + if(this.containers.length === 1) { + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } else if(this.currentContainer != this.containers[innermostIndex]) { + + //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[innermostIndex].floating ? 'left' : 'top']; + for (var j = this.items.length - 1; j >= 0; j--) { + if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + var cur = this.items[j][this.containers[innermostIndex].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 + return; + + this.currentContainer = this.containers[innermostIndex]; + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); + this._trigger("change", event, this._uiHash()); + this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); + + //Update the placeholder + this.options.placeholder.update(this.currentContainer, this.placeholder); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + + }, _createHelper: function(event) { @@ -3326,10 +3518,24 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, _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; + if (typeof obj == 'string') { + obj = obj.split(' '); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ('left' in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ('right' in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ('top' in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ('bottom' in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } }, _getParentOffset: function() { @@ -3556,7 +3762,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { //Do what was originally in plugins if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor - if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset cursor + if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index this.dragging = false; @@ -3587,7 +3793,7 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { }, _trigger: function() { - if ($.widget.prototype._trigger.apply(this, arguments) === false) { + if ($.Widget.prototype._trigger.apply(this, arguments) === false) { this.cancel(); } }, @@ -3598,53 +3804,24 @@ $.widget("ui.sortable", $.extend({}, $.ui.mouse, { helper: self.helper, placeholder: self.placeholder || $([]), position: self.position, - absolutePosition: self.positionAbs, //deprecated + originalPosition: self.originalPosition, offset: self.positionAbs, item: self.currentItem, sender: inst ? inst.element : null }; } -})); +}); $.extend($.ui.sortable, { - getter: "serialize toArray", - version: "1.7.2", - eventPrefix: "sort", - defaults: { - appendTo: "parent", - axis: false, - cancel: ":input,option", - connectWith: false, - containment: false, - cursor: 'auto', - cursorAt: false, - delay: 0, - distance: 1, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: '> *', - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000 - } + version: "1.8.2" }); })(jQuery); /* - * jQuery UI Effects 1.7.2 + * jQuery UI Effects 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * @@ -3652,228 +3829,30 @@ $.extend($.ui.sortable, { */ ;jQuery.effects || (function($) { -$.effects = { - version: "1.7.2", +$.effects = {}; - // 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; - }, +/******************************************************************************/ +/****************************** COLOR ANIMATIONS ******************************/ +/******************************************************************************/ - 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('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>'); - 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 }); +// override the animation for color styles +$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', + 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], +function(i, attr) { + $.fx.step[attr] = function(fx) { + if (!fx.colorInit) { + fx.start = getColor(fx.elem, attr); + fx.end = getRGB(fx.end); + fx.colorInit = true; } - 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); - }); - - }); - } -}; - - -function _normalizeArguments(a, m) { - - var o = a[1] && a[1].constructor == Object ? a[1] : {}; if(m) o.mode = m; - var speed = a[1] && a[1].constructor != Object ? a[1] : (o.duration ? o.duration : a[2]); //either comes from options.duration or the secon/third argument - speed = $.fx.off ? 0 : typeof speed === "number" ? speed : $.fx.speeds[speed] || $.fx.speeds._default; - var callback = o.callback || ( $.isFunction(a[1]) && a[1] ) || ( $.isFunction(a[2]) && a[2] ) || ( $.isFunction(a[3]) && a[3] ); - - return [a[0], o, speed, callback]; - -} - -//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 { - return this.effect.apply(this, _normalizeArguments(arguments, 'show')); - } - }, - - hide: function() { - if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0]))) - return this._hide.apply(this, arguments); - else { - return this.effect.apply(this, _normalizeArguments(arguments, 'hide')); - } - }, - - toggle: function(){ - if(!arguments[0] || - (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) || - ($.isFunction(arguments[0]) || typeof arguments[0] == 'boolean')) { - return this.__toggle.apply(this, arguments); - } else { - return this.effect.apply(this, _normalizeArguments(arguments, 'toggle')); - } - }, - - 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 ( (typeof speed !== "boolean") && speed ) ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames, speed); - }, - 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(",") + ")"; - }; + 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) + ')'; + }; }); // Color Conversion functions from highlightFade @@ -3979,6 +3958,373 @@ var colors = { transparent: [255,255,255] }; + + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ + +var classAnimationActions = ['add', 'remove', 'toggle'], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + +function getElementStyles() { + var style = document.defaultView + ? document.defaultView.getComputedStyle(this, null) + : this.currentStyle, + newStyle = {}, + key, + camelCase; + + // webkit enumerates style porperties + if (style && style.length && style[0] && style[style[0]]) { + var len = style.length; + while (len--) { + key = style[len]; + if (typeof style[key] == 'string') { + camelCase = key.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + newStyle[camelCase] = style[key]; + } + } + } else { + for (key in style) { + if (typeof style[key] === 'string') { + newStyle[key] = style[key]; + } + } + } + + return newStyle; +} + +function filterStyles(styles) { + var name, value; + for (name in styles) { + value = styles[name]; + if ( + // ignore null and undefined values + value == null || + // ignore functions (when does this occur?) + $.isFunction(value) || + // shorthand styles that need to be expanded + name in shorthandStyles || + // ignore scrollbars (break in IE) + (/scrollbar/).test(name) || + + // only colors or values that can be converted to numbers + (!(/color/i).test(name) && isNaN(parseFloat(value))) + ) { + delete styles[name]; + } + } + + return styles; +} + +function styleDifference(oldStyle, newStyle) { + var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459 + name; + + for (name in newStyle) { + if (oldStyle[name] != newStyle[name]) { + diff[name] = newStyle[name]; + } + } + + return diff; +} + +$.effects.animateClass = function(value, duration, easing, callback) { + if ($.isFunction(easing)) { + callback = easing; + easing = null; + } + + return this.each(function() { + + var that = $(this), + originalStyleAttr = that.attr('style') || ' ', + originalStyle = filterStyles(getElementStyles.call(this)), + newStyle, + className = that.attr('className'); + + $.each(classAnimationActions, function(i, action) { + if (value[action]) { + that[action + 'Class'](value[action]); + } + }); + newStyle = filterStyles(getElementStyles.call(this)); + that.attr('className', className); + + that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() { + $.each(classAnimationActions, function(i, action) { + if (value[action]) { that[action + 'Class'](value[action]); } + }); + // work around bug in IE by clearing the cssText before setting it + if (typeof that.attr('style') == 'object') { + that.attr('style').cssText = ''; + that.attr('style').cssText = originalStyleAttr; + } else { + that.attr('style', originalStyleAttr); + } + if (callback) { callback.apply(this, arguments); } + }); + }); +}; + +$.fn.extend({ + _addClass: $.fn.addClass, + addClass: function(classNames, speed, easing, callback) { + return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); + }, + + _removeClass: $.fn.removeClass, + removeClass: function(classNames,speed,easing,callback) { + return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); + }, + + _toggleClass: $.fn.toggleClass, + toggleClass: function(classNames, force, speed, easing, callback) { + if ( typeof force == "boolean" || force === undefined ) { + if ( !speed ) { + // without speed parameter; + return this._toggleClass(classNames, force); + } else { + return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]); + } + } else { + // without switch parameter; + return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]); + } + }, + + switchClass: function(remove,add,speed,easing,callback) { + return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); + } +}); + + + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +$.extend($.effects, { + version: "1.8.2", + + // 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(); + } + + // wrap the element + var props = { + width: element.outerWidth(true), + height: element.outerHeight(true), + 'float': element.css('float') + }, + wrapper = $('<div></div>') + .addClass('ui-effects-wrapper') + .css({ + fontSize: '100%', + background: 'transparent', + border: 'none', + margin: 0, + padding: 0 + }); + + element.wrap(wrapper); + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element + + // transfer positioning properties to the wrapper + if (element.css('position') == 'static') { + wrapper.css({ position: 'relative' }); + element.css({ position: 'relative' }); + } else { + $.extend(props, { + position: element.css('position'), + zIndex: element.css('z-index') + }); + $.each(['top', 'left', 'bottom', 'right'], function(i, pos) { + props[pos] = element.css(pos); + if (isNaN(parseInt(props[pos], 10))) { + props[pos] = 'auto'; + } + }); + element.css({position: 'relative', top: 0, left: 0 }); + } + + return wrapper.css(props).show(); + }, + + 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; + } +}); + + +function _normalizeArguments(effect, options, speed, callback) { + // shift params for method overloading + if (typeof effect == 'object') { + callback = options; + speed = null; + options = effect; + effect = options.effect; + } + if ($.isFunction(options)) { + callback = options; + speed = null; + options = {}; + } + if ($.isFunction(speed)) { + callback = speed; + speed = null; + } + if (typeof options == 'number' || $.fx.speeds[options]) { + callback = speed; + speed = options; + options = {}; + } + + options = options || {}; + + speed = speed || options.duration; + speed = $.fx.off ? 0 : typeof speed == 'number' + ? speed : $.fx.speeds[speed] || $.fx.speeds._default; + + callback = callback || options.complete; + + return [effect, options, speed, callback]; +} + +$.fn.extend({ + effect: function(effect, options, speed, callback) { + var args = _normalizeArguments.apply(this, arguments), + // TODO: make effects takes actual parameters instead of a hash + args2 = { + options: args[1], + duration: args[2], + callback: args[3] + }, + effectMethod = $.effects[effect]; + + return effectMethod && !$.fx.off ? effectMethod.call(this, args2) : this; + }, + + _show: $.fn.show, + show: function(speed) { + if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) { + return this._show.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'show'; + return this.effect.apply(this, args); + } + }, + + _hide: $.fn.hide, + hide: function(speed) { + if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) { + return this._hide.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'hide'; + return this.effect.apply(this, args); + } + }, + + // jQuery core overloads toggle and create _toggle + __toggle: $.fn.toggle, + toggle: function(speed) { + if (!speed || typeof speed == 'number' || $.fx.speeds[speed] || + typeof speed == 'boolean' || $.isFunction(speed)) { + return this.__toggle.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'toggle'; + return this.effect.apply(this, args); + } + }, + + // 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; + } +}); + + + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + /* * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ * @@ -4187,16 +4533,16 @@ $.extend($.easing, })(jQuery); /* - * jQuery UI Effects Blind 1.7.2 + * jQuery UI Effects Blind 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.effects.core.js */ (function($) { @@ -4236,16 +4582,16 @@ $.effects.blind = function(o) { })(jQuery); /* - * jQuery UI Effects Bounce 1.7.2 + * jQuery UI Effects Bounce 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.effects.core.js */ (function($) { @@ -4314,16 +4660,16 @@ $.effects.bounce = function(o) { })(jQuery); /* - * jQuery UI Effects Clip 1.7.2 + * jQuery UI Effects Clip 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.effects.core.js */ (function($) { @@ -4368,16 +4714,16 @@ $.effects.clip = function(o) { })(jQuery); /* - * jQuery UI Effects Drop 1.7.2 + * jQuery UI Effects Drop 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.effects.core.js */ (function($) { @@ -4418,16 +4764,16 @@ $.effects.drop = function(o) { })(jQuery); /* - * jQuery UI Effects Explode 1.7.2 + * jQuery UI Effects Explode 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.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 + * jquery.effects.core.js */ (function($) { @@ -4497,16 +4843,48 @@ $.effects.explode = function(o) { })(jQuery); /* - * jQuery UI Effects Fold 1.7.2 + * jQuery UI Effects Fade 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function($) { + +$.effects.fade = function(o) { + return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'hide'); + + elem.animate({ opacity: mode }, { + queue: false, + duration: o.duration, + easing: o.options.easing, + complete: function() { + (o.callback && o.callback.apply(this, arguments)); + elem.dequeue(); + } + }); + }); +}; + +})(jQuery); +/* + * jQuery UI Effects Fold 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Fold * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { @@ -4553,151 +4931,143 @@ $.effects.fold = function(o) { })(jQuery); /* - * jQuery UI Effects Highlight 1.7.2 + * jQuery UI Effects Highlight 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Highlight * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { $.effects.highlight = function(o) { - return this.queue(function() { + var elem = $(this), + props = ['backgroundImage', 'backgroundColor', 'opacity'], + mode = $.effects.setMode(elem, o.options.mode || 'show'), + animation = { + backgroundColor: elem.css('backgroundColor') + }; - // Create element - var el = $(this), props = ['backgroundImage','backgroundColor','opacity']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode - var color = o.options.color || "#ffff99"; // Default highlight color - var oldColor = el.css("backgroundColor"); - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - el.css({backgroundImage: 'none', backgroundColor: color}); // Shift - - // Animation - var animation = {backgroundColor: oldColor }; - if (mode == "hide") animation['opacity'] = 0; - - // Animate - el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { - if(mode == "hide") el.hide(); - $.effects.restore(el, props); - if (mode == "show" && $.browser.msie) this.style.removeAttribute('filter'); - if(o.callback) o.callback.apply(this, arguments); - el.dequeue(); - }}); + if (mode == 'hide') { + animation.opacity = 0; + } + $.effects.save(elem, props); + elem + .show() + .css({ + backgroundImage: 'none', + backgroundColor: o.options.color || '#ffff99' + }) + .animate(animation, { + queue: false, + duration: o.duration, + easing: o.options.easing, + complete: function() { + (mode == 'hide' && elem.hide()); + $.effects.restore(elem, props); + (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter')); + (o.callback && o.callback.apply(this, arguments)); + elem.dequeue(); + } + }); }); - }; })(jQuery); /* - * jQuery UI Effects Pulsate 1.7.2 + * jQuery UI Effects Pulsate 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Pulsate * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { $.effects.pulsate = function(o) { - return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'show'); + times = ((o.options.times || 5) * 2) - 1; + duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2, + isVisible = elem.is(':visible'), + animateTo = 0; - // Create element - var el = $(this); + if (!isVisible) { + elem.css('opacity', 0).show(); + animateTo = 1; + } - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode - var times = o.options.times || 5; // Default # of times - var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2; + if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) { + times--; + } - // Adjust - if (mode == 'hide') times--; - if (el.is(':hidden')) { // Show fadeIn - el.css('opacity', 0); - el.show(); // Show - el.animate({opacity: 1}, duration, o.options.easing); - times = times-2; + for (var i = 0; i < times; i++) { + elem.animate({ opacity: animateTo }, duration, o.options.easing); + animateTo = (animateTo + 1) % 2; } - // Animate - for (var i = 0; i < times; i++) { // Pulsate - el.animate({opacity: 0}, duration, o.options.easing).animate({opacity: 1}, duration, o.options.easing); - }; - if (mode == 'hide') { // Last Pulse - el.animate({opacity: 0}, duration, o.options.easing, function(){ - el.hide(); // Hide - if(o.callback) o.callback.apply(this, arguments); // Callback - }); - } else { - el.animate({opacity: 0}, duration, o.options.easing).animate({opacity: 1}, duration, o.options.easing, function(){ - if(o.callback) o.callback.apply(this, arguments); // Callback - }); - }; - el.queue('fx', function() { el.dequeue(); }); - el.dequeue(); - }); + elem.animate({ opacity: animateTo }, duration, o.options.easing, function() { + if (animateTo == 0) { + elem.hide(); + } + (o.callback && o.callback.apply(this, arguments)); + }); + elem + .queue('fx', function() { elem.dequeue(); }) + .dequeue(); + }); }; })(jQuery); /* - * jQuery UI Effects Scale 1.7.2 + * jQuery UI Effects Scale 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Scale * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { $.effects.puff = function(o) { - return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'hide'), + percent = parseInt(o.options.percent, 10) || 150, + factor = percent / 100, + original = { height: elem.height(), width: elem.width() }; + + $.extend(o.options, { + fade: true, + mode: mode, + percent: mode == 'hide' ? percent : 100, + from: mode == 'hide' + ? original + : { + height: original.height * factor, + width: original.width * factor + } + }); - // Create element - var el = $(this); - - // Set options - var options = $.extend(true, {}, o.options); - var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode - var percent = parseInt(o.options.percent,10) || 150; // Set default puff percent - options.fade = true; // It's not a puff if it doesn't fade! :) - var original = {height: el.height(), width: el.width()}; // Save original - - // Adjust - var factor = percent / 100; - el.from = (mode == 'hide') ? original : {height: original.height * factor, width: original.width * factor}; - - // Animation - options.from = el.from; - options.percent = (mode == 'hide') ? percent : 100; - options.mode = mode; - - // Animate - el.effect('scale', options, o.duration, o.callback); - el.dequeue(); + elem.effect('scale', o.options, o.duration, o.callback); + elem.dequeue(); }); - }; $.effects.scale = function(o) { @@ -4825,6 +5195,9 @@ $.effects.size = function(o) { // Animate el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { + if (el.to.opacity === 0) { + el.css('opacity', el.from.opacity); + } if(mode == 'hide') el.hide(); // Hide $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore if(o.callback) o.callback.apply(this, arguments); // Callback @@ -4837,16 +5210,16 @@ $.effects.size = function(o) { })(jQuery); /* - * jQuery UI Effects Shake 1.7.2 + * jQuery UI Effects Shake 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Shake * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { @@ -4894,16 +5267,16 @@ $.effects.shake = function(o) { })(jQuery); /* - * jQuery UI Effects Slide 1.7.2 + * jQuery UI Effects Slide 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Slide * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { @@ -4944,16 +5317,16 @@ $.effects.slide = function(o) { })(jQuery); /* - * jQuery UI Effects Transfer 1.7.2 + * jQuery UI Effects Transfer 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Effects/Transfer * * Depends: - * effects.core.js + * jquery.effects.core.js */ (function($) { @@ -4989,52 +5362,48 @@ $.effects.transfer = function(o) { })(jQuery); /* - * jQuery UI Accordion 1.7.2 + * jQuery UI Accordion 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Accordion * * Depends: - * ui.core.js + * jquery.ui.core.js + * jquery.ui.widget.js */ (function($) { $.widget("ui.accordion", { - - _init: function() { + options: { + active: 0, + animated: 'slide', + autoHeight: true, + clearStyle: false, + collapsible: false, + event: "click", + fillSpace: false, + header: "> li > :first-child,> :not(li):even", + icons: { + header: "ui-icon-triangle-1-e", + headerSelected: "ui-icon-triangle-1-s" + }, + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() == location.href.toLowerCase(); + } + }, + _create: function() { var o = this.options, self = this; this.running = 0; - // if the user set the alwaysOpen option on init - // then we need to set the collapsible option - // if they set both on init, collapsible will take priority - if (o.collapsible == $.ui.accordion.defaults.collapsible && - o.alwaysOpen != $.ui.accordion.defaults.alwaysOpen) { - o.collapsible = !o.alwaysOpen; - } - - if ( o.navigation ) { - var current = this.element.find("a").filter(o.navigationFilter); - if ( current.length ) { - if ( current.filter(o.header).length ) { - this.active = current; - } else { - this.active = current.parent().parent().prev(); - current.addClass("ui-accordion-content-active"); - } - } - } - this.element.addClass("ui-accordion ui-widget ui-helper-reset"); - + // in lack of child-selectors in CSS we need to mark top-LIs in a UL-accordion for some IE-fix - if (this.element[0].nodeName == "UL") { - this.element.children("li").addClass("ui-accordion-li-fix"); - } + this.element.children("li").addClass("ui-accordion-li-fix"); this.headers = this.element.find(o.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all") .bind("mouseenter.accordion", function(){ $(this).addClass('ui-state-hover'); }) @@ -5046,17 +5415,25 @@ $.widget("ui.accordion", { .next() .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); + if ( o.navigation ) { + var current = this.element.find("a").filter(o.navigationFilter); + if ( current.length ) { + var header = current.closest(".ui-accordion-header"); + if ( header.length ) { + // anchor within header + this.active = header; + } else { + // anchor within content + this.active = current.closest(".ui-accordion-content").prev(); + } + } + } + this.active = this._findActive(this.active || o.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"); this.active.next().addClass('ui-accordion-content-active'); //Append icon elements - $("<span/>").addClass("ui-icon " + o.icons.header).prependTo(this.headers); - this.active.find(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected); - - // IE7-/Win - Extra vertical space in lists fixed - if ($.browser.msie) { - this.element.find('a').css('zoom', '1'); - } + this._createIcons(); this.resize(); @@ -5090,10 +5467,27 @@ $.widget("ui.accordion", { this.headers.find('a').attr('tabIndex','-1'); if (o.event) { - this.headers.bind((o.event) + ".accordion", function(event) { return self._clickHandler.call(self, event, this); }); + this.headers.bind((o.event) + ".accordion", function(event) { + self._clickHandler.call(self, event, this); + event.preventDefault(); + }); } }, + + _createIcons: function() { + var o = this.options; + if (o.icons) { + $("<span/>").addClass("ui-icon " + o.icons.header).prependTo(this.headers); + this.active.find(".ui-icon").toggleClass(o.icons.header).toggleClass(o.icons.headerSelected); + this.element.addClass("ui-accordion-icons"); + } + }, + + _destroyIcons: function() { + this.headers.children(".ui-icon").remove(); + this.element.removeClass("ui-accordion-icons"); + }, destroy: function() { var o = this.options; @@ -5107,19 +5501,31 @@ $.widget("ui.accordion", { this.headers .unbind(".accordion") .removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top") - .removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex"); + .removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex"); - this.headers.find("a").removeAttr("tabindex"); - this.headers.children(".ui-icon").remove(); + this.headers.find("a").removeAttr("tabIndex"); + this._destroyIcons(); var contents = this.headers.next().css("display", "").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active"); if (o.autoHeight || o.fillHeight) { contents.css("height", ""); } - }, - _setData: function(key, value) { - if(key == 'alwaysOpen') { key = 'collapsible'; value = !value; } - $.widget.prototype._setData.apply(this, arguments); + return this; + }, + + _setOption: function(key, value) { + $.Widget.prototype._setOption.apply(this, arguments); + + if (key == "active") { + this.activate(value); + } + if (key == "icons") { + this._destroyIcons(); + if (value) { + this._createIcons(); + } + } + }, _keydown: function(event) { @@ -5144,7 +5550,8 @@ $.widget("ui.accordion", { break; case keyCode.SPACE: case keyCode.ENTER: - return this._clickHandler({ target: event.target }, event.target); + this._clickHandler({ target: event.target }, event.target); + event.preventDefault(); } if (toFocus) { @@ -5163,34 +5570,37 @@ $.widget("ui.accordion", { var o = this.options, maxHeight; if (o.fillSpace) { - + if($.browser.msie) { var defOverflow = this.element.parent().css('overflow'); this.element.parent().css('overflow', 'hidden'); } maxHeight = this.element.parent().height(); if($.browser.msie) { this.element.parent().css('overflow', defOverflow); } - + this.headers.each(function() { - maxHeight -= $(this).outerHeight(); + maxHeight -= $(this).outerHeight(true); }); - var maxPadding = 0; this.headers.next().each(function() { - maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height()); - }).height(Math.max(0, maxHeight - maxPadding)) - .css('overflow', 'auto'); + $(this).height(Math.max(0, maxHeight - $(this).innerHeight() + $(this).height())); + }).css('overflow', 'auto'); } else if ( o.autoHeight ) { maxHeight = 0; this.headers.next().each(function() { - maxHeight = Math.max(maxHeight, $(this).outerHeight()); + maxHeight = Math.max(maxHeight, $(this).height()); }).height(maxHeight); } + return this; }, activate: function(index) { + // TODO this gets called on init, changing the option without an explicit call for that + this.options.active = index; // call clickHandler with custom event var active = this._findActive(index)[0]; this._clickHandler({ target: active }, active); + + return this; }, _findActive: function(selector) { @@ -5203,13 +5613,17 @@ $.widget("ui.accordion", { : this.headers.filter(":eq(0)"); }, + // TODO isn't event.target enough? why the seperate target argument? _clickHandler: function(event, target) { var o = this.options; - if (o.disabled) return false; + if (o.disabled) + return; // called only when using activate(false) to close all parts programmatically - if (!event.target && o.collapsible) { + if (!event.target) { + if (!o.collapsible) + return; this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); this.active.next().addClass('ui-accordion-content-active'); @@ -5223,22 +5637,25 @@ $.widget("ui.accordion", { }, toShow = (this.active = $([])); this._toggle(toShow, toHide, data); - return false; + return; } // get the click target var clicked = $(event.currentTarget || target); var clickedIsActive = clicked[0] == this.active[0]; + + // TODO the option is changed, is that correct? + // TODO if it is correct, shouldn't that happen after determining that the click is valid? + o.active = o.collapsible && clickedIsActive ? false : $('.ui-accordion-header', this.element).index(clicked); // if animations are still active, or the active header is the target, ignore click if (this.running || (!o.collapsible && clickedIsActive)) { - return false; + return; } // switch classes this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all") .find(".ui-icon").removeClass(o.icons.headerSelected).addClass(o.icons.header); - this.active.next().addClass('ui-accordion-content-active'); if (!clickedIsActive) { clicked.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top") .find(".ui-icon").removeClass(o.icons.header).addClass(o.icons.headerSelected); @@ -5252,15 +5669,15 @@ $.widget("ui.accordion", { options: o, newHeader: clickedIsActive && o.collapsible ? $([]) : clicked, oldHeader: this.active, - newContent: clickedIsActive && o.collapsible ? $([]) : toShow.find('> *'), - oldContent: toHide.find('> *') + newContent: clickedIsActive && o.collapsible ? $([]) : toShow, + oldContent: toHide }, down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); this.active = clickedIsActive ? $([]) : clicked; this._toggle(toShow, toHide, data, clickedIsActive, down); - return false; + return; }, @@ -5320,6 +5737,9 @@ $.widget("ui.accordion", { duration = o.duration, easing = o.animated; + if (easing && !animations[easing] && !$.easing[easing]) { + easing = 'slide'; + } if (!animations[easing]) { animations[easing] = function(options) { this.slide(options, { @@ -5344,6 +5764,7 @@ $.widget("ui.accordion", { } + // TODO assert that the blur and focus triggers are really necessary, remove otherwise toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1").blur(); toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus(); @@ -5362,6 +5783,9 @@ $.widget("ui.accordion", { overflow: "" }); } + + // other classes are removed before the animation; this one needs to stay until completed + this.toHide.removeClass("ui-accordion-content-active"); this._trigger('change', null, this.data); } @@ -5370,26 +5794,7 @@ $.widget("ui.accordion", { $.extend($.ui.accordion, { - version: "1.7.2", - defaults: { - active: null, - alwaysOpen: true, //deprecated, use collapsible - animated: 'slide', - autoHeight: true, - clearStyle: false, - collapsible: false, - event: "click", - fillSpace: false, - header: "> li > :first-child,> :not(li):even", - icons: { - header: "ui-icon-triangle-1-e", - headerSelected: "ui-icon-triangle-1-s" - }, - navigation: false, - navigationFilter: function() { - return this.href.toLowerCase() == location.href.toLowerCase(); - } - }, + version: "1.8.2", animations: { slide: function(options, additions) { options = $.extend({ @@ -5405,7 +5810,7 @@ $.extend($.ui.accordion, { return; } var overflow = options.toShow.css('overflow'), - percentDone, + percentDone = 0, showProps = {}, hideProps = {}, fxAttrs = [ "height", "paddingTop", "paddingBottom" ], @@ -5414,10 +5819,10 @@ $.extend($.ui.accordion, { var s = options.toShow; originalWidth = s[0].style.width; s.width( parseInt(s.parent().width(),10) - parseInt(s.css("paddingLeft"),10) - parseInt(s.css("paddingRight"),10) - (parseInt(s.css("borderLeftWidth"),10) || 0) - (parseInt(s.css("borderRightWidth"),10) || 0) ); - + $.each(fxAttrs, function(i, prop) { hideProps[prop] = 'hide'; - + var parts = ('' + $.css(options.toShow[0], prop)).match(/^([\d+-.]+)(.*)$/); showProps[prop] = { value: parts[1], @@ -5431,9 +5836,10 @@ $.extend($.ui.accordion, { // IE gets very inconsistent results when animating elements // with small values, which is common for padding if (settings.prop == 'height') { - percentDone = (settings.now - settings.start) / (settings.end - settings.start); + percentDone = ( settings.end - settings.start === 0 ) ? 0 : + (settings.now - settings.start) / (settings.end - settings.start); } - + options.toShow[0].style[settings.prop] = (percentDone * showProps[settings.prop].value) + showProps[settings.prop].unit; }, @@ -5454,35 +5860,906 @@ $.extend($.ui.accordion, { easing: options.down ? "easeOutBounce" : "swing", duration: options.down ? 1000 : 200 }); - }, - easeslide: function(options) { - this.slide(options, { - easing: "easeinout", - duration: 700 - }); } } }); })(jQuery); /* - * jQuery UI Datepicker 1.7.2 + * jQuery UI Autocomplete 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function( $ ) { + +$.widget( "ui.autocomplete", { + options: { + minLength: 1, + delay: 300 + }, + _create: function() { + var self = this, + doc = this.element[ 0 ].ownerDocument; + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ) + // TODO verify these actually work as intended + .attr({ + role: "textbox", + "aria-autocomplete": "list", + "aria-haspopup": "true" + }) + .bind( "keydown.autocomplete", function( event ) { + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + self._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + self._move( "nextPage", event ); + break; + case keyCode.UP: + self._move( "previous", event ); + // prevent moving cursor to beginning of text field in some browsers + event.preventDefault(); + break; + case keyCode.DOWN: + self._move( "next", event ); + // prevent moving cursor to end of text field in some browsers + event.preventDefault(); + break; + case keyCode.ENTER: + case keyCode.NUMPAD_ENTER: + // when menu is open or has focus + if ( self.menu.active ) { + event.preventDefault(); + } + //passthrough - ENTER and TAB both select the current element + case keyCode.TAB: + if ( !self.menu.active ) { + return; + } + self.menu.select( event ); + break; + case keyCode.ESCAPE: + self.element.val( self.term ); + self.close( event ); + break; + case keyCode.LEFT: + case keyCode.RIGHT: + case keyCode.SHIFT: + case keyCode.CONTROL: + case keyCode.ALT: + case keyCode.COMMAND: + case keyCode.COMMAND_RIGHT: + case keyCode.INSERT: + case keyCode.CAPS_LOCK: + case keyCode.END: + case keyCode.HOME: + // ignore metakeys (shift, ctrl, alt) + break; + default: + // keypress is triggered before the input value is changed + clearTimeout( self.searching ); + self.searching = setTimeout(function() { + self.search( null, event ); + }, self.options.delay ); + break; + } + }) + .bind( "focus.autocomplete", function() { + self.selectedItem = null; + self.previous = self.element.val(); + }) + .bind( "blur.autocomplete", function( event ) { + clearTimeout( self.searching ); + // clicks on the menu (or a button to trigger a search) will cause a blur event + self.closing = setTimeout(function() { + self.close( event ); + self._change( event ); + }, 150 ); + }); + this._initSource(); + this.response = function() { + return self._response.apply( self, arguments ); + }; + this.menu = $( "<ul></ul>" ) + .addClass( "ui-autocomplete" ) + .appendTo( "body", doc ) + // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) + .mousedown(function() { + // use another timeout to make sure the blur-event-handler on the input was already triggered + setTimeout(function() { + clearTimeout( self.closing ); + }, 13); + }) + .menu({ + focus: function( event, ui ) { + var item = ui.item.data( "item.autocomplete" ); + if ( false !== self._trigger( "focus", null, { item: item } ) ) { + // use value to match what will end up in the input, if it was a key event + if ( /^key/.test(event.originalEvent.type) ) { + self.element.val( item.value ); + } + } + }, + selected: function( event, ui ) { + var item = ui.item.data( "item.autocomplete" ); + if ( false !== self._trigger( "select", event, { item: item } ) ) { + self.element.val( item.value ); + } + self.close( event ); + // only trigger when focus was lost (click on menu) + var previous = self.previous; + if ( self.element[0] !== doc.activeElement ) { + self.element.focus(); + self.previous = previous; + } + self.selectedItem = item; + }, + blur: function( event, ui ) { + if ( self.menu.element.is(":visible") ) { + self.element.val( self.term ); + } + } + }) + .zIndex( this.element.zIndex() + 1 ) + // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 + .css({ top: 0, left: 0 }) + .hide() + .data( "menu" ); + if ( $.fn.bgiframe ) { + this.menu.element.bgiframe(); + } + }, + + destroy: function() { + this.element + .removeClass( "ui-autocomplete-input" ) + .removeAttr( "autocomplete" ) + .removeAttr( "role" ) + .removeAttr( "aria-autocomplete" ) + .removeAttr( "aria-haspopup" ); + this.menu.element.remove(); + $.Widget.prototype.destroy.call( this ); + }, + + _setOption: function( key ) { + $.Widget.prototype._setOption.apply( this, arguments ); + if ( key === "source" ) { + this._initSource(); + } + }, + + _initSource: function() { + var array, + url; + if ( $.isArray(this.options.source) ) { + array = this.options.source; + this.source = function( request, response ) { + response( $.ui.autocomplete.filter(array, request.term) ); + }; + } else if ( typeof this.options.source === "string" ) { + url = this.options.source; + this.source = function( request, response ) { + $.getJSON( url, request, response ); + }; + } else { + this.source = this.options.source; + } + }, + + search: function( value, event ) { + value = value != null ? value : this.element.val(); + if ( value.length < this.options.minLength ) { + return this.close( event ); + } + + clearTimeout( this.closing ); + if ( this._trigger("search") === false ) { + return; + } + + return this._search( value ); + }, + + _search: function( value ) { + this.term = this.element + .addClass( "ui-autocomplete-loading" ) + // always save the actual value, not the one passed as an argument + .val(); + + this.source( { term: value }, this.response ); + }, + + _response: function( content ) { + if ( content.length ) { + content = this._normalize( content ); + this._suggest( content ); + this._trigger( "open" ); + } else { + this.close(); + } + this.element.removeClass( "ui-autocomplete-loading" ); + }, + + close: function( event ) { + clearTimeout( this.closing ); + if ( this.menu.element.is(":visible") ) { + this._trigger( "close", event ); + this.menu.element.hide(); + this.menu.deactivate(); + } + }, + + _change: function( event ) { + if ( this.previous !== this.element.val() ) { + this._trigger( "change", event, { item: this.selectedItem } ); + } + }, + + _normalize: function( items ) { + // assume all items have the right format when the first item is complete + if ( items.length && items[0].label && items[0].value ) { + return items; + } + return $.map( items, function(item) { + if ( typeof item === "string" ) { + return { + label: item, + value: item + }; + } + return $.extend({ + label: item.label || item.value, + value: item.value || item.label + }, item ); + }); + }, + + _suggest: function( items ) { + var ul = this.menu.element + .empty() + .zIndex( this.element.zIndex() + 1 ), + menuWidth, + textWidth; + this._renderMenu( ul, items ); + // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate + this.menu.deactivate(); + this.menu.refresh(); + this.menu.element.show().position({ + my: "left top", + at: "left bottom", + of: this.element, + collision: "none" + }); + + menuWidth = ul.width( "" ).width(); + textWidth = this.element.width(); + ul.width( Math.max( menuWidth, textWidth ) ); + }, + + _renderMenu: function( ul, items ) { + var self = this; + $.each( items, function( index, item ) { + self._renderItem( ul, item ); + }); + }, + + _renderItem: function( ul, item) { + return $( "<li></li>" ) + .data( "item.autocomplete", item ) + .append( "<a>" + item.label + "</a>" ) + .appendTo( ul ); + }, + + _move: function( direction, event ) { + if ( !this.menu.element.is(":visible") ) { + this.search( null, event ); + return; + } + if ( this.menu.first() && /^previous/.test(direction) || + this.menu.last() && /^next/.test(direction) ) { + this.element.val( this.term ); + this.menu.deactivate(); + return; + } + this.menu[ direction ]( event ); + }, + + widget: function() { + return this.menu.element; + } +}); + +$.extend( $.ui.autocomplete, { + escapeRegex: function( value ) { + return value.replace( /([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1" ); + }, + filter: function(array, term) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); + return $.grep( array, function(value) { + return matcher.test( value.label || value.value || value ); + }); + } +}); + +}( jQuery )); + +/* + * jQuery UI Menu (not officially released) + * + * This widget isn't yet finished and the API is subject to change. We plan to finish + * it for the next release. You're welcome to give it a try anyway and give us feedback, + * as long as you're okay with migrating your code later on. We can help with that, too. + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Menu + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function($) { + +$.widget("ui.menu", { + _create: function() { + var self = this; + this.element + .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") + .attr({ + role: "listbox", + "aria-activedescendant": "ui-active-menuitem" + }) + .click(function( event ) { + if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) { + return; + } + // temporary + event.preventDefault(); + self.select( event ); + }); + this.refresh(); + }, + + refresh: function() { + var self = this; + + // don't refresh list items that are already adapted + var items = this.element.children("li:not(.ui-menu-item):has(a)") + .addClass("ui-menu-item") + .attr("role", "menuitem"); + + items.children("a") + .addClass("ui-corner-all") + .attr("tabindex", -1) + // mouseenter doesn't work with event delegation + .mouseenter(function( event ) { + self.activate( event, $(this).parent() ); + }) + .mouseleave(function() { + self.deactivate(); + }); + }, + + activate: function( event, item ) { + this.deactivate(); + if (this.hasScroll()) { + var offset = item.offset().top - this.element.offset().top, + scroll = this.element.attr("scrollTop"), + elementHeight = this.element.height(); + if (offset < 0) { + this.element.attr("scrollTop", scroll + offset); + } else if (offset > elementHeight) { + this.element.attr("scrollTop", scroll + offset - elementHeight + item.height()); + } + } + this.active = item.eq(0) + .children("a") + .addClass("ui-state-hover") + .attr("id", "ui-active-menuitem") + .end(); + this._trigger("focus", event, { item: item }); + }, + + deactivate: function() { + if (!this.active) { return; } + + this.active.children("a") + .removeClass("ui-state-hover") + .removeAttr("id"); + this._trigger("blur"); + this.active = null; + }, + + next: function(event) { + this.move("next", ".ui-menu-item:first", event); + }, + + previous: function(event) { + this.move("prev", ".ui-menu-item:last", event); + }, + + first: function() { + return this.active && !this.active.prev().length; + }, + + last: function() { + return this.active && !this.active.next().length; + }, + + move: function(direction, edge, event) { + if (!this.active) { + this.activate(event, this.element.children(edge)); + return; + } + var next = this.active[direction + "All"](".ui-menu-item").eq(0); + if (next.length) { + this.activate(event, next); + } else { + this.activate(event, this.element.children(edge)); + } + }, + + // TODO merge with previousPage + nextPage: function(event) { + if (this.hasScroll()) { + // TODO merge with no-scroll-else + if (!this.active || this.last()) { + this.activate(event, this.element.children(":first")); + return; + } + var base = this.active.offset().top, + height = this.element.height(), + result = this.element.children("li").filter(function() { + var close = $(this).offset().top - base - height + $(this).height(); + // TODO improve approximation + return close < 10 && close > -10; + }); + + // TODO try to catch this earlier when scrollTop indicates the last page anyway + if (!result.length) { + result = this.element.children(":last"); + } + this.activate(event, result); + } else { + this.activate(event, this.element.children(!this.active || this.last() ? ":first" : ":last")); + } + }, + + // TODO merge with nextPage + previousPage: function(event) { + if (this.hasScroll()) { + // TODO merge with no-scroll-else + if (!this.active || this.first()) { + this.activate(event, this.element.children(":last")); + return; + } + + var base = this.active.offset().top, + height = this.element.height(); + result = this.element.children("li").filter(function() { + var close = $(this).offset().top - base + height - $(this).height(); + // TODO improve approximation + return close < 10 && close > -10; + }); + + // TODO try to catch this earlier when scrollTop indicates the last page anyway + if (!result.length) { + result = this.element.children(":first"); + } + this.activate(event, result); + } else { + this.activate(event, this.element.children(!this.active || this.first() ? ":last" : ":first")); + } + }, + + hasScroll: function() { + return this.element.height() < this.element.attr("scrollHeight"); + }, + + select: function( event ) { + this._trigger("selected", event, { item: this.active }); + } +}); + +}(jQuery)); +/* + * jQuery UI Button 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Button + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $ ) { + +var lastActive, + baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", + stateClasses = "ui-state-hover ui-state-active ", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon ui-button-text-only", + formResetHandler = function( event ) { + $( ":ui-button", event.target.form ).each(function() { + var inst = $( this ).data( "button" ); + setTimeout(function() { + inst.refresh(); + }, 1 ); + }); + }, + radioGroup = function( radio ) { + var name = radio.name, + form = radio.form, + radios = $( [] ); + if ( name ) { + if ( form ) { + radios = $( form ).find( "[name='" + name + "']" ); + } else { + radios = $( "[name='" + name + "']", radio.ownerDocument ) + .filter(function() { + return !this.form; + }); + } + } + return radios; + }; + +$.widget( "ui.button", { + options: { + text: true, + label: null, + icons: { + primary: null, + secondary: null + } + }, + _create: function() { + this.element.closest( "form" ) + .unbind( "reset.button" ) + .bind( "reset.button", formResetHandler ); + + this._determineButtonType(); + this.hasTitle = !!this.buttonElement.attr( "title" ); + + var self = this, + options = this.options, + toggleButton = this.type === "checkbox" || this.type === "radio", + hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), + focusClass = "ui-state-focus"; + + if ( options.label === null ) { + options.label = this.buttonElement.html(); + } + + if ( this.element.is( ":disabled" ) ) { + options.disabled = true; + } + + this.buttonElement + .addClass( baseClasses ) + .attr( "role", "button" ) + .bind( "mouseenter.button", function() { + if ( options.disabled ) { + return; + } + $( this ).addClass( "ui-state-hover" ); + if ( this === lastActive ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "mouseleave.button", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( hoverClass ); + }) + .bind( "focus.button", function() { + // no need to check disabled, focus won't be triggered anyway + $( this ).addClass( focusClass ); + }) + .bind( "blur.button", function() { + $( this ).removeClass( focusClass ); + }); + + if ( toggleButton ) { + this.element.bind( "change.button", function() { + self.refresh(); + }); + } + + if ( this.type === "checkbox" ) { + this.buttonElement.bind( "click.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).toggleClass( "ui-state-active" ); + self.buttonElement.attr( "aria-pressed", self.element[0].checked ); + }); + } else if ( this.type === "radio" ) { + this.buttonElement.bind( "click.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + self.buttonElement.attr( "aria-pressed", true ); + + var radio = self.element[ 0 ]; + radioGroup( radio ) + .not( radio ) + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", false ); + }); + } else { + this.buttonElement + .bind( "mousedown.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + lastActive = this; + $( document ).one( "mouseup", function() { + lastActive = null; + }); + }) + .bind( "mouseup.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).removeClass( "ui-state-active" ); + }) + .bind( "keydown.button", function(event) { + if ( options.disabled ) { + return false; + } + if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "keyup.button", function() { + $( this ).removeClass( "ui-state-active" ); + }); + + if ( this.buttonElement.is("a") ) { + this.buttonElement.keyup(function(event) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + // TODO pass through original event correctly (just as 2nd argument doesn't work) + $( this ).click(); + } + }); + } + } + + // TODO: pull out $.Widget's handling for the disabled option into + // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can + // be overridden by individual plugins + this._setOption( "disabled", options.disabled ); + }, + + _determineButtonType: function() { + + if ( this.element.is(":checkbox") ) { + this.type = "checkbox"; + } else { + if ( this.element.is(":radio") ) { + this.type = "radio"; + } else { + if ( this.element.is("input") ) { + this.type = "input"; + } else { + this.type = "button"; + } + } + } + + if ( this.type === "checkbox" || this.type === "radio" ) { + // we don't search against the document in case the element + // is disconnected from the DOM + this.buttonElement = this.element.parents().last() + .find( "[for=" + this.element.attr("id") + "]" ); + this.element.addClass( "ui-helper-hidden-accessible" ); + + var checked = this.element.is( ":checked" ); + if ( checked ) { + this.buttonElement.addClass( "ui-state-active" ); + } + this.buttonElement.attr( "aria-pressed", checked ); + } else { + this.buttonElement = this.element; + } + }, + + widget: function() { + return this.buttonElement; + }, + + destroy: function() { + this.element + .removeClass( "ui-helper-hidden-accessible" ); + this.buttonElement + .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) + .removeAttr( "role" ) + .removeAttr( "aria-pressed" ) + .html( this.buttonElement.find(".ui-button-text").html() ); + + if ( !this.hasTitle ) { + this.buttonElement.removeAttr( "title" ); + } + + $.Widget.prototype.destroy.call( this ); + }, + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); + if ( key === "disabled" ) { + if ( value ) { + this.element.attr( "disabled", true ); + } else { + this.element.removeAttr( "disabled" ); + } + } + this._resetButton(); + }, + + refresh: function() { + var isDisabled = this.element.is( ":disabled" ); + if ( isDisabled !== this.options.disabled ) { + this._setOption( "disabled", isDisabled ); + } + if ( this.type === "radio" ) { + radioGroup( this.element[0] ).each(function() { + if ( $( this ).is( ":checked" ) ) { + $( this ).button( "widget" ) + .addClass( "ui-state-active" ) + .attr( "aria-pressed", true ); + } else { + $( this ).button( "widget" ) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", false ); + } + }); + } else if ( this.type === "checkbox" ) { + if ( this.element.is( ":checked" ) ) { + this.buttonElement + .addClass( "ui-state-active" ) + .attr( "aria-pressed", true ); + } else { + this.buttonElement + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", false ); + } + } + }, + + _resetButton: function() { + if ( this.type === "input" ) { + if ( this.options.label ) { + this.element.val( this.options.label ); + } + return; + } + var buttonElement = this.buttonElement.removeClass( typeClasses ), + buttonText = $( "<span></span>" ) + .addClass( "ui-button-text" ) + .html( this.options.label ) + .appendTo( buttonElement.empty() ) + .text(), + icons = this.options.icons, + multipleIcons = icons.primary && icons.secondary; + if ( icons.primary || icons.secondary ) { + buttonElement.addClass( "ui-button-text-icon" + + ( multipleIcons ? "s" : "" ) ); + if ( icons.primary ) { + buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); + } + if ( icons.secondary ) { + buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); + } + if ( !this.options.text ) { + buttonElement + .addClass( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ) + .removeClass( "ui-button-text-icons ui-button-text-icon" ); + if ( !this.hasTitle ) { + buttonElement.attr( "title", buttonText ); + } + } + } else { + buttonElement.addClass( "ui-button-text-only" ); + } + } +}); + +$.widget( "ui.buttonset", { + _create: function() { + this.element.addClass( "ui-buttonset" ); + this._init(); + }, + + _init: function() { + this.refresh(); + }, + + _setOption: function( key, value ) { + if ( key === "disabled" ) { + this.buttons.button( "option", key, value ); + } + + $.Widget.prototype._setOption.apply( this, arguments ); + }, + + refresh: function() { + this.buttons = this.element.find( ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" ) + .filter( ":ui-button" ) + .button( "refresh" ) + .end() + .not( ":ui-button" ) + .button() + .end() + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) + .filter( ":first" ) + .addClass( "ui-corner-left" ) + .end() + .filter( ":last" ) + .addClass( "ui-corner-right" ) + .end() + .end(); + }, + + destroy: function() { + this.element.removeClass( "ui-buttonset" ); + this.buttons + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-left ui-corner-right" ) + .end() + .button( "destroy" ); + + $.Widget.prototype.destroy.call( this ); + } +}); + +}( jQuery ) ); +/* + * jQuery UI Datepicker 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Datepicker * * Depends: - * ui.core.js + * jquery.ui.core.js */ (function($) { // hide the namespace -$.extend($.ui, { datepicker: { version: "1.7.2" } }); +$.extend($.ui, { datepicker: { version: "1.8.2" } }); var PROP_NAME = 'datepicker'; +var dpuuid = new Date().getTime(); /* Date picker manager. Use the singleton instance of this class, $.datepicker, to interact with the date picker. @@ -5517,14 +6794,17 @@ function Datepicker() { dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday + weekHeader: 'Wk', // Column header for week of the year dateFormat: 'mm/dd/yy', // See format options on parseDate firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false // True if right-to-left language, false if left-to-right + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: '' // Additional text to append to the year in the month headers }; this._defaults = { // Global defaults for all the date picker instances showOn: 'focus', // 'focus' for popup on focus, // 'button' for trigger button, or 'both' for either - showAnim: 'show', // Name of jQuery animation for popup + showAnim: 'fadeIn', // Name of jQuery animation for popup showOptions: {}, // Options for enhanced animations defaultDate: null, // Used when field is blank: actual date, // +/-number for offset from today, null for today @@ -5538,10 +6818,12 @@ function Datepicker() { gotoCurrent: false, // True if today link goes back to current selection instead changeMonth: false, // True if month can be selected directly, false if only prev/next changeYear: false, // True if year can be selected directly, false if only prev/next - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearRange: '-10:+10', // Range of years to display in drop-down, - // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) + yearRange: 'c-10:c+10', // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it calculateWeek: this.iso8601Week, // How to calculate the week of the year, // takes a Date and returns the number of the week for it shortYearCutoff: '+10', // Short year values < this are in the current century, @@ -5549,7 +6831,7 @@ function Datepicker() { // string value starting with '+' for current year + value minDate: null, // The earliest selectable date, or null for no limit maxDate: null, // The latest selectable date, or null for no limit - duration: 'normal', // Duration of display/closure + duration: 'fast', // Duration of display/closure beforeShowDay: null, // Function that takes a date and returns an array with // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', // [2] = cell title (optional), e.g. $.datepicker.noWeekends @@ -5565,7 +6847,8 @@ function Datepicker() { altField: '', // Selector for an alternate field to store selected dates into altFormat: '', // The date format to use for the alternate field constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false // True to show button panel, false to not show it + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false // True to size the input for the date format, false to leave as is }; $.extend(this._defaults, this.regional['']); this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>'); @@ -5580,6 +6863,11 @@ $.extend(Datepicker.prototype, { if (this.debug) console.log.apply('', arguments); }, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, /* Override the default settings for all instances of the date picker. @param settings object - the new settings to use as defaults (anonymous object) @@ -5608,8 +6896,10 @@ $.extend(Datepicker.prototype, { } var nodeName = target.nodeName.toLowerCase(); var inline = (nodeName == 'div' || nodeName == 'span'); - if (!target.id) - target.id = 'dp' + (++this.uuid); + if (!target.id) { + this.uuid += 1; + target.id = 'dp' + this.uuid; + } var inst = this._newInst($(target), inline); inst.settings = $.extend({}, settings || {}, inlineSettings || {}); if (nodeName == 'input') { @@ -5621,7 +6911,7 @@ $.extend(Datepicker.prototype, { /* Create a new instance object. */ _newInst: function(target, inline) { - var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars + var id = target[0].id.replace(/([^A-Za-z0-9_])/g, '\\\\$1'); // escape jQuery meta chars return {id: id, input: target, // associated target selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection drawMonth: 0, drawYear: 0, // month being drawn @@ -5637,12 +6927,31 @@ $.extend(Datepicker.prototype, { inst.trigger = $([]); if (input.hasClass(this.markerClassName)) return; + this._attachments(input, inst); + input.addClass(this.markerClassName).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp). + bind("setData.datepicker", function(event, key, value) { + inst.settings[key] = value; + }).bind("getData.datepicker", function(event, key) { + return this._get(inst, key); + }); + this._autoSize(inst); + $.data(target, PROP_NAME, inst); + }, + + /* Make attachments based on settings. */ + _attachments: function(input, inst) { var appendText = this._get(inst, 'appendText'); var isRTL = this._get(inst, 'isRTL'); + if (inst.append) + inst.append.remove(); if (appendText) { inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>'); input[isRTL ? 'before' : 'after'](inst.append); } + input.unbind('focus', this._showDatepicker); + if (inst.trigger) + inst.trigger.remove(); var showOn = this._get(inst, 'showOn'); if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field input.focus(this._showDatepicker); @@ -5657,20 +6966,39 @@ $.extend(Datepicker.prototype, { { src:buttonImage, alt:buttonText, title:buttonText }))); input[isRTL ? 'before' : 'after'](inst.trigger); inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) + if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) $.datepicker._hideDatepicker(); else - $.datepicker._showDatepicker(target); + $.datepicker._showDatepicker(input[0]); return false; }); } - input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress). - bind("setData.datepicker", function(event, key, value) { - inst.settings[key] = value; - }).bind("getData.datepicker", function(event, key) { - return this._get(inst, key); - }); - $.data(target, PROP_NAME, inst); + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, 'autoSize') && !inst.inline) { + var date = new Date(2009, 12 - 1, 20); // Ensure double digits + var dateFormat = this._get(inst, 'dateFormat'); + if (dateFormat.match(/[DM]/)) { + var findMax = function(names) { + var max = 0; + var maxI = 0; + for (var i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + 'monthNames' : 'monthNamesShort')))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); + } + inst.input.attr('size', this._formatDate(inst, date).length); + } }, /* Attach an inline date picker to a div. */ @@ -5685,26 +7013,27 @@ $.extend(Datepicker.prototype, { return this._get(inst, key); }); $.data(target, PROP_NAME, inst); - this._setDate(inst, this._getDefaultDate(inst)); + this._setDate(inst, this._getDefaultDate(inst), true); this._updateDatepicker(inst); this._updateAlternate(inst); }, /* Pop-up the date picker in a "dialog" box. @param input element - ignored - @param dateText string - the initial date to display (in the current format) - @param onSelect function - the function(dateText) to call when a date is selected + @param date string or Date - the initial date to display + @param onSelect function - the function to call when a date is selected @param settings object - update the dialog date picker instance's settings (anonymous object) @param pos int[2] - coordinates for the dialog's position within the screen or event - with x/y coordinates or leave empty for default (screen centre) @return the manager object */ - _dialogDatepicker: function(input, dateText, onSelect, settings, pos) { + _dialogDatepicker: function(input, date, onSelect, settings, pos) { var inst = this._dialogInst; // internal instance if (!inst) { - var id = 'dp' + (++this.uuid); + this.uuid += 1; + var id = 'dp' + this.uuid; this._dialogInput = $('<input type="text" id="' + id + - '" size="1" style="position: absolute; top: -100px;"/>'); + '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'); this._dialogInput.keydown(this._doKeyDown); $('body').append(this._dialogInput); inst = this._dialogInst = this._newInst(this._dialogInput, false); @@ -5712,12 +7041,13 @@ $.extend(Datepicker.prototype, { $.data(this._dialogInput[0], PROP_NAME, inst); } extendRemove(inst.settings, settings || {}); - this._dialogInput.val(dateText); + date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); if (!this._pos) { - var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; - var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; + var browserWidth = document.documentElement.clientWidth; + var browserHeight = document.documentElement.clientHeight; var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; var scrollY = document.documentElement.scrollTop || document.body.scrollTop; this._pos = // should use actual width/height below @@ -5725,7 +7055,7 @@ $.extend(Datepicker.prototype, { } // move input on screen for focus, but hidden behind dialog - this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); + this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); inst.settings.onSelect = onSelect; this._inDialog = true; this.dpDiv.addClass(this._dialogClass); @@ -5752,7 +7082,8 @@ $.extend(Datepicker.prototype, { $target.removeClass(this.markerClassName). unbind('focus', this._showDatepicker). unbind('keydown', this._doKeyDown). - unbind('keypress', this._doKeyPress); + unbind('keypress', this._doKeyPress). + unbind('keyup', this._doKeyUp); } else if (nodeName == 'div' || nodeName == 'span') $target.removeClass(this.markerClassName).empty(); }, @@ -5853,10 +7184,12 @@ $.extend(Datepicker.prototype, { } if (inst) { if (this._curInst == inst) { - this._hideDatepicker(null); + this._hideDatepicker(); } - var date = this._getDateDatepicker(target); + var date = this._getDateDatepicker(target, true); extendRemove(inst.settings, settings); + this._attachments($(target), inst); + this._autoSize(inst); this._setDateDatepicker(target, date); this._updateDatepicker(inst); } @@ -5878,25 +7211,24 @@ $.extend(Datepicker.prototype, { /* Set the dates for a jQuery selection. @param target element - the target input field or division or span - @param date Date - the new date - @param endDate Date - the new end date for a range (optional) */ - _setDateDatepicker: function(target, date, endDate) { + @param date Date - the new date */ + _setDateDatepicker: function(target, date) { var inst = this._getInst(target); if (inst) { - this._setDate(inst, date, endDate); + this._setDate(inst, date); this._updateDatepicker(inst); this._updateAlternate(inst); } }, /* Get the date(s) for the first entry in a jQuery selection. - @param target element - the target input field or division or span - @return Date - the current date or - Date[2] - the current dates for a range */ - _getDateDatepicker: function(target) { + @param target element - the target input field or division or span + @param noDefault boolean - true if no default date is to be used + @return Date - the current date */ + _getDateDatepicker: function(target, noDefault) { var inst = this._getInst(target); if (inst && !inst.inline) - this._setDateFromField(inst); + this._setDateFromField(inst, noDefault); return (inst ? this._getDate(inst) : null); }, @@ -5908,17 +7240,18 @@ $.extend(Datepicker.prototype, { inst._keyEvent = true; if ($.datepicker._datepickerShowing) switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(null, ''); + case 9: $.datepicker._hideDatepicker(); + handled = false; break; // hide on tab out - case 13: var sel = $('td.' + $.datepicker._dayOverClass + - ', td.' + $.datepicker._currentClass, inst.dpDiv); + case 13: var sel = $('td.' + $.datepicker._dayOverClass, inst.dpDiv). + add($('td.' + $.datepicker._currentClass, inst.dpDiv)); if (sel[0]) $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); else - $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); + $.datepicker._hideDatepicker(); return false; // don't submit the form break; // select the value on enter - case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration')); + case 27: $.datepicker._hideDatepicker(); break; // hide on escape case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? -$.datepicker._get(inst, 'stepBigMonths') : @@ -5979,6 +7312,27 @@ $.extend(Datepicker.prototype, { } }, + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var inst = $.datepicker._getInst(event.target); + if (inst.input.val() != inst.lastVal) { + try { + var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (event) { + $.datepicker.log(event); + } + } + return true; + }, + /* Pop-up the date picker for a given input field. @param input element - the input field attached to the date picker or event - if triggered by focus */ @@ -5989,9 +7343,12 @@ $.extend(Datepicker.prototype, { if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here return; var inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst != inst) { + $.datepicker._curInst.dpDiv.stop(true, true); + } var beforeShow = $.datepicker._get(inst, 'beforeShow'); extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); - $.datepicker._hideDatepicker(null, ''); + inst.lastVal = null; $.datepicker._lastInput = input; $.datepicker._setDateFromField(inst); if ($.datepicker._inDialog) // hide cursor @@ -6011,7 +7368,6 @@ $.extend(Datepicker.prototype, { } var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; $.datepicker._pos = null; - inst.rangeStart = null; // determine sizing offscreen inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); $.datepicker._updateDatepicker(inst); @@ -6022,34 +7378,36 @@ $.extend(Datepicker.prototype, { 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', left: offset.left + 'px', top: offset.top + 'px'}); if (!inst.inline) { - var showAnim = $.datepicker._get(inst, 'showAnim') || 'show'; + var showAnim = $.datepicker._get(inst, 'showAnim'); var duration = $.datepicker._get(inst, 'duration'); var postProcess = function() { $.datepicker._datepickerShowing = true; - if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems - $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4, - height: inst.dpDiv.height() + 4}); + var borders = $.datepicker._getBorders(inst.dpDiv); + inst.dpDiv.find('iframe.ui-datepicker-cover'). // IE6- only + css({left: -borders[0], top: -borders[1], + width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); }; + inst.dpDiv.zIndex($(input).zIndex()+1); if ($.effects && $.effects[showAnim]) inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); else - inst.dpDiv[showAnim](duration, postProcess); - if (duration == '') + inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); + if (!showAnim || !duration) postProcess(); - if (inst.input[0].type != 'hidden') - inst.input[0].focus(); + if (inst.input.is(':visible') && !inst.input.is(':disabled')) + inst.input.focus(); $.datepicker._curInst = inst; } }, /* Generate the date picker content. */ _updateDatepicker: function(inst) { - var dims = {width: inst.dpDiv.width() + 4, - height: inst.dpDiv.height() + 4}; var self = this; + var borders = $.datepicker._getBorders(inst.dpDiv); inst.dpDiv.empty().append(this._generateHTML(inst)) - .find('iframe.ui-datepicker-cover'). - css({width: dims.width, height: dims.height}) + .find('iframe.ui-datepicker-cover') // IE6- only + .css({left: -borders[0], top: -borders[1], + width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) .end() .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a') .bind('mouseout', function(){ @@ -6072,17 +7430,28 @@ $.extend(Datepicker.prototype, { var numMonths = this._getNumberOfMonths(inst); var cols = numMonths[1]; var width = 17; - if (cols > 1) { + if (cols > 1) inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); - } else { + else inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); - } inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + 'Class']('ui-datepicker-multi'); inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + 'Class']('ui-datepicker-rtl'); - if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst) - $(inst.input[0]).focus(); + if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && + inst.input.is(':visible') && !inst.input.is(':disabled')) + inst.input.focus(); + }, + + /* Retrieve the size of left and top borders for an element. + @param elem (jQuery object) the element of interest + @return (number[2]) the left and top borders */ + _getBorders: function(elem) { + var convert = function(value) { + return {thin: 1, medium: 2, thick: 3}[value] || value; + }; + return [parseFloat(convert(elem.css('border-left-width'))), + parseFloat(convert(elem.css('border-top-width')))]; }, /* Check positioning to remain on screen. */ @@ -6091,54 +7460,53 @@ $.extend(Datepicker.prototype, { var dpHeight = inst.dpDiv.outerHeight(); var inputWidth = inst.input ? inst.input.outerWidth() : 0; var inputHeight = inst.input ? inst.input.outerHeight() : 0; - var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft(); - var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop(); + var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft(); + var viewHeight = document.documentElement.clientHeight + $(document).scrollTop(); offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; // now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0; - offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0; + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); return offset; }, /* Find an object's position on the screen. */ _findPos: function(obj) { + var inst = this._getInst(obj); + var isRTL = this._get(inst, 'isRTL'); while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { - obj = obj.nextSibling; + obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; } var position = $(obj).offset(); return [position.left, position.top]; }, /* Hide the date picker from view. - @param input element - the input field attached to the date picker - @param duration string - the duration over which to close the date picker */ - _hideDatepicker: function(input, duration) { + @param input element - the input field attached to the date picker */ + _hideDatepicker: function(input) { var inst = this._curInst; if (!inst || (input && inst != $.data(input, PROP_NAME))) return; - if (inst.stayOpen) - this._selectDate('#' + inst.id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); - inst.stayOpen = false; if (this._datepickerShowing) { - duration = (duration != null ? duration : this._get(inst, 'duration')); var showAnim = this._get(inst, 'showAnim'); + var duration = this._get(inst, 'duration'); var postProcess = function() { $.datepicker._tidyDialog(inst); + this._curInst = null; }; - if (duration != '' && $.effects && $.effects[showAnim]) - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), - duration, postProcess); + if ($.effects && $.effects[showAnim]) + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); else - inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' : - (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess); - if (duration == '') - this._tidyDialog(inst); + inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : + (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); + if (!showAnim) + postProcess(); var onClose = this._get(inst, 'onClose'); if (onClose) onClose.apply((inst.input ? inst.input[0] : null), @@ -6154,7 +7522,6 @@ $.extend(Datepicker.prototype, { } this._inDialog = false; } - this._curInst = null; }, /* Tidy up after a dialog display. */ @@ -6167,11 +7534,12 @@ $.extend(Datepicker.prototype, { if (!$.datepicker._curInst) return; var $target = $(event.target); - if (($target.parents('#' + $.datepicker._mainDivId).length == 0) && + if ($target[0].id != $.datepicker._mainDivId && + $target.parents('#' + $.datepicker._mainDivId).length == 0 && !$target.hasClass($.datepicker.markerClassName) && !$target.hasClass($.datepicker._triggerClass) && $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) - $.datepicker._hideDatepicker(null, ''); + $.datepicker._hideDatepicker(); }, /* Adjust one of the date sub-fields. */ @@ -6197,10 +7565,10 @@ $.extend(Datepicker.prototype, { inst.drawYear = inst.selectedYear = inst.currentYear; } else { - var date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); + var date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); } this._notifyChange(inst); this._adjustDate(target); @@ -6223,7 +7591,7 @@ $.extend(Datepicker.prototype, { var target = $(id); var inst = this._getInst(target[0]); if (inst.input && inst._selectingMonthYear && !$.browser.msie) - inst.input[0].focus(); + inst.input.focus(); inst._selectingMonthYear = !inst._selectingMonthYear; }, @@ -6237,24 +7605,14 @@ $.extend(Datepicker.prototype, { inst.selectedDay = inst.currentDay = $('a', td).html(); inst.selectedMonth = inst.currentMonth = month; inst.selectedYear = inst.currentYear = year; - if (inst.stayOpen) { - inst.endDay = inst.endMonth = inst.endYear = null; - } this._selectDate(id, this._formatDate(inst, inst.currentDay, inst.currentMonth, inst.currentYear)); - if (inst.stayOpen) { - inst.rangeStart = this._daylightSavingAdjust( - new Date(inst.currentYear, inst.currentMonth, inst.currentDay)); - this._updateDatepicker(inst); - } }, /* Erase the input field and hide the date picker. */ _clearDate: function(id) { var target = $(id); var inst = this._getInst(target[0]); - inst.stayOpen = false; - inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null; this._selectDate(target, ''); }, @@ -6273,11 +7631,11 @@ $.extend(Datepicker.prototype, { inst.input.trigger('change'); // fire the change event if (inst.inline) this._updateDatepicker(inst); - else if (!inst.stayOpen) { - this._hideDatepicker(null, this._get(inst, 'duration')); + else { + this._hideDatepicker(); this._lastInput = inst.input[0]; if (typeof(inst.input[0]) != 'object') - inst.input[0].focus(); // restore focus + inst.input.focus(); // restore focus this._lastInput = null; } }, @@ -6288,7 +7646,7 @@ $.extend(Datepicker.prototype, { if (altField) { // update alternate field too var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); var date = this._getDate(inst); - dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); $(altField).each(function() { $(this).val(dateStr); }); } }, @@ -6305,20 +7663,13 @@ $.extend(Datepicker.prototype, { @param date Date - the date to get the week for @return number - the number of the week within the year that contains this date */ iso8601Week: function(date) { - var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()); - var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan - var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7 - firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday - if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary - checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year - return $.datepicker.iso8601Week(checkDate); - } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year - firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7; - if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary - return 1; - } - } - return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date + var checkDate = new Date(date.getTime()); + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + var time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; }, /* Parse a string value into a date object. @@ -6359,34 +7710,25 @@ $.extend(Datepicker.prototype, { // Extract a number from the string value var getNumber = function(match) { lookAhead(match); - var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2))); - var size = origSize; - var num = 0; - while (size > 0 && iValue < value.length && - value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') { - num = num * 10 + parseInt(value.charAt(iValue++),10); - size--; - } - if (size == origSize) + var size = (match == '@' ? 14 : (match == '!' ? 20 : + (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))); + var digits = new RegExp('^\\d{1,' + size + '}'); + var num = value.substring(iValue).match(digits); + if (!num) throw 'Missing number at position ' + iValue; - return num; + iValue += num[0].length; + return parseInt(num[0], 10); }; // Extract a name from the string value and convert to an index var getName = function(match, shortNames, longNames) { var names = (lookAhead(match) ? longNames : shortNames); - var size = 0; - for (var j = 0; j < names.length; j++) - size = Math.max(size, names[j].length); - var name = ''; - var iInit = iValue; - while (size > 0 && iValue < value.length) { - name += value.charAt(iValue++); - for (var i = 0; i < names.length; i++) - if (name == names[i]) - return i + 1; - size--; - } - throw 'Unknown name at position ' + iInit; + for (var i = 0; i < names.length; i++) { + if (value.substr(iValue, names[i].length) == names[i]) { + iValue += names[i].length; + return i + 1; + } + } + throw 'Unknown name at position ' + iValue; }; // Confirm that a literal character matches the string value var checkLiteral = function() { @@ -6427,6 +7769,12 @@ $.extend(Datepicker.prototype, { month = date.getMonth() + 1; day = date.getDate(); break; + case '!': + var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; case "'": if (lookAhead("'")) checkLiteral(); @@ -6469,9 +7817,13 @@ $.extend(Datepicker.prototype, { RFC_1123: 'D, d M yy', RFC_2822: 'D, d M yy', RSS: 'D, d M y', // RFC 822 + TICKS: '!', TIMESTAMP: '@', W3C: 'yy-mm-dd', // ISO 8601 + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + /* Format a date object into a string value. The format can be combinations of the following: d - day of month (no leading zero) @@ -6487,6 +7839,7 @@ $.extend(Datepicker.prototype, { y - year (two digit) yy - year (four digit) @ - Unix timestamp (ms since 01/01/1970) + ! - Windows ticks (100ns since 01/01/0001) '...' - literal text '' - single quote @@ -6542,10 +7895,8 @@ $.extend(Datepicker.prototype, { output += formatName('D', date.getDay(), dayNamesShort, dayNames); break; case 'o': - var doy = date.getDate(); - for (var m = date.getMonth() - 1; m >= 0; m--) - doy += this._getDaysInMonth(date.getFullYear(), m); - output += formatNumber('o', doy, 3); + output += formatNumber('o', + (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3); break; case 'm': output += formatNumber('m', date.getMonth() + 1, 2); @@ -6560,6 +7911,9 @@ $.extend(Datepicker.prototype, { case '@': output += date.getTime(); break; + case '!': + output += date.getTime() * 10000 + this._ticksTo1970; + break; case "'": if (lookAhead("'")) output += "'"; @@ -6577,6 +7931,13 @@ $.extend(Datepicker.prototype, { _possibleChars: function (format) { var chars = ''; var literal = false; + // Check whether a format character is doubled + var lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); + if (matches) + iFormat++; + return matches; + }; for (var iFormat = 0; iFormat < format.length; iFormat++) if (literal) if (format.charAt(iFormat) == "'" && !lookAhead("'")) @@ -6609,17 +7970,20 @@ $.extend(Datepicker.prototype, { }, /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst) { + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() == inst.lastVal) { + return; + } var dateFormat = this._get(inst, 'dateFormat'); - var dates = inst.input ? inst.input.val() : null; - inst.endDay = inst.endMonth = inst.endYear = null; - var date = defaultDate = this._getDefaultDate(inst); + var dates = inst.lastVal = inst.input ? inst.input.val() : null; + var date, defaultDate; + date = defaultDate = this._getDefaultDate(inst); var settings = this._getFormatConfig(inst); try { date = this.parseDate(dateFormat, dates, settings) || defaultDate; } catch (event) { this.log(event); - date = defaultDate; + dates = (noDefault ? '' : dates); } inst.selectedDay = date.getDate(); inst.drawMonth = inst.selectedMonth = date.getMonth(); @@ -6632,23 +7996,27 @@ $.extend(Datepicker.prototype, { /* Retrieve the default date shown on opening. */ _getDefaultDate: function(inst) { - var date = this._determineDate(this._get(inst, 'defaultDate'), new Date()); - var minDate = this._getMinMaxDate(inst, 'min', true); - var maxDate = this._getMinMaxDate(inst, 'max'); - date = (minDate && date < minDate ? minDate : date); - date = (maxDate && date > maxDate ? maxDate : date); - return date; + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); }, /* A date may be specified as an exact value or a relative one. */ - _determineDate: function(date, defaultDate) { + _determineDate: function(inst, date, defaultDate) { var offsetNumeric = function(offset) { var date = new Date(); date.setDate(date.getDate() + offset); return date; }; - var offsetString = function(offset, getDaysInMonth) { - var date = new Date(); + var offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(); var year = date.getFullYear(); var month = date.getMonth(); var day = date.getDate(); @@ -6662,19 +8030,18 @@ $.extend(Datepicker.prototype, { day += parseInt(matches[1],10) * 7; break; case 'm' : case 'M' : month += parseInt(matches[1],10); - day = Math.min(day, getDaysInMonth(year, month)); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); break; case 'y': case 'Y' : year += parseInt(matches[1],10); - day = Math.min(day, getDaysInMonth(year, month)); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); break; } matches = pattern.exec(offset); } return new Date(year, month, day); }; - date = (date == null ? defaultDate : - (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) : + date = (date == null ? defaultDate : (typeof date == 'string' ? offsetString(date) : (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date))); date = (date && date.toString() == 'Invalid Date' ? defaultDate : date); if (date) { @@ -6699,15 +8066,15 @@ $.extend(Datepicker.prototype, { }, /* Set the date(s) directly. */ - _setDate: function(inst, date, endDate) { + _setDate: function(inst, date, noChange) { var clear = !(date); var origMonth = inst.selectedMonth; var origYear = inst.selectedYear; - date = this._determineDate(date, new Date()); + date = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); inst.selectedDay = inst.currentDay = date.getDate(); inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth(); inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear(); - if (origMonth != inst.selectedMonth || origYear != inst.selectedYear) + if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) this._notifyChange(inst); this._adjustInstDate(inst); if (inst.input) { @@ -6735,11 +8102,10 @@ $.extend(Datepicker.prototype, { var numMonths = this._getNumberOfMonths(inst); var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); var stepMonths = this._get(inst, 'stepMonths'); - var stepBigMonths = this._get(inst, 'stepBigMonths'); var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - var minDate = this._getMinMaxDate(inst, 'min', true); + var minDate = this._getMinMaxDate(inst, 'min'); var maxDate = this._getMinMaxDate(inst, 'max'); var drawMonth = inst.drawMonth - showCurrentAtPos; var drawYear = inst.drawYear; @@ -6749,7 +8115,7 @@ $.extend(Datepicker.prototype, { } if (maxDate) { var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate())); + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { drawMonth--; @@ -6766,7 +8132,8 @@ $.extend(Datepicker.prototype, { this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), this._getFormatConfig(inst))); var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + + '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid + + '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' + ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' : (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>')); var nextText = this._get(inst, 'nextText'); @@ -6774,19 +8141,23 @@ $.extend(Datepicker.prototype, { this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), this._getFormatConfig(inst))); var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + + '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid + + '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' + ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' : (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>')); var currentText = this._get(inst, 'currentText'); var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); currentText = (!navigationAsDateFormat ? currentText : this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : ''); + var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid + + '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : ''); var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') + - (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' + + (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid + + '.datepicker._gotoToday(\'#' + inst.id + '\');"' + '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : ''; var firstDay = parseInt(this._get(inst, 'firstDay'),10); firstDay = (isNaN(firstDay) ? 0 : firstDay); + var showWeek = this._get(inst, 'showWeek'); var dayNames = this._get(inst, 'dayNames'); var dayNamesShort = this._get(inst, 'dayNamesShort'); var dayNamesMin = this._get(inst, 'dayNamesMin'); @@ -6794,9 +8165,8 @@ $.extend(Datepicker.prototype, { var monthNamesShort = this._get(inst, 'monthNamesShort'); var beforeShowDay = this._get(inst, 'beforeShowDay'); var showOtherMonths = this._get(inst, 'showOtherMonths'); + var selectOtherMonths = this._get(inst, 'selectOtherMonths'); var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; - var endDate = inst.endDay ? this._daylightSavingAdjust( - new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate; var defaultDate = this._getDefaultDate(inst); var html = ''; for (var row = 0; row < numMonths[0]; row++) { @@ -6806,22 +8176,25 @@ $.extend(Datepicker.prototype, { var cornerClass = ' ui-corner-all'; var calender = ''; if (isMultiMonth) { - calender += '<div class="ui-datepicker-group ui-datepicker-group-'; - switch (col) { - case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; - case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; - default: calender += 'middle'; cornerClass = ''; break; - } + calender += '<div class="ui-datepicker-group'; + if (numMonths[1] > 1) + switch (col) { + case 0: calender += ' ui-datepicker-group-first'; + cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break; + case numMonths[1]-1: calender += ' ui-datepicker-group-last'; + cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break; + default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break; + } calender += '">'; } calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' + (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, - selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers '</div><table class="ui-datepicker-calendar"><thead>' + '<tr>'; - var thead = ''; + var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : ''); for (var dow = 0; dow < 7; dow++) { // days of the week var day = (dow + firstDay) % 7; thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + @@ -6836,12 +8209,13 @@ $.extend(Datepicker.prototype, { var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows calender += '<tr>'; - var tbody = ''; + var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' + + this._get(inst, 'calculateWeek')(printDate) + '</td>'); for (var dow = 0; dow < 7; dow++) { // create date picker days var daySettings = (beforeShowDay ? beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); var otherMonth = (printDate.getMonth() != drawMonth); - var unselectable = otherMonth || !daySettings[0] || + var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || (minDate && printDate < minDate) || (maxDate && printDate > maxDate); tbody += '<td class="' + ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends @@ -6852,18 +8226,17 @@ $.extend(Datepicker.prototype, { ' ' + this._dayOverClass : '') + // highlight selected day (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates - (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range - ' ' + this._currentClass : '') + // highlight selected day + (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different) ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title - (unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' + - inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions - (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months + (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' + + inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions + (otherMonth && !showOtherMonths ? ' ' : // display for other months (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' + (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') + - (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range - ' ui-state-active' : '') + // highlight selected day - '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month + (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day + (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months + '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date printDate.setDate(printDate.getDate() + 1); printDate = this._daylightSavingAdjust(printDate); } @@ -6874,7 +8247,7 @@ $.extend(Datepicker.prototype, { drawMonth = 0; drawYear++; } - calender += '</tbody></table>' + (isMultiMonth ? '</div>' + + calender += '</tbody></table>' + (isMultiMonth ? '</div>' + ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : ''); group += calender; } @@ -6888,8 +8261,7 @@ $.extend(Datepicker.prototype, { /* Generate the month and year header. */ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - selectedDate, secondary, monthNames, monthNamesShort) { - minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); + secondary, monthNames, monthNamesShort) { var changeMonth = this._get(inst, 'changeMonth'); var changeYear = this._get(inst, 'changeYear'); var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); @@ -6897,13 +8269,13 @@ $.extend(Datepicker.prototype, { var monthHtml = ''; // month selection if (secondary || !changeMonth) - monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> '; + monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>'; else { var inMinYear = (minDate && minDate.getFullYear() == drawYear); var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); monthHtml += '<select class="ui-datepicker-month" ' + - 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + - 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + + 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' + + 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + '>'; for (var month = 0; month < 12; month++) { if ((!inMinYear || month >= minDate.getMonth()) && @@ -6915,30 +8287,27 @@ $.extend(Datepicker.prototype, { monthHtml += '</select>'; } if (!showMonthAfterYear) - html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? ' ' : ''); + html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); // year selection if (secondary || !changeYear) html += '<span class="ui-datepicker-year">' + drawYear + '</span>'; else { // determine range of years to display var years = this._get(inst, 'yearRange').split(':'); - var year = 0; - var endYear = 0; - if (years.length != 2) { - year = drawYear - 10; - endYear = drawYear + 10; - } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { - year = drawYear + parseInt(years[0], 10); - endYear = drawYear + parseInt(years[1], 10); - } else { - year = parseInt(years[0], 10); - endYear = parseInt(years[1], 10); - } + var thisYear = new Date().getFullYear(); + var determineYear = function(value) { + var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + var year = determineYear(years[0]); + var endYear = Math.max(year, determineYear(years[1] || '')); year = (minDate ? Math.max(year, minDate.getFullYear()) : year); endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); html += '<select class="ui-datepicker-year" ' + - 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + - 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + + 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' + + 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' + '>'; for (; year <= endYear; year++) { html += '<option value="' + year + '"' + @@ -6947,8 +8316,9 @@ $.extend(Datepicker.prototype, { } html += '</select>'; } + html += this._get(inst, 'yearSuffix'); if (showMonthAfterYear) - html += (secondary || changeMonth || changeYear ? ' ' : '') + monthHtml; + html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; html += '</div>'; // Close datepicker_header return html; }, @@ -6959,12 +8329,8 @@ $.extend(Datepicker.prototype, { var month = inst.drawMonth + (period == 'M' ? offset : 0); var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period == 'D' ? offset : 0); - var date = this._daylightSavingAdjust(new Date(year, month, day)); - // ensure it is within the bounds set - var minDate = this._getMinMaxDate(inst, 'min', true); - var maxDate = this._getMinMaxDate(inst, 'max'); - date = (minDate && date < minDate ? minDate : date); - date = (maxDate && date > maxDate ? maxDate : date); + var date = this._restrictMinMax(inst, + this._daylightSavingAdjust(new Date(year, month, day))); inst.selectedDay = date.getDate(); inst.drawMonth = inst.selectedMonth = date.getMonth(); inst.drawYear = inst.selectedYear = date.getFullYear(); @@ -6972,6 +8338,15 @@ $.extend(Datepicker.prototype, { this._notifyChange(inst); }, + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + date = (minDate && date < minDate ? minDate : date); + date = (maxDate && date > maxDate ? maxDate : date); + return date; + }, + /* Notify change of month/year. */ _notifyChange: function(inst) { var onChange = this._get(inst, 'onChangeMonthYear'); @@ -6986,11 +8361,9 @@ $.extend(Datepicker.prototype, { return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); }, - /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */ - _getMinMaxDate: function(inst, minMax, checkRange) { - var date = this._determineDate(this._get(inst, minMax + 'Date'), null); - return (!checkRange || !inst.rangeStart ? date : - (!date || inst.rangeStart > date ? inst.rangeStart : date)); + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); }, /* Find the number of days in a given month. */ @@ -7006,8 +8379,8 @@ $.extend(Datepicker.prototype, { /* Determines if we should allow a "next/prev" month display change. */ _canAdjustMonth: function(inst, offset, curYear, curMonth) { var numMonths = this._getNumberOfMonths(inst); - var date = this._daylightSavingAdjust(new Date( - curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1)); + var date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); if (offset < 0) date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); return this._isInRange(inst, date); @@ -7015,13 +8388,10 @@ $.extend(Datepicker.prototype, { /* Is the given date in the accepted range? */ _isInRange: function(inst, date) { - // during range selection, use minimum of selected date and range start - var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust( - new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay))); - newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate); - var minDate = newMinDate || this._getMinMaxDate(inst, 'min'); + var minDate = this._getMinMaxDate(inst, 'min'); var maxDate = this._getMinMaxDate(inst, 'max'); - return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime())); }, /* Provide the configuration settings for formatting/parsing. */ @@ -7077,7 +8447,7 @@ $.fn.datepicker = function(options){ } var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate')) + if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) return $.datepicker['_' + options + 'Datepicker']. apply($.datepicker, [this[0]].concat(otherArgs)); if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') @@ -7094,73 +8464,87 @@ $.fn.datepicker = function(options){ $.datepicker = new Datepicker(); // singleton instance $.datepicker.initialized = false; $.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.7.2"; +$.datepicker.version = "1.8.2"; // Workaround for #4055 // Add another global to avoid noConflict issues with inline event handlers -window.DP_jQuery = $; +window['DP_jQuery_' + dpuuid] = $; })(jQuery); /* - * jQuery UI Dialog 1.7.2 + * jQuery UI Dialog 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Dialog * * Depends: - * ui.core.js - * ui.draggable.js - * ui.resizable.js + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js */ (function($) { -var setDataSwitch = { - dragStart: "start.draggable", - drag: "drag.draggable", - dragStop: "stop.draggable", - maxHeight: "maxHeight.resizable", - minHeight: "minHeight.resizable", - maxWidth: "maxWidth.resizable", - minWidth: "minWidth.resizable", - resizeStart: "start.resizable", - resize: "drag.resizable", - resizeStop: "stop.resizable" - }, - - uiDialogClasses = - 'ui-dialog ' + - 'ui-widget ' + - 'ui-widget-content ' + - 'ui-corner-all '; +var uiDialogClasses = + 'ui-dialog ' + + 'ui-widget ' + + 'ui-widget-content ' + + 'ui-corner-all '; $.widget("ui.dialog", { - - _init: function() { + options: { + autoOpen: true, + buttons: {}, + closeOnEscape: true, + closeText: 'close', + dialogClass: '', + draggable: true, + hide: null, + height: 'auto', + maxHeight: false, + maxWidth: false, + minHeight: 150, + minWidth: 150, + modal: false, + position: 'center', + resizable: true, + show: null, + stack: true, + title: '', + width: 300, + zIndex: 1000 + }, + _create: function() { this.originalTitle = this.element.attr('title'); var self = this, - options = this.options, + options = self.options, - title = options.title || this.originalTitle || ' ', - titleId = $.ui.dialog.getTitleId(this.element), + title = options.title || self.originalTitle || ' ', + titleId = $.ui.dialog.getTitleId(self.element), - uiDialog = (this.uiDialog = $('<div/>')) + uiDialog = (self.uiDialog = $('<div></div>')) .appendTo(document.body) .hide() .addClass(uiDialogClasses + options.dialogClass) .css({ - position: 'absolute', - overflow: 'hidden', zIndex: options.zIndex }) // setting tabIndex makes the div focusable // setting outline to 0 prevents a border on focus in Mozilla .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { - (options.closeOnEscape && event.keyCode - && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event)); + if (options.closeOnEscape && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE) { + + self.close(event); + event.preventDefault(); + } }) .attr({ role: 'dialog', @@ -7170,7 +8554,7 @@ $.widget("ui.dialog", { self.moveToTop(false, event); }), - uiDialogContent = this.element + uiDialogContent = self.element .show() .removeAttr('title') .addClass( @@ -7178,7 +8562,7 @@ $.widget("ui.dialog", { 'ui-widget-content') .appendTo(uiDialog), - uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>')) + uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>')) .addClass( 'ui-dialog-titlebar ' + 'ui-widget-header ' + @@ -7187,7 +8571,7 @@ $.widget("ui.dialog", { ) .prependTo(uiDialog), - uiDialogTitlebarClose = $('<a href="#"/>') + uiDialogTitlebarClose = $('<a href="#"></a>') .addClass( 'ui-dialog-titlebar-close ' + 'ui-corner-all' @@ -7207,16 +8591,13 @@ $.widget("ui.dialog", { .blur(function() { uiDialogTitlebarClose.removeClass('ui-state-focus'); }) - .mousedown(function(ev) { - ev.stopPropagation(); - }) .click(function(event) { self.close(event); return false; }) .appendTo(uiDialogTitlebar), - uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>')) + uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>')) .addClass( 'ui-icon ' + 'ui-icon-closethick' @@ -7224,68 +8605,104 @@ $.widget("ui.dialog", { .text(options.closeText) .appendTo(uiDialogTitlebarClose), - uiDialogTitle = $('<span/>') + uiDialogTitle = $('<span></span>') .addClass('ui-dialog-title') .attr('id', titleId) .html(title) .prependTo(uiDialogTitlebar); - uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); + //handling of deprecated beforeclose (vs beforeClose) option + //Ticket #4669 http://dev.jqueryui.com/ticket/4669 + //TODO: remove in 1.9pre + if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { + options.beforeClose = options.beforeclose; + } - (options.draggable && $.fn.draggable && this._makeDraggable()); - (options.resizable && $.fn.resizable && this._makeResizable()); + uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); - this._createButtons(options.buttons); - this._isOpen = false; + if (options.draggable && $.fn.draggable) { + self._makeDraggable(); + } + if (options.resizable && $.fn.resizable) { + self._makeResizable(); + } - (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe()); - (options.autoOpen && this.open()); + self._createButtons(options.buttons); + self._isOpen = false; + if ($.fn.bgiframe) { + uiDialog.bgiframe(); + } + }, + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } }, destroy: function() { - (this.overlay && this.overlay.destroy()); - this.uiDialog.hide(); - this.element + var self = this; + + if (self.overlay) { + self.overlay.destroy(); + } + self.uiDialog.hide(); + self.element .unbind('.dialog') .removeData('dialog') .removeClass('ui-dialog-content ui-widget-content') .hide().appendTo('body'); - this.uiDialog.remove(); + self.uiDialog.remove(); + + if (self.originalTitle) { + self.element.attr('title', self.originalTitle); + } - (this.originalTitle && this.element.attr('title', this.originalTitle)); + return self; + }, + + widget: function() { + return this.uiDialog; }, close: function(event) { - var self = this; - - if (false === self._trigger('beforeclose', event)) { + var self = this, + maxZ; + + if (false === self._trigger('beforeClose', event)) { return; } - (self.overlay && self.overlay.destroy()); + if (self.overlay) { + self.overlay.destroy(); + } self.uiDialog.unbind('keypress.ui-dialog'); - (self.options.hide - ? self.uiDialog.hide(self.options.hide, function() { + self._isOpen = false; + + if (self.options.hide) { + self.uiDialog.hide(self.options.hide, function() { self._trigger('close', event); - }) - : self.uiDialog.hide() && self._trigger('close', event)); + }); + } else { + self.uiDialog.hide(); + self._trigger('close', event); + } $.ui.dialog.overlay.resize(); - self._isOpen = false; - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) if (self.options.modal) { - var maxZ = 0; + maxZ = 0; $('.ui-dialog').each(function() { - if (this != self.uiDialog[0]) { + if (this !== self.uiDialog[0]) { maxZ = Math.max(maxZ, $(this).css('z-index')); } }); $.ui.dialog.maxZ = maxZ; } + + return self; }, isOpen: function() { @@ -7295,58 +8712,70 @@ $.widget("ui.dialog", { // the force parameter allows us to move modal dialogs to their correct // position on open moveToTop: function(force, event) { - - if ((this.options.modal && !force) - || (!this.options.stack && !this.options.modal)) { - return this._trigger('focus', event); + var self = this, + options = self.options, + saveScroll; + + if ((options.modal && !force) || + (!options.stack && !options.modal)) { + return self._trigger('focus', event); } - - if (this.options.zIndex > $.ui.dialog.maxZ) { - $.ui.dialog.maxZ = this.options.zIndex; + + if (options.zIndex > $.ui.dialog.maxZ) { + $.ui.dialog.maxZ = options.zIndex; + } + if (self.overlay) { + $.ui.dialog.maxZ += 1; + self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); } - (this.overlay && this.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = ++$.ui.dialog.maxZ)); //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. // http://ui.jquery.com/bugs/ticket/3193 - var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') }; - this.uiDialog.css('z-index', ++$.ui.dialog.maxZ); - this.element.attr(saveScroll); - this._trigger('focus', event); + saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') }; + $.ui.dialog.maxZ += 1; + self.uiDialog.css('z-index', $.ui.dialog.maxZ); + self.element.attr(saveScroll); + self._trigger('focus', event); + + return self; }, open: function() { if (this._isOpen) { return; } - var options = this.options, - uiDialog = this.uiDialog; + var self = this, + options = self.options, + uiDialog = self.uiDialog; - this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null; - (uiDialog.next().length && uiDialog.appendTo('body')); - this._size(); - this._position(options.position); + self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; + if (uiDialog.next().length) { + uiDialog.appendTo('body'); + } + self._size(); + self._position(options.position); uiDialog.show(options.show); - this.moveToTop(true); + self.moveToTop(true); // prevent tabbing out of modal dialogs - (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) { - if (event.keyCode != $.ui.keyCode.TAB) { - return; - } - - var tabbables = $(':tabbable', this), - first = tabbables.filter(':first')[0], - last = tabbables.filter(':last')[0]; - - if (event.target == last && !event.shiftKey) { - setTimeout(function() { - first.focus(); - }, 1); - } else if (event.target == first && event.shiftKey) { - setTimeout(function() { - last.focus(); - }, 1); - } - })); + if (options.modal) { + uiDialog.bind('keypress.ui-dialog', function(event) { + if (event.keyCode !== $.ui.keyCode.TAB) { + return; + } + + var tabbables = $(':tabbable', this), + first = tabbables.filter(':first'), + last = tabbables.filter(':last'); + + if (event.target === last[0] && !event.shiftKey) { + first.focus(1); + return false; + } else if (event.target === first[0] && event.shiftKey) { + last.focus(1); + return false; + } + }); + } // set focus to the first tabbable element in the content area or the first button // if there are no tabbable elements, set focus on the dialog itself @@ -7357,8 +8786,10 @@ $.widget("ui.dialog", { .filter(':first') .focus(); - this._trigger('open'); - this._isOpen = true; + self._trigger('open'); + self._isOpen = true; + + return self; }, _createButtons: function(buttons) { @@ -7372,59 +8803,57 @@ $.widget("ui.dialog", { ); // if we already have a button pane, remove it - this.uiDialog.find('.ui-dialog-buttonpane').remove(); + self.uiDialog.find('.ui-dialog-buttonpane').remove(); - (typeof buttons == 'object' && buttons !== null && - $.each(buttons, function() { return !(hasButtons = true); })); + if (typeof buttons === 'object' && buttons !== null) { + $.each(buttons, function() { + return !(hasButtons = true); + }); + } if (hasButtons) { $.each(buttons, function(name, fn) { - $('<button type="button"></button>') - .addClass( - 'ui-state-default ' + - 'ui-corner-all' - ) + var button = $('<button type="button"></button>') .text(name) .click(function() { fn.apply(self.element[0], arguments); }) - .hover( - function() { - $(this).addClass('ui-state-hover'); - }, - function() { - $(this).removeClass('ui-state-hover'); - } - ) - .focus(function() { - $(this).addClass('ui-state-focus'); - }) - .blur(function() { - $(this).removeClass('ui-state-focus'); - }) .appendTo(uiDialogButtonPane); + if ($.fn.button) { + button.button(); + } }); - uiDialogButtonPane.appendTo(this.uiDialog); + uiDialogButtonPane.appendTo(self.uiDialog); } }, _makeDraggable: function() { var self = this, - options = this.options, + options = self.options, + doc = $(document), heightBeforeDrag; - this.uiDialog.draggable({ - cancel: '.ui-dialog-content', + function filteredUi(ui) { + return { + position: ui.position, + offset: ui.offset + }; + } + + self.uiDialog.draggable({ + cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', handle: '.ui-dialog-titlebar', containment: 'document', - start: function() { - heightBeforeDrag = options.height; + start: function(event, ui) { + heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); $(this).height($(this).height()).addClass("ui-dialog-dragging"); - (options.dragStart && options.dragStart.apply(self.element[0], arguments)); + self._trigger('dragStart', event, filteredUi(ui)); }, - drag: function() { - (options.drag && options.drag.apply(self.element[0], arguments)); + drag: function(event, ui) { + self._trigger('drag', event, filteredUi(ui)); }, - stop: function() { + stop: function(event, ui) { + options.position = [ui.position.left - doc.scrollLeft(), + ui.position.top - doc.scrollTop()]; $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); - (options.dragStop && options.dragStop.apply(self.element[0], arguments)); + self._trigger('dragStop', event, filteredUi(ui)); $.ui.dialog.overlay.resize(); } }); @@ -7433,202 +8862,282 @@ $.widget("ui.dialog", { _makeResizable: function(handles) { handles = (handles === undefined ? this.options.resizable : handles); var self = this, - options = this.options, - resizeHandles = typeof handles == 'string' - ? handles - : 'n,e,s,w,se,sw,ne,nw'; + options = self.options, + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = self.uiDialog.css('position'), + resizeHandles = (typeof handles === 'string' ? + handles : + 'n,e,s,w,se,sw,ne,nw' + ); + + function filteredUi(ui) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } - this.uiDialog.resizable({ + self.uiDialog.resizable({ cancel: '.ui-dialog-content', - alsoResize: this.element, + containment: 'document', + alsoResize: self.element, maxWidth: options.maxWidth, maxHeight: options.maxHeight, minWidth: options.minWidth, - minHeight: options.minHeight, - start: function() { + minHeight: self._minHeight(), + handles: resizeHandles, + start: function(event, ui) { $(this).addClass("ui-dialog-resizing"); - (options.resizeStart && options.resizeStart.apply(self.element[0], arguments)); + self._trigger('resizeStart', event, filteredUi(ui)); }, - resize: function() { - (options.resize && options.resize.apply(self.element[0], arguments)); + resize: function(event, ui) { + self._trigger('resize', event, filteredUi(ui)); }, - handles: resizeHandles, - stop: function() { + stop: function(event, ui) { $(this).removeClass("ui-dialog-resizing"); options.height = $(this).height(); options.width = $(this).width(); - (options.resizeStop && options.resizeStop.apply(self.element[0], arguments)); + self._trigger('resizeStop', event, filteredUi(ui)); $.ui.dialog.overlay.resize(); } }) + .css('position', position) .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); }, - _position: function(pos) { - var wnd = $(window), doc = $(document), - pTop = doc.scrollTop(), pLeft = doc.scrollLeft(), - minTop = pTop; + _minHeight: function() { + var options = this.options; - if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) { - pos = [ - pos == 'right' || pos == 'left' ? pos : 'center', - pos == 'top' || pos == 'bottom' ? pos : 'middle' - ]; - } - if (pos.constructor != Array) { - pos = ['center', 'middle']; - } - if (pos[0].constructor == Number) { - pLeft += pos[0]; + if (options.height === 'auto') { + return options.minHeight; } else { - switch (pos[0]) { - case 'left': - pLeft += 0; - break; - case 'right': - pLeft += wnd.width() - this.uiDialog.outerWidth(); - break; - default: - case 'center': - pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2; - } + return Math.min(options.minHeight, options.height); } - if (pos[1].constructor == Number) { - pTop += pos[1]; - } else { - switch (pos[1]) { - case 'top': - pTop += 0; - break; - case 'bottom': - pTop += wnd.height() - this.uiDialog.outerHeight(); - break; - default: - case 'middle': - pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2; + }, + + _position: function(position) { + var myAt = [], + offset = [0, 0], + isVisible; + + position = position || $.ui.dialog.prototype.options.position; + + // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( +// if (typeof position == 'string' || $.isArray(position)) { +// myAt = $.isArray(position) ? position : position.split(' '); + + if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { + myAt = position.split ? position.split(' ') : [position[0], position[1]]; + if (myAt.length === 1) { + myAt[1] = myAt[0]; + } + + $.each(['left', 'top'], function(i, offsetPosition) { + if (+myAt[i] === myAt[i]) { + offset[i] = myAt[i]; + myAt[i] = offsetPosition; + } + }); + } else if (typeof position === 'object') { + if ('left' in position) { + myAt[0] = 'left'; + offset[0] = position.left; + } else if ('right' in position) { + myAt[0] = 'right'; + offset[0] = -position.right; + } + + if ('top' in position) { + myAt[1] = 'top'; + offset[1] = position.top; + } else if ('bottom' in position) { + myAt[1] = 'bottom'; + offset[1] = -position.bottom; } } - // prevent the dialog from being too high (make sure the titlebar - // is accessible) - pTop = Math.max(pTop, minTop); - this.uiDialog.css({top: pTop, left: pLeft}); + // need to show the dialog to get the actual offset in the position plugin + isVisible = this.uiDialog.is(':visible'); + if (!isVisible) { + this.uiDialog.show(); + } + this.uiDialog + // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 + .css({ top: 0, left: 0 }) + .position({ + my: myAt.join(' '), + at: myAt.join(' '), + offset: offset.join(' '), + of: window, + collision: 'fit', + // ensure that the titlebar is never outside the document + using: function(pos) { + var topOffset = $(this).css(pos).offset().top; + if (topOffset < 0) { + $(this).css('top', pos.top - topOffset); + } + } + }); + if (!isVisible) { + this.uiDialog.hide(); + } }, - _setData: function(key, value){ - (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value)); + _setOption: function(key, value){ + var self = this, + uiDialog = self.uiDialog, + isResizable = uiDialog.is(':data(resizable)'), + resize = false; + switch (key) { + //handling of deprecated beforeclose (vs beforeClose) option + //Ticket #4669 http://dev.jqueryui.com/ticket/4669 + //TODO: remove in 1.9pre + case "beforeclose": + key = "beforeClose"; + break; case "buttons": - this._createButtons(value); + self._createButtons(value); break; case "closeText": - this.uiDialogTitlebarCloseText.text(value); + // convert whatever was passed in to a string, for text() to not throw up + self.uiDialogTitlebarCloseText.text("" + value); break; case "dialogClass": - this.uiDialog - .removeClass(this.options.dialogClass) + uiDialog + .removeClass(self.options.dialogClass) .addClass(uiDialogClasses + value); break; + case "disabled": + if (value) { + uiDialog.addClass('ui-dialog-disabled'); + } else { + uiDialog.removeClass('ui-dialog-disabled'); + } + break; case "draggable": - (value - ? this._makeDraggable() - : this.uiDialog.draggable('destroy')); + if (value) { + self._makeDraggable(); + } else { + uiDialog.draggable('destroy'); + } break; case "height": - this.uiDialog.height(value); + resize = true; + break; + case "maxHeight": + if (isResizable) { + uiDialog.resizable('option', 'maxHeight', value); + } + resize = true; + break; + case "maxWidth": + if (isResizable) { + uiDialog.resizable('option', 'maxWidth', value); + } + resize = true; + break; + case "minHeight": + if (isResizable) { + uiDialog.resizable('option', 'minHeight', value); + } + resize = true; + break; + case "minWidth": + if (isResizable) { + uiDialog.resizable('option', 'minWidth', value); + } + resize = true; break; case "position": - this._position(value); + self._position(value); break; case "resizable": - var uiDialog = this.uiDialog, - isResizable = this.uiDialog.is(':data(resizable)'); - // currently resizable, becoming non-resizable - (isResizable && !value && uiDialog.resizable('destroy')); + if (isResizable && !value) { + uiDialog.resizable('destroy'); + } // currently resizable, changing handles - (isResizable && typeof value == 'string' && - uiDialog.resizable('option', 'handles', value)); + if (isResizable && typeof value === 'string') { + uiDialog.resizable('option', 'handles', value); + } // currently non-resizable, becoming resizable - (isResizable || this._makeResizable(value)); + if (!isResizable && value !== false) { + self._makeResizable(value); + } break; case "title": - $(".ui-dialog-title", this.uiDialogTitlebar).html(value || ' '); + // convert whatever was passed in o a string, for html() to not throw up + $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); break; case "width": - this.uiDialog.width(value); + resize = true; break; } - $.widget.prototype._setData.apply(this, arguments); + $.Widget.prototype._setOption.apply(self, arguments); + if (resize) { + self._size(); + } }, _size: function() { /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content * divs will both have width and height set, so we need to reset them */ - var options = this.options; + var options = this.options, + nonContentHeight; // reset content sizing + // hide for non content measurement because height: 0 doesn't work in IE quirks mode (see #4350) this.element.css({ - height: 0, + width: 'auto', minHeight: 0, - width: 'auto' + height: 0 }); // reset wrapper sizing // determine the height of all the non-content elements - var nonContentHeight = this.uiDialog.css({ + nonContentHeight = this.uiDialog.css({ height: 'auto', width: options.width }) .height(); this.element - .css({ - minHeight: Math.max(options.minHeight - nonContentHeight, 0), - height: options.height == 'auto' - ? 'auto' - : Math.max(options.height - nonContentHeight, 0) - }); + .css(options.height === 'auto' ? { + minHeight: Math.max(options.minHeight - nonContentHeight, 0), + height: 'auto' + } : { + minHeight: 0, + height: Math.max(options.height - nonContentHeight, 0) + }) + .show(); + + if (this.uiDialog.is(':data(resizable)')) { + this.uiDialog.resizable('option', 'minHeight', this._minHeight()); + } } }); $.extend($.ui.dialog, { - version: "1.7.2", - defaults: { - autoOpen: true, - bgiframe: false, - buttons: {}, - closeOnEscape: true, - closeText: 'close', - dialogClass: '', - draggable: true, - hide: null, - height: 'auto', - maxHeight: false, - maxWidth: false, - minHeight: 150, - minWidth: 150, - modal: false, - position: 'center', - resizable: true, - show: null, - stack: true, - title: '', - width: 300, - zIndex: 1000 - }, - - getter: 'isOpen', + version: "1.8.2", uuid: 0, maxZ: 0, getTitleId: function($el) { - return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid); + var id = $el.attr('id'); + if (!id) { + this.uuid += 1; + id = this.uuid; + } + return 'ui-dialog-title-' + id; }, overlay: function(dialog) { @@ -7638,6 +9147,8 @@ $.extend($.ui.dialog, { $.extend($.ui.dialog.overlay, { instances: [], + // reuse old instances due to IE memory leak with alpha transparency (see #5185) + oldInstances: [], maxZ: 0, events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), function(event) { return event + '.dialog-overlay'; }).join(' '), @@ -7650,43 +9161,50 @@ $.extend($.ui.dialog.overlay, { // handle $(el).dialog().dialog('close') (see #4065) if ($.ui.dialog.overlay.instances.length) { $(document).bind($.ui.dialog.overlay.events, function(event) { - var dialogZ = $(event.target).parents('.ui-dialog').css('zIndex') || 0; - return (dialogZ > $.ui.dialog.overlay.maxZ); + // stop events if the z-index of the target is < the z-index of the overlay + return ($(event.target).zIndex() >= $.ui.dialog.overlay.maxZ); }); } }, 1); // allow closing by pressing the escape key $(document).bind('keydown.dialog-overlay', function(event) { - (dialog.options.closeOnEscape && event.keyCode - && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event)); + if (dialog.options.closeOnEscape && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE) { + + dialog.close(event); + event.preventDefault(); + } }); // handle window resize $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); } - var $el = $('<div></div>').appendTo(document.body) - .addClass('ui-widget-overlay').css({ + var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay')) + .appendTo(document.body) + .css({ width: this.width(), height: this.height() }); - (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe()); + if ($.fn.bgiframe) { + $el.bgiframe(); + } this.instances.push($el); return $el; }, destroy: function($el) { - this.instances.splice($.inArray(this.instances, $el), 1); + this.oldInstances.push(this.instances.splice($.inArray($el, this.instances), 1)[0]); if (this.instances.length === 0) { $([document, window]).unbind('.dialog-overlay'); } $el.remove(); - + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) var maxZ = 0; $.each(this.instances, function() { @@ -7696,13 +9214,15 @@ $.extend($.ui.dialog.overlay, { }, height: function() { + var scrollHeight, + offsetHeight; // handle IE 6 if ($.browser.msie && $.browser.version < 7) { - var scrollHeight = Math.max( + scrollHeight = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight ); - var offsetHeight = Math.max( + offsetHeight = Math.max( document.documentElement.offsetHeight, document.body.offsetHeight ); @@ -7719,13 +9239,15 @@ $.extend($.ui.dialog.overlay, { }, width: function() { + var scrollWidth, + offsetWidth; // handle IE 6 if ($.browser.msie && $.browser.version < 7) { - var scrollWidth = Math.max( + scrollWidth = Math.max( document.documentElement.scrollWidth, document.body.scrollWidth ); - var offsetWidth = Math.max( + offsetWidth = Math.max( document.documentElement.offsetWidth, document.body.offsetWidth ); @@ -7771,30 +9293,262 @@ $.extend($.ui.dialog.overlay.prototype, { } }); -})(jQuery); +}(jQuery)); /* - * jQuery UI Progressbar 1.7.2 + * jQuery UI Position 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Position + */ +(function( $ ) { + +$.ui = $.ui || {}; + +var horizontalPositions = /left|center|right/, + horizontalDefault = "center", + verticalPositions = /top|center|bottom/, + verticalDefault = "center", + _position = $.fn.position, + _offset = $.fn.offset; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var target = $( options.of ), + collision = ( options.collision || "flip" ).split( " " ), + offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], + targetWidth, + targetHeight, + basePosition; + + if ( options.of.nodeType === 9 ) { + targetWidth = target.width(); + targetHeight = target.height(); + basePosition = { top: 0, left: 0 }; + } else if ( options.of.scrollTo && options.of.document ) { + targetWidth = target.width(); + targetHeight = target.height(); + basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; + } else if ( options.of.preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + targetWidth = targetHeight = 0; + basePosition = { top: options.of.pageY, left: options.of.pageX }; + } else { + targetWidth = target.outerWidth(); + targetHeight = target.outerHeight(); + basePosition = target.offset(); + } + + // force my and at to have valid horizontal and veritcal positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[this] || "" ).split( " " ); + if ( pos.length === 1) { + pos = horizontalPositions.test( pos[0] ) ? + pos.concat( [verticalDefault] ) : + verticalPositions.test( pos[0] ) ? + [ horizontalDefault ].concat( pos ) : + [ horizontalDefault, verticalDefault ]; + } + pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : horizontalDefault; + pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : verticalDefault; + options[ this ] = pos; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + // normalize offset option + offset[ 0 ] = parseInt( offset[0], 10 ) || 0; + if ( offset.length === 1 ) { + offset[ 1 ] = offset[ 0 ]; + } + offset[ 1 ] = parseInt( offset[1], 10 ) || 0; + + if ( options.at[0] === "right" ) { + basePosition.left += targetWidth; + } else if (options.at[0] === horizontalDefault ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[1] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[1] === verticalDefault ) { + basePosition.top += targetHeight / 2; + } + + basePosition.left += offset[ 0 ]; + basePosition.top += offset[ 1 ]; + + return this.each(function() { + var elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + position = $.extend( {}, basePosition ); + + if ( options.my[0] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[0] === horizontalDefault ) { + position.left -= elemWidth / 2; + } + + if ( options.my[1] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[1] === verticalDefault ) { + position.top -= elemHeight / 2; + } + + // prevent fractions (see #5280) + position.left = parseInt( position.left ); + position.top = parseInt( position.top ); + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[i] ] ) { + $.ui.position[ collision[i] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + offset: offset, + my: options.my, + at: options.at + }); + } + }); + + if ( $.fn.bgiframe ) { + elem.bgiframe(); + } + elem.offset( $.extend( position, { using: options.using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var win = $( window ), + over = position.left + data.elemWidth - win.width() - win.scrollLeft(); + position.left = over > 0 ? position.left - over : Math.max( 0, position.left ); + }, + top: function( position, data ) { + var win = $( window ), + over = position.top + data.elemHeight - win.height() - win.scrollTop(); + position.top = over > 0 ? position.top - over : Math.max( 0, position.top ); + } + }, + + flip: { + left: function( position, data ) { + if ( data.at[0] === "center" ) { + return; + } + var win = $( window ), + over = position.left + data.elemWidth - win.width() - win.scrollLeft(), + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + offset = -2 * data.offset[ 0 ]; + position.left += position.left < 0 ? + myOffset + data.targetWidth + offset : + over > 0 ? + myOffset - data.targetWidth + offset : + 0; + }, + top: function( position, data ) { + if ( data.at[1] === "center" ) { + return; + } + var win = $( window ), + over = position.top + data.elemHeight - win.height() - win.scrollTop(), + myOffset = data.my[ 1 ] === "top" ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + -data.targetHeight, + offset = -2 * data.offset[ 1 ]; + position.top += position.top < 0 ? + myOffset + data.targetHeight + offset : + over > 0 ? + myOffset + atOffset + offset : + 0; + } + } +}; + +// offset setter from jQuery 1.4 +if ( !$.offset.setOffset ) { + $.offset.setOffset = function( elem, options ) { + // set position first, in-case top/left are set even on static elem + if ( /static/.test( $.curCSS( elem, "position" ) ) ) { + elem.style.position = "relative"; + } + var curElem = $( elem ), + curOffset = curElem.offset(), + curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0, + curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0, + props = { + top: (options.top - curOffset.top) + curTop, + left: (options.left - curOffset.left) + curLeft + }; + + if ( 'using' in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + }; + + $.fn.offset = function( options ) { + var elem = this[ 0 ]; + if ( !elem || !elem.ownerDocument ) { return null; } + if ( options ) { + return this.each(function() { + $.offset.setOffset( this, options ); + }); + } + return _offset.call( this ); + }; +} + +}( jQuery )); +/* + * jQuery UI Progressbar 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Progressbar * * Depends: - * ui.core.js + * jquery.ui.core.js + * jquery.ui.widget.js */ -(function($) { - -$.widget("ui.progressbar", { - - _init: function() { +(function( $ ) { +$.widget( "ui.progressbar", { + options: { + value: 0 + }, + _create: function() { this.element - .addClass("ui-progressbar" - + " ui-widget" - + " ui-widget-content" - + " ui-corner-all") + .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) .attr({ role: "progressbar", "aria-valuemin": this._valueMin(), @@ -7802,294 +9556,345 @@ $.widget("ui.progressbar", { "aria-valuenow": this._value() }); - this.valueDiv = $('<div class="ui-progressbar-value ui-widget-header ui-corner-left"></div>').appendTo(this.element); + this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) + .appendTo( this.element ); this._refreshValue(); - }, destroy: function() { - this.element - .removeClass("ui-progressbar" - + " ui-widget" - + " ui-widget-content" - + " ui-corner-all") - .removeAttr("role") - .removeAttr("aria-valuemin") - .removeAttr("aria-valuemax") - .removeAttr("aria-valuenow") - .removeData("progressbar") - .unbind(".progressbar"); + .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); this.valueDiv.remove(); - $.widget.prototype.destroy.apply(this, arguments); - + $.Widget.prototype.destroy.apply( this, arguments ); }, - value: function(newValue) { - if (newValue === undefined) { + value: function( newValue ) { + if ( newValue === undefined ) { return this._value(); } - this._setData('value', newValue); + this._setOption( "value", newValue ); return this; }, - _setData: function(key, value) { - - switch (key) { - case 'value': + _setOption: function( key, value ) { + switch ( key ) { + case "value": this.options.value = value; this._refreshValue(); - this._trigger('change', null, {}); + this._trigger( "change" ); break; } - $.widget.prototype._setData.apply(this, arguments); - + $.Widget.prototype._setOption.apply( this, arguments ); }, _value: function() { - var val = this.options.value; - if (val < this._valueMin()) val = this._valueMin(); - if (val > this._valueMax()) val = this._valueMax(); + // normalize invalid value + if ( typeof val !== "number" ) { + val = 0; + } + if ( val < this._valueMin() ) { + val = this._valueMin(); + } + if ( val > this._valueMax() ) { + val = this._valueMax(); + } return val; - }, _valueMin: function() { - var valueMin = 0; - return valueMin; + return 0; }, _valueMax: function() { - var valueMax = 100; - return valueMax; + return 100; }, _refreshValue: function() { var value = this.value(); - this.valueDiv[value == this._valueMax() ? 'addClass' : 'removeClass']("ui-corner-right"); - this.valueDiv.width(value + '%'); - this.element.attr("aria-valuenow", value); + this.valueDiv + [ value === this._valueMax() ? "addClass" : "removeClass"]( "ui-corner-right" ) + .width( value + "%" ); + this.element.attr( "aria-valuenow", value ); } - }); -$.extend($.ui.progressbar, { - version: "1.7.2", - defaults: { - value: 0 - } +$.extend( $.ui.progressbar, { + version: "1.8.2" }); -})(jQuery); +})( jQuery ); /* - * jQuery UI Slider 1.7.2 + * jQuery UI Slider 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Slider * * Depends: - * ui.core.js + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js */ -(function($) { +(function( $ ) { -$.widget("ui.slider", $.extend({}, $.ui.mouse, { +// number of pages in a slider +// (how many times can you page up/down to go through the whole range) +var numPages = 5; - _init: function() { +$.widget( "ui.slider", $.ui.mouse, { + + widgetEventPrefix: "slide", + + options: { + animate: false, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null + }, + + _create: function() { + var self = this, + o = this.options; - var self = this, o = this.options; this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; this._handleIndex = null; this._detectOrientation(); this._mouseInit(); this.element - .addClass("ui-slider" - + " ui-slider-" + this.orientation - + " ui-widget" - + " ui-widget-content" - + " ui-corner-all"); + .addClass( "ui-slider" + + " ui-slider-" + this.orientation + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ); + + if ( o.disabled ) { + this.element.addClass( "ui-slider-disabled ui-disabled" ); + } this.range = $([]); - if (o.range) { - - if (o.range === true) { - this.range = $('<div></div>'); - if (!o.values) o.values = [this._valueMin(), this._valueMin()]; - if (o.values.length && o.values.length != 2) { - o.values = [o.values[0], o.values[0]]; + if ( o.range ) { + if ( o.range === true ) { + this.range = $( "<div></div>" ); + if ( !o.values ) { + o.values = [ this._valueMin(), this._valueMin() ]; + } + if ( o.values.length && o.values.length !== 2 ) { + o.values = [ o.values[0], o.values[0] ]; } } else { - this.range = $('<div></div>'); + this.range = $( "<div></div>" ); } this.range - .appendTo(this.element) - .addClass("ui-slider-range"); + .appendTo( this.element ) + .addClass( "ui-slider-range" ); - if (o.range == "min" || o.range == "max") { - this.range.addClass("ui-slider-range-" + o.range); + if ( o.range === "min" || o.range === "max" ) { + this.range.addClass( "ui-slider-range-" + o.range ); } // note: this isn't the most fittingly semantic framework class for this element, // but worked best visually with a variety of themes - this.range.addClass("ui-widget-header"); - + this.range.addClass( "ui-widget-header" ); } - if ($(".ui-slider-handle", this.element).length == 0) - $('<a href="#"></a>') - .appendTo(this.element) - .addClass("ui-slider-handle"); + if ( $( ".ui-slider-handle", this.element ).length === 0 ) { + $( "<a href='#'></a>" ) + .appendTo( this.element ) + .addClass( "ui-slider-handle" ); + } - if (o.values && o.values.length) { - while ($(".ui-slider-handle", this.element).length < o.values.length) - $('<a href="#"></a>') - .appendTo(this.element) - .addClass("ui-slider-handle"); + if ( o.values && o.values.length ) { + while ( $(".ui-slider-handle", this.element).length < o.values.length ) { + $( "<a href='#'></a>" ) + .appendTo( this.element ) + .addClass( "ui-slider-handle" ); + } } - this.handles = $(".ui-slider-handle", this.element) - .addClass("ui-state-default" - + " ui-corner-all"); + this.handles = $( ".ui-slider-handle", this.element ) + .addClass( "ui-state-default" + + " ui-corner-all" ); - this.handle = this.handles.eq(0); + this.handle = this.handles.eq( 0 ); - this.handles.add(this.range).filter("a") - .click(function(event) { + this.handles.add( this.range ).filter( "a" ) + .click(function( event ) { event.preventDefault(); }) .hover(function() { - if (!o.disabled) { - $(this).addClass('ui-state-hover'); + if ( !o.disabled ) { + $( this ).addClass( "ui-state-hover" ); } }, function() { - $(this).removeClass('ui-state-hover'); + $( this ).removeClass( "ui-state-hover" ); }) .focus(function() { - if (!o.disabled) { - $(".ui-slider .ui-state-focus").removeClass('ui-state-focus'); $(this).addClass('ui-state-focus'); + if ( !o.disabled ) { + $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); + $( this ).addClass( "ui-state-focus" ); } else { - $(this).blur(); + $( this ).blur(); } }) .blur(function() { - $(this).removeClass('ui-state-focus'); + $( this ).removeClass( "ui-state-focus" ); }); - this.handles.each(function(i) { - $(this).data("index.ui-slider-handle", i); + this.handles.each(function( i ) { + $( this ).data( "index.ui-slider-handle", i ); }); - this.handles.keydown(function(event) { - - var ret = true; - - var index = $(this).data("index.ui-slider-handle"); - - if (self.options.disabled) - return; - - switch (event.keyCode) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - ret = false; - if (!self._keySliding) { - self._keySliding = true; - $(this).addClass("ui-state-active"); - self._start(event, index); - } - break; - } - - var curVal, newVal, step = self._step(); - if (self.options.values && self.options.values.length) { - curVal = newVal = self.values(index); - } else { - curVal = newVal = self.value(); - } - - switch (event.keyCode) { - case $.ui.keyCode.HOME: - newVal = self._valueMin(); - break; - case $.ui.keyCode.END: - newVal = self._valueMax(); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if(curVal == self._valueMax()) return; - newVal = curVal + step; - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if(curVal == self._valueMin()) return; - newVal = curVal - step; - break; - } - - self._slide(event, index, newVal); - - return ret; - - }).keyup(function(event) { - - var index = $(this).data("index.ui-slider-handle"); - - if (self._keySliding) { - self._stop(event, index); - self._change(event, index); - self._keySliding = false; - $(this).removeClass("ui-state-active"); - } - - }); + this.handles + .keydown(function( event ) { + var ret = true, + index = $( this ).data( "index.ui-slider-handle" ), + allowed, + curVal, + newVal, + step; + + if ( self.options.disabled ) { + return; + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + ret = false; + if ( !self._keySliding ) { + self._keySliding = true; + $( this ).addClass( "ui-state-active" ); + allowed = self._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = self.options.step; + if ( self.options.values && self.options.values.length ) { + curVal = newVal = self.values( index ); + } else { + curVal = newVal = self.value(); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = self._valueMin(); + break; + case $.ui.keyCode.END: + newVal = self._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === self._valueMax() ) { + return; + } + newVal = self._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === self._valueMin() ) { + return; + } + newVal = self._trimAlignValue( curVal - step ); + break; + } + + self._slide( event, index, newVal ); + + return ret; + + }) + .keyup(function( event ) { + var index = $( this ).data( "index.ui-slider-handle" ); + + if ( self._keySliding ) { + self._keySliding = false; + self._stop( event, index ); + self._change( event, index ); + $( this ).removeClass( "ui-state-active" ); + } + + }); this._refreshValue(); + this._animateOff = false; }, destroy: function() { - this.handles.remove(); this.range.remove(); this.element - .removeClass("ui-slider" - + " ui-slider-horizontal" - + " ui-slider-vertical" - + " ui-slider-disabled" - + " ui-widget" - + " ui-widget-content" - + " ui-corner-all") - .removeData("slider") - .unbind(".slider"); + .removeClass( "ui-slider" + + " ui-slider-horizontal" + + " ui-slider-vertical" + + " ui-slider-disabled" + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ) + .removeData( "slider" ) + .unbind( ".slider" ); this._mouseDestroy(); + return this; }, - _mouseCapture: function(event) { + _mouseCapture: function( event ) { + var o = this.options, + position, + normValue, + distance, + closestHandle, + self, + index, + allowed, + offset, + mouseOverHandle; - var o = this.options; - - if (o.disabled) + if ( o.disabled ) { return false; + } this.elementSize = { width: this.element.outerWidth(), @@ -8097,16 +9902,15 @@ $.widget("ui.slider", $.extend({}, $.ui.mouse, { }; this.elementOffset = this.element.offset(); - var position = { x: event.pageX, y: event.pageY }; - var normValue = this._normValueFromMouse(position); - - var distance = this._valueMax() - this._valueMin() + 1, closestHandle; - var self = this, index; - this.handles.each(function(i) { - var thisDistance = Math.abs(normValue - self.values(i)); - if (distance > thisDistance) { + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + self = this; + this.handles.each(function( i ) { + var thisDistance = Math.abs( normValue - self.values(i) ); + if ( distance > thisDistance ) { distance = thisDistance; - closestHandle = $(this); + closestHandle = $( this ); index = i; } }); @@ -8114,362 +9918,456 @@ $.widget("ui.slider", $.extend({}, $.ui.mouse, { // workaround for bug #3736 (if both handles of a range are at 0, // the first is always used as the one with least distance, // and moving it is obviously prevented by preventing negative ranges) - if(o.range == true && this.values(1) == o.min) { - closestHandle = $(this.handles[++index]); + if( o.range === true && this.values(1) === o.min ) { + index += 1; + closestHandle = $( this.handles[index] ); } - this._start(event, index); + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; + } + this._mouseSliding = true; self._handleIndex = index; closestHandle - .addClass("ui-state-active") + .addClass( "ui-state-active" ) .focus(); - - var offset = closestHandle.offset(); - var mouseOverHandle = !$(event.target).parents().andSelf().is('.ui-slider-handle'); + + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - (closestHandle.width() / 2), - top: event.pageY - offset.top - - (closestHandle.height() / 2) - - (parseInt(closestHandle.css('borderTopWidth'),10) || 0) - - (parseInt(closestHandle.css('borderBottomWidth'),10) || 0) - + (parseInt(closestHandle.css('marginTop'),10) || 0) + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - + ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + + ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) }; - normValue = this._normValueFromMouse(position); - this._slide(event, index, normValue); + normValue = this._normValueFromMouse( position ); + this._slide( event, index, normValue ); + this._animateOff = true; return true; - }, - _mouseStart: function(event) { + _mouseStart: function( event ) { return true; }, - _mouseDrag: function(event) { - - var position = { x: event.pageX, y: event.pageY }; - var normValue = this._normValueFromMouse(position); - - this._slide(event, this._handleIndex, normValue); + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); + + this._slide( event, this._handleIndex, normValue ); return false; - }, - _mouseStop: function(event) { + _mouseStop: function( event ) { + this.handles.removeClass( "ui-state-active" ); + this._mouseSliding = false; + + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); - this.handles.removeClass("ui-state-active"); - this._stop(event, this._handleIndex); - this._change(event, this._handleIndex); this._handleIndex = null; this._clickOffset = null; + this._animateOff = false; return false; - }, - + _detectOrientation: function() { - this.orientation = this.options.orientation == 'vertical' ? 'vertical' : 'horizontal'; + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; }, - _normValueFromMouse: function(position) { + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; - var pixelTotal, pixelMouse; - if ('horizontal' == this.orientation) { + if ( this.orientation === "horizontal" ) { pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0); + pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); } else { pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0); + pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); } - var percentMouse = (pixelMouse / pixelTotal); - if (percentMouse > 1) percentMouse = 1; - if (percentMouse < 0) percentMouse = 0; - if ('vertical' == this.orientation) + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; + } + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { percentMouse = 1 - percentMouse; + } - var valueTotal = this._valueMax() - this._valueMin(), - valueMouse = percentMouse * valueTotal, - valueMouseModStep = valueMouse % this.options.step, - normValue = this._valueMin() + valueMouse - valueMouseModStep; - - if (valueMouseModStep > (this.options.step / 2)) - normValue += this.options.step; - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat(normValue.toFixed(5)); + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; + return this._trimAlignValue( valueMouse ); }, - _start: function(event, index) { + _start: function( event, index ) { var uiHash = { - handle: this.handles[index], + handle: this.handles[ index ], value: this.value() }; - if (this.options.values && this.options.values.length) { - uiHash.value = this.values(index); + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); uiHash.values = this.values(); } - this._trigger("start", event, uiHash); + return this._trigger( "start", event, uiHash ); }, - _slide: function(event, index, newVal) { + _slide: function( event, index, newVal ) { + var otherVal, + newValues, + allowed; - var handle = this.handles[index]; + if ( this.options.values && this.options.values.length ) { + otherVal = this.values( index ? 0 : 1 ); - if (this.options.values && this.options.values.length) { - - var otherVal = this.values(index ? 0 : 1); - - if ((this.options.values.length == 2 && this.options.range === true) && - ((index == 0 && newVal > otherVal) || (index == 1 && newVal < otherVal))){ - newVal = otherVal; + if ( ( this.options.values.length === 2 && this.options.range === true ) && + ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + ) { + newVal = otherVal; } - if (newVal != this.values(index)) { - var newValues = this.values(); - newValues[index] = newVal; + if ( newVal !== this.values( index ) ) { + newValues = this.values(); + newValues[ index ] = newVal; // A slide can be canceled by returning false from the slide callback - var allowed = this._trigger("slide", event, { - handle: this.handles[index], + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], value: newVal, values: newValues - }); - var otherVal = this.values(index ? 0 : 1); - if (allowed !== false) { - this.values(index, newVal, ( event.type == 'mousedown' && this.options.animate ), true); + } ); + otherVal = this.values( index ? 0 : 1 ); + if ( allowed !== false ) { + this.values( index, newVal, true ); } } - } else { - - if (newVal != this.value()) { + if ( newVal !== this.value() ) { // A slide can be canceled by returning false from the slide callback - var allowed = this._trigger("slide", event, { - handle: this.handles[index], + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], value: newVal - }); - if (allowed !== false) { - this._setData('value', newVal, ( event.type == 'mousedown' && this.options.animate )); + } ); + if ( allowed !== false ) { + this.value( newVal ); } - } - } - }, - _stop: function(event, index) { + _stop: function( event, index ) { var uiHash = { - handle: this.handles[index], + handle: this.handles[ index ], value: this.value() }; - if (this.options.values && this.options.values.length) { - uiHash.value = this.values(index); + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); uiHash.values = this.values(); } - this._trigger("stop", event, uiHash); + + this._trigger( "stop", event, uiHash ); }, - _change: function(event, index) { - var uiHash = { - handle: this.handles[index], - value: this.value() - }; - if (this.options.values && this.options.values.length) { - uiHash.value = this.values(index); - uiHash.values = this.values(); + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "change", event, uiHash ); } - this._trigger("change", event, uiHash); }, - value: function(newValue) { - - if (arguments.length) { - this._setData("value", newValue); - this._change(null, 0); + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); } return this._value(); - }, - values: function(index, newValue, animated, noPropagation) { + values: function( index, newValue ) { + var vals, + newValues, + i; - if (arguments.length > 1) { - this.options.values[index] = newValue; - this._refreshValue(animated); - if(!noPropagation) this._change(null, index); + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); } - if (arguments.length) { - if (this.options.values && this.options.values.length) { - return this._values(index); + if ( arguments.length ) { + if ( $.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); } else { - return this.value(); + if ( this.options.values && this.options.values.length ) { + return this._values( index ); + } else { + return this.value(); + } } } else { return this._values(); } - }, - _setData: function(key, value, animated) { + _setOption: function( key, value ) { + var i, + valsLength = 0; - $.widget.prototype._setData.apply(this, arguments); + if ( $.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } - switch (key) { - case 'disabled': - if (value) { - this.handles.filter(".ui-state-focus").blur(); - this.handles.removeClass("ui-state-hover"); - this.handles.attr("disabled", "disabled"); + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "disabled": + if ( value ) { + this.handles.filter( ".ui-state-focus" ).blur(); + this.handles.removeClass( "ui-state-hover" ); + this.handles.attr( "disabled", "disabled" ); + this.element.addClass( "ui-disabled" ); } else { - this.handles.removeAttr("disabled"); + this.handles.removeAttr( "disabled" ); + this.element.removeClass( "ui-disabled" ); } - case 'orientation': - + break; + case "orientation": this._detectOrientation(); - this.element - .removeClass("ui-slider-horizontal ui-slider-vertical") - .addClass("ui-slider-" + this.orientation); - this._refreshValue(animated); + .removeClass( "ui-slider-horizontal ui-slider-vertical" ) + .addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; break; - case 'value': - this._refreshValue(animated); + case "values": + this._animateOff = true; + this._refreshValue(); + for ( i = 0; i < valsLength; i += 1 ) { + this._change( null, i ); + } + this._animateOff = false; break; } - - }, - - _step: function() { - var step = this.options.step; - return step; }, + //internal value getter + // _value() returns value trimmed by min and max, aligned by step _value: function() { - var val = this.options.value; - if (val < this._valueMin()) val = this._valueMin(); - if (val > this._valueMax()) val = this._valueMax(); + val = this._trimAlignValue( val ); return val; - }, - _values: function(index) { + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; - if (arguments.length) { - var val = this.options.values[index]; - if (val < this._valueMin()) val = this._valueMin(); - if (val > this._valueMax()) val = this._valueMax(); + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); return val; } else { - return this.options.values; + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i+= 1) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); + } + + return vals; + } + }, + + // returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val < this._valueMin() ) { + return this._valueMin(); + } + if ( val > this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = val % step, + alignValue = val - valModStep; + + if ( Math.abs(valModStep) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); } + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed(5) ); }, _valueMin: function() { - var valueMin = this.options.min; - return valueMin; + return this.options.min; }, _valueMax: function() { - var valueMax = this.options.max; - return valueMax; + return this.options.max; }, - - _refreshValue: function(animate) { - - var oRange = this.options.range, o = this.options, self = this; - - if (this.options.values && this.options.values.length) { - var vp0, vp1; - this.handles.each(function(i, j) { - var valPercent = (self.values(i) - self._valueMin()) / (self._valueMax() - self._valueMin()) * 100; - var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%'; - $(this).stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate); - if (self.options.range === true) { - if (self.orientation == 'horizontal') { - (i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ left: valPercent + '%' }, o.animate); - (i == 1) && self.range[animate ? 'animate' : 'css']({ width: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate }); + + _refreshValue: function() { + var oRange = this.options.range, + o = this.options, + self = this, + animate = ( !this._animateOff ) ? o.animate : false, + valPercent, + _set = {}, + lastValPercent, + value, + valueMin, + valueMax; + + if ( this.options.values && this.options.values.length ) { + this.handles.each(function( i, j ) { + valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100; + _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( self.options.range === true ) { + if ( self.orientation === "horizontal" ) { + if ( i === 0 ) { + self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); + } + if ( i === 1 ) { + self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } } else { - (i == 0) && self.range.stop(1,1)[animate ? 'animate' : 'css']({ bottom: (valPercent) + '%' }, o.animate); - (i == 1) && self.range[animate ? 'animate' : 'css']({ height: (valPercent - lastValPercent) + '%' }, { queue: false, duration: o.animate }); + if ( i === 0 ) { + self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); + } + if ( i === 1 ) { + self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } } } lastValPercent = valPercent; }); } else { - var value = this.value(), - valueMin = this._valueMin(), - valueMax = this._valueMax(), - valPercent = valueMax != valueMin - ? (value - valueMin) / (valueMax - valueMin) * 100 - : 0; - var _set = {}; _set[self.orientation == 'horizontal' ? 'left' : 'bottom'] = valPercent + '%'; - this.handle.stop(1,1)[animate ? 'animate' : 'css'](_set, o.animate); - - (oRange == "min") && (this.orientation == "horizontal") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ width: valPercent + '%' }, o.animate); - (oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate }); - (oRange == "min") && (this.orientation == "vertical") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate); - (oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate }); + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } } - } -})); +}); -$.extend($.ui.slider, { - getter: "value values", - version: "1.7.2", - eventPrefix: "slide", - defaults: { - animate: false, - delay: 0, - distance: 0, - max: 100, - min: 0, - orientation: 'horizontal', - range: false, - step: 1, - value: 0, - values: null - } +$.extend( $.ui.slider, { + version: "1.8.2" }); -})(jQuery); +}(jQuery)); /* - * jQuery UI Tabs 1.7.2 + * jQuery UI Tabs 1.8.2 * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Tabs * * Depends: - * ui.core.js + * jquery.ui.core.js + * jquery.ui.widget.js */ (function($) { -$.widget("ui.tabs", { +var tabId = 0, + listId = 0; - _init: function() { - if (this.options.deselectable !== undefined) { - this.options.collapsible = this.options.deselectable; - } +function getNextTabId() { + return ++tabId; +} + +function getNextListId() { + return ++listId; +} + +$.widget("ui.tabs", { + options: { + add: null, + ajaxOptions: null, + cache: false, + cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } + collapsible: false, + disable: null, + disabled: [], + enable: null, + event: 'click', + fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } + idPrefix: 'ui-tabs-', + load: null, + panelTemplate: '<div></div>', + remove: null, + select: null, + show: null, + spinner: '<em>Loading…</em>', + tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' + }, + _create: function() { this._tabify(true); }, - _setData: function(key, value) { + _setOption: function(key, value) { if (key == 'selected') { if (this.options.collapsible && value == this.options.selected) { return; @@ -8478,16 +10376,13 @@ $.widget("ui.tabs", { } else { this.options[key] = value; - if (key == 'deselectable') { - this.options.collapsible = value; - } this._tabify(); } }, _tabId: function(a) { return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') || - this.options.idPrefix + $.data(a); + this.options.idPrefix + getNextTabId(); }, _sanitizeSelector: function(hash) { @@ -8495,7 +10390,7 @@ $.widget("ui.tabs", { }, _cookie: function() { - var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + $.data(this.list[0])); + var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + getNextListId()); return $.cookie.apply(null, [cookie].concat($.makeArray(arguments))); }, @@ -8519,7 +10414,7 @@ $.widget("ui.tabs", { _tabify: function(init) { - this.list = this.element.children('ul:first'); + this.list = this.element.find('ol,ul').eq(0); this.lis = $('li:has(a[href])', this.list); this.anchors = this.lis.map(function() { return $('a', this)[0]; }); this.panels = $([]); @@ -8601,7 +10496,7 @@ $.widget("ui.tabs", { if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) { o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected')); } - o.selected = o.selected || 0; + o.selected = o.selected || (this.lis.length ? 0 : -1); } else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release o.selected = -1; @@ -8633,7 +10528,7 @@ $.widget("ui.tabs", { self.element.queue("tabs", function() { self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected])); }); - + this.load(o.selected); } @@ -8710,7 +10605,7 @@ $.widget("ui.tabs", { // and prevent IE's ClearType bug... function resetStyle($el, fx) { $el.css({ display: '' }); - if ($.browser.msie && fx.opacity) { + if (!$.support.opacity && fx.opacity) { $el[0].style.removeAttribute('filter'); } } @@ -8718,7 +10613,7 @@ $.widget("ui.tabs", { // Show a tab... var showTab = showFx ? function(clicked, $show) { - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); + $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active'); $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way .animate(showFx, showFx.duration || 'normal', function() { resetStyle($show, showFx); @@ -8726,7 +10621,7 @@ $.widget("ui.tabs", { }); } : function(clicked, $show) { - $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active'); + $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active'); $show.removeClass('ui-tabs-hide'); self._trigger('show', null, self._ui(clicked, $show[0])); }; @@ -8735,14 +10630,14 @@ $.widget("ui.tabs", { var hideTab = hideFx ? function(clicked, $hide) { $hide.animate(hideFx, hideFx.duration || 'normal', function() { - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); + self.lis.removeClass('ui-tabs-selected ui-state-active'); $hide.addClass('ui-tabs-hide'); resetStyle($hide, hideFx); self.element.dequeue("tabs"); }); } : function(clicked, $hide, $show) { - self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default'); + self.lis.removeClass('ui-tabs-selected ui-state-active'); $hide.addClass('ui-tabs-hide'); self.element.dequeue("tabs"); }; @@ -8780,7 +10675,7 @@ $.widget("ui.tabs", { self.element.queue("tabs", function() { hideTab(el, $hide); }).dequeue("tabs"); - + this.blur(); return false; } @@ -8788,13 +10683,13 @@ $.widget("ui.tabs", { if (o.cookie) { self._cookie(o.selected, o.cookie); } - + self.element.queue("tabs", function() { showTab(el, $show); }); self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - + this.blur(); return false; } @@ -8814,7 +10709,7 @@ $.widget("ui.tabs", { self.element.queue("tabs", function() { showTab(el, $show); }); - + self.load(self.anchors.index(this)); } else { @@ -8840,7 +10735,7 @@ $.widget("ui.tabs", { var o = this.options; this.abort(); - + this.element.unbind('.tabs') .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible') .removeData('tabs'); @@ -8882,6 +10777,8 @@ $.widget("ui.tabs", { if (o.cookie) { this._cookie(null, o.cookie); } + + return this; }, add: function(url, label, index) { @@ -8917,17 +10814,19 @@ $.widget("ui.tabs", { this._tabify(); if (this.anchors.length == 1) { // after tabify + o.selected = 0; $li.addClass('ui-tabs-selected ui-state-active'); $panel.removeClass('ui-tabs-hide'); this.element.queue("tabs", function() { self._trigger('show', null, self._ui(self.anchors[0], self.panels[0])); }); - + this.load(0); } // callback this._trigger('add', null, this._ui(this.anchors[index], this.panels[index])); + return this; }, remove: function(index) { @@ -8947,6 +10846,7 @@ $.widget("ui.tabs", { // callback this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0])); + return this; }, enable: function(index) { @@ -8960,6 +10860,7 @@ $.widget("ui.tabs", { // callback this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index])); + return this; }, disable: function(index) { @@ -8973,6 +10874,8 @@ $.widget("ui.tabs", { // callback this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index])); } + + return this; }, select: function(index) { @@ -8987,6 +10890,7 @@ $.widget("ui.tabs", { } this.anchors.eq(index).trigger(this.options.event + '.tabs'); + return this; }, load: function(index) { @@ -9026,11 +10930,28 @@ $.widget("ui.tabs", { o.ajaxOptions.success(r, s); } catch (e) {} + }, + error: function(xhr, s, e) { + // take care of tab labels + self._cleanup(); - // last, so that load event is fired before show... - self.element.dequeue("tabs"); + // callbacks + self._trigger('load', null, self._ui(self.anchors[index], self.panels[index])); + try { + // Passing index avoid a race condition when this method is + // called after the user has selected another tab. + // Pass the anchor that initiated this request allows + // loadError to manipulate the tab content panel via $(a.hash) + o.ajaxOptions.error(xhr, s, index, a); + } + catch (e) {} } })); + + // last, so that load event is fired before show... + self.element.dequeue("tabs"); + + return this; }, abort: function() { @@ -9038,6 +10959,10 @@ $.widget("ui.tabs", { this.element.queue([]); this.panels.stop(false, true); + // "tabs" queue must not contain more than two elements, + // which are the callbacks for the latest clicked tab... + this.element.queue("tabs", this.element.queue("tabs").splice(-2, 2)); + // terminate pending requests from other tabs if (this.xhr) { this.xhr.abort(); @@ -9046,11 +10971,12 @@ $.widget("ui.tabs", { // take care of tab labels this._cleanup(); - + return this; }, url: function(index, url) { this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url); + return this; }, length: function() { @@ -9060,21 +10986,7 @@ $.widget("ui.tabs", { }); $.extend($.ui.tabs, { - version: '1.7.2', - getter: 'length', - defaults: { - ajaxOptions: null, - cache: false, - cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } - collapsible: false, - disabled: [], - event: 'click', - fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } - idPrefix: 'ui-tabs-', - panelTemplate: '<div></div>', - spinner: '<em>Loading…</em>', - tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>' - } + version: '1.8.2' }); /* @@ -9089,19 +11001,19 @@ $.extend($.ui.tabs.prototype, { rotate: function(ms, continuing) { var self = this, o = this.options; - + var rotate = self._rotate || (self._rotate = function(e) { clearTimeout(self.rotation); self.rotation = setTimeout(function() { var t = o.selected; self.select( ++t < self.anchors.length ? t : 0 ); }, ms); - + if (e) { e.stopPropagation(); } }); - + var stop = self._unrotate || (self._unrotate = !continuing ? function(e) { if (e.clientX) { // in case of a true click @@ -9127,6 +11039,8 @@ $.extend($.ui.tabs.prototype, { delete this._rotate; delete this._unrotate; } + + return this; } }); |