diff options
Diffstat (limited to 'lib/scripts/jquery/jquery-ui.js')
-rw-r--r-- | lib/scripts/jquery/jquery-ui.js | 15671 |
1 files changed, 8880 insertions, 6791 deletions
diff --git a/lib/scripts/jquery/jquery-ui.js b/lib/scripts/jquery/jquery-ui.js index 31ee9cd81..021355237 100644 --- a/lib/scripts/jquery/jquery-ui.js +++ b/lib/scripts/jquery/jquery-ui.js @@ -1,7 +1,7 @@ -/*! jQuery UI - v1.11.4 - 2015-03-11 +/*! jQuery UI - v1.12.1 - 2016-09-14 * http://jqueryui.com -* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ +* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ (function( factory ) { if ( typeof define === "function" && define.amd ) { @@ -14,319 +14,36 @@ factory( jQuery ); } }(function( $ ) { -/*! - * jQuery UI Core 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/category/ui-core/ - */ - -// $.ui might exist from components with no dependencies, e.g., $.ui.position $.ui = $.ui || {}; -$.extend( $.ui, { - version: "1.11.4", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - scrollParent: function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; - } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); - }).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; - }, - - uniqueId: (function() { - var uuid = 0; - - return function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); - } - }); - }; - })(), - - removeUniqueId: function() { - return this.each(function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; - return !!img && visible( img ); - } - return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support: jQuery <1.8 -if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - -// deprecated -$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - disableSelection: (function() { - var eventType = "onselectstart" in document.createElement( "div" ) ? - "selectstart" : - "mousedown"; - - return function() { - return this.bind( eventType + ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }; - })(), - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - }, - - 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" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - } -}); - -// $.ui.plugin is deprecated. Use $.widget() extensions instead. -$.ui.plugin = { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args, allowDisconnected ) { - var i, - set = instance.plugins[ name ]; - - if ( !set ) { - return; - } - - if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } -}; +var version = $.ui.version = "1.12.1"; /*! - * jQuery UI Widget 1.11.4 + * jQuery UI Widget 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ */ +//>>label: Widget +//>>group: Core +//>>description: Provides a factory for creating stateful widgets with a common API. +//>>docs: http://api.jqueryui.com/jQuery.widget/ +//>>demos: http://jqueryui.com/widget/ + + -var widget_uuid = 0, - widget_slice = Array.prototype.slice; +var widgetUuid = 0; +var widgetSlice = Array.prototype.slice; -$.cleanData = (function( orig ) { +$.cleanData = ( function( orig ) { return function( elems ) { var events, elem, i; - for ( i = 0; (elem = elems[i]) != null; i++ ) { + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { try { // Only trigger remove when necessary to save time @@ -335,29 +52,34 @@ $.cleanData = (function( orig ) { $( elem ).triggerHandler( "remove" ); } - // http://bugs.jquery.com/ticket/8235 + // Http://bugs.jquery.com/ticket/8235 } catch ( e ) {} } orig( elems ); }; -})( $.cleanData ); +} )( $.cleanData ); $.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; + var existingConstructor, constructor, basePrototype; + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split( "." )[ 0 ]; name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; + var fullName = namespace + "-" + name; if ( !prototype ) { prototype = base; base = $.Widget; } - // create selector for plugin + if ( $.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } + + // Create selector for plugin $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { return !!$.data( elem, fullName ); }; @@ -365,30 +87,35 @@ $.widget = function( name, base, prototype ) { $[ namespace ] = $[ namespace ] || {}; existingConstructor = $[ namespace ][ name ]; constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword + + // Allow instantiation without "new" keyword if ( !this._createWidget ) { return new constructor( options, element ); } - // allow instantiation without initializing for simple inheritance + // Allow instantiation without initializing for simple inheritance // must use "new" keyword (the code above always passes args) if ( arguments.length ) { this._createWidget( options, element ); } }; - // extend with the existing constructor to carry over any static properties + + // Extend with the existing constructor to carry over any static properties $.extend( constructor, existingConstructor, { version: prototype.version, - // copy the object used to create the prototype in case we need to + + // Copy the object used to create the prototype in case we need to // redefine the widget later _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is + + // Track widgets that inherit from this widget in case this widget is // redefined after a widget inherits from it _childConstructors: [] - }); + } ); basePrototype = new base(); - // we need to make the options hash a property directly on the new instance + + // 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 basePrototype.options = $.widget.extend( {}, basePrototype.options ); @@ -397,17 +124,19 @@ $.widget = function( name, base, prototype ) { proxiedPrototype[ prop ] = value; return; } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } + + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } + return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; + var __super = this._super; + var __superApply = this._superApply; + var returnValue; this._super = _super; this._superApply = _superApply; @@ -419,19 +148,20 @@ $.widget = function( name, base, prototype ) { return returnValue; }; - })(); - }); + } )(); + } ); constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name }, proxiedPrototype, { constructor: constructor, namespace: namespace, widgetName: name, widgetFullName: fullName - }); + } ); // If this widget is being redefined then we need to find all widgets that // are inheriting from it and redefine all of them so that they inherit from @@ -441,11 +171,13 @@ $.widget = function( name, base, prototype ) { $.each( existingConstructor._childConstructors, function( i, child ) { var childPrototype = child.prototype; - // redefine the child widget using the same prototype that was + // Redefine the child widget using the same prototype that was // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); + + // Remove the list of existing child constructors from the old constructor // so the old child constructors can be garbage collected delete existingConstructor._childConstructors; } else { @@ -458,21 +190,25 @@ $.widget = function( name, base, prototype ) { }; $.widget.extend = function( target ) { - var input = widget_slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + for ( ; inputIndex < inputLength; inputIndex++ ) { for ( key in input[ inputIndex ] ) { value = input[ inputIndex ][ key ]; if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects if ( $.isPlainObject( value ) ) { target[ key ] = $.isPlainObject( target[ key ] ) ? $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects $.widget.extend( {}, value ); + // Copy everything else by reference } else { target[ key ] = value; @@ -486,41 +222,55 @@ $.widget.extend = function( target ) { $.widget.bridge = function( name, object ) { var fullName = object.prototype.widgetFullName || name; $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = widget_slice.call( arguments, 1 ), - returnValue = this; + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( options === "instance" ) { - returnValue = instance; - return false; - } - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } } else { // Allow multiple hashes to be passed on init if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat(args) ); + options = $.widget.extend.apply( null, [ options ].concat( args ) ); } - this.each(function() { + this.each( function() { var instance = $.data( this, fullName ); if ( instance ) { instance.option( options || {} ); @@ -530,7 +280,7 @@ $.widget.bridge = function( name, object ) { } else { $.data( this, fullName, new object( options, this ) ); } - }); + } ); } return returnValue; @@ -544,21 +294,25 @@ $.Widget.prototype = { widgetName: "widget", widgetEventPrefix: "", defaultElement: "<div>", + options: { + classes: {}, disabled: false, - // callbacks + // Callbacks create: null }, + _createWidget: function( options, element ) { element = $( element || this.defaultElement || this )[ 0 ]; this.element = $( element ); - this.uuid = widget_uuid++; + this.uuid = widgetUuid++; this.eventNamespace = "." + this.widgetName + this.uuid; this.bindings = $(); this.hoverable = $(); this.focusable = $(); + this.classesElementLookup = {}; if ( element !== this ) { $.data( element, this.widgetFullName, this ); @@ -568,13 +322,15 @@ $.Widget.prototype = { this.destroy(); } } - }); + } ); this.document = $( element.style ? - // element within the document + + // Element within the document element.ownerDocument : - // element is window or document + + // Element is window or document element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); } this.options = $.widget.extend( {}, @@ -583,36 +339,46 @@ $.Widget.prototype = { options ); this._create(); + + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + this._trigger( "create", null, this._getCreateEventData() ); this._init(); }, - _getCreateOptions: $.noop, + + _getCreateOptions: function() { + return {}; + }, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, destroy: function() { + var that = this; + this._destroy(); - // we can probably remove the unbind calls in 2.0 + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element - .unbind( this.eventNamespace ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); + // Clean up events and states + this.bindings.off( this.eventNamespace ); }, + _destroy: $.noop, widget: function() { @@ -620,18 +386,20 @@ $.Widget.prototype = { }, option: function( key, value ) { - var options = key, - parts, - curOption, - i; + var options = key; + var parts; + var curOption; + var i; if ( arguments.length === 0 ) { - // don't return a reference to the internal hash + + // Don't return a reference to the internal hash return $.widget.extend( {}, this.options ); } if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } options = {}; parts = key.split( "." ); key = parts.shift(); @@ -658,6 +426,7 @@ $.Widget.prototype = { return this; }, + _setOptions: function( options ) { var key; @@ -667,42 +436,152 @@ $.Widget.prototype = { return this; }, + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + this.options[ key ] = value; if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); + this._setOptionDisabled( value ); + } - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); } + }, - return this; + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } }, enable: function() { - return this._setOptions({ disabled: false }); + return this._setOptions( { disabled: false } ); }, + disable: function() { - return this._setOptions({ disabled: true }); + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + current = $( $.unique( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + this._on( options.element, { + "remove": "_untrackClassesElement" + } ); + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; }, _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; + var delegateElement; + var instance = this; - // no suppressDisabledCheck flag, shuffle arguments + // No suppressDisabledCheck flag, shuffle arguments if ( typeof suppressDisabledCheck !== "boolean" ) { handlers = element; element = suppressDisabledCheck; suppressDisabledCheck = false; } - // no element argument, shuffle and use this.element + // No element argument, shuffle and use this.element if ( !handlers ) { handlers = element; element = this.element; @@ -714,39 +593,41 @@ $.Widget.prototype = { $.each( handlers, function( event, handler ) { function handlerProxy() { - // allow widgets to customize the disabled handling + + // Allow widgets to customize the disabled handling // - disabled as an array instead of boolean // - disabled class as method for disabling individual parts if ( !suppressDisabledCheck && ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { + $( this ).hasClass( "ui-state-disabled" ) ) ) { return; } return ( typeof handler === "string" ? instance[ handler ] : handler ) .apply( instance, arguments ); } - // copy the guid so direct unbinding works + // Copy the guid so direct unbinding works if ( typeof handler !== "string" ) { handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++; } - var match = event.match( /^([\w:-]*)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); + delegateElement.on( eventName, selector, handlerProxy ); } else { - element.bind( eventName, handlerProxy ); + element.on( eventName, handlerProxy ); } - }); + } ); }, _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); + element.off( eventName ).off( eventName ); // Clear the stack to avoid memory leaks (#10056) this.bindings = $( this.bindings.not( element ).get() ); @@ -767,40 +648,41 @@ $.Widget.prototype = { this.hoverable = this.hoverable.add( element ); this._on( element, { mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); }, mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); } - }); + } ); }, _focusable: function( element ) { this.focusable = this.focusable.add( element ); this._on( element, { focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); }, focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); } - }); + } ); }, _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; + var prop, orig; + var callback = this.options[ type ]; data = data || {}; event = $.Event( event ); event.type = ( type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element + + // The original event may come from any element // so we need to reset the target on the new event event.target = this.element[ 0 ]; - // copy original event properties over to the new event + // Copy original event properties over to the new event orig = event.originalEvent; if ( orig ) { for ( prop in orig ) { @@ -812,7 +694,7 @@ $.Widget.prototype = { this.element.trigger( event, data ); return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || event.isDefaultPrevented() ); } }; @@ -822,228 +704,47 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { if ( typeof options === "string" ) { options = { effect: options }; } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; if ( typeof options === "number" ) { options = { duration: options }; } + hasOptions = !$.isEmptyObject( options ); options.complete = callback; + if ( options.delay ) { element.delay( options.delay ); } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { element[ method ]( options ); } else if ( effectName !== method && element[ effectName ] ) { element[ effectName ]( options.duration, options.easing, callback ); } else { - element.queue(function( next ) { + element.queue( function( next ) { $( this )[ method ](); if ( callback ) { callback.call( element[ 0 ] ); } next(); - }); + } ); } }; -}); +} ); var widget = $.widget; /*! - * jQuery UI Mouse 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/mouse/ - */ - - -var mouseHandled = false; -$( document ).mouseup( function() { - mouseHandled = false; -}); - -var mouse = $.widget("ui.mouse", { - version: "1.11.4", - options: { - cancel: "input,textarea,button,select,option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind("mousedown." + this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind("click." + this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { - $.removeData(event.target, that.widgetName + ".preventClickEvent"); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("." + this.widgetName); - if ( this._mouseMoveDelegate ) { - this.document - .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; - } - - this._mouseMoved = false; - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { - $.removeData(event.target, this.widgetName + ".preventClickEvent"); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - - this.document - .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); - - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - return this._mouseUp( event ); - } - } - - if ( event.which || event.button ) { - this._mouseMoved = true; - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - this.document - .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + ".preventClickEvent", true); - } - - this._mouseStop(event); - } - - mouseHandled = false; - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(/* event */) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } -}); - - -/*! - * jQuery UI Position 1.11.4 + * jQuery UI Position 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -1053,14 +754,17 @@ var mouse = $.widget("ui.mouse", { * http://api.jqueryui.com/position/ */ -(function() { +//>>label: Position +//>>group: Core +//>>description: Positions elements relative to other elements. +//>>docs: http://api.jqueryui.com/position/ +//>>demos: http://jqueryui.com/position/ -$.ui = $.ui || {}; -var cachedScrollbarWidth, supportsOffsetFractions, +( function() { +var cachedScrollbarWidth, max = Math.max, abs = Math.abs, - round = Math.round, rhorizontal = /left|center|right/, rvertical = /top|center|bottom/, roffset = /[\+\-]\d+(\.[\d]+)?%?/, @@ -1080,7 +784,7 @@ function parseCss( element, property ) { } function getDimensions( elem ) { - var raw = elem[0]; + var raw = elem[ 0 ]; if ( raw.nodeType === 9 ) { return { width: elem.width(), @@ -1115,8 +819,10 @@ $.position = { return cachedScrollbarWidth; } var w1, w2, - div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), - innerDiv = div.children()[0]; + div = $( "<div " + + "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + + "<div style='height:100px;width:auto;'></div></div>" ), + innerDiv = div.children()[ 0 ]; $( "body" ).append( div ); w1 = innerDiv.offsetWidth; @@ -1125,12 +831,12 @@ $.position = { w2 = innerDiv.offsetWidth; if ( w1 === w2 ) { - w2 = div[0].clientWidth; + w2 = div[ 0 ].clientWidth; } div.remove(); - return (cachedScrollbarWidth = w1 - w2); + return ( cachedScrollbarWidth = w1 - w2 ); }, getScrollInfo: function( within ) { var overflowX = within.isWindow || within.isDocument ? "" : @@ -1138,9 +844,9 @@ $.position = { overflowY = within.isWindow || within.isDocument ? "" : within.element.css( "overflow-y" ), hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); return { width: hasOverflowY ? $.position.scrollbarWidth() : 0, height: hasOverflowX ? $.position.scrollbarWidth() : 0 @@ -1148,20 +854,18 @@ $.position = { }, getWithinInfo: function( element ) { var withinElement = $( element || window ), - isWindow = $.isWindow( withinElement[0] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; + isWindow = $.isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isWindow && !isDocument; return { element: withinElement, isWindow: isWindow, isDocument: isDocument, - offset: withinElement.offset() || { left: 0, top: 0 }, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), - - // support: jQuery 1.6.x - // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows - width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), - height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() + width: withinElement.outerWidth(), + height: withinElement.outerHeight() }; } }; @@ -1171,7 +875,7 @@ $.fn.position = function( options ) { return _position.apply( this, arguments ); } - // make a copy, we don't want to modify arguments + // Make a copy, we don't want to modify arguments options = $.extend( {}, options ); var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, @@ -1182,24 +886,26 @@ $.fn.position = function( options ) { offsets = {}; dimensions = getDimensions( target ); - if ( target[0].preventDefault ) { - // force left top to allow flipping + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping options.at = "left top"; } targetWidth = dimensions.width; targetHeight = dimensions.height; targetOffset = dimensions.offset; - // clone to reuse original targetOffset later + + // Clone to reuse original targetOffset later basePosition = $.extend( {}, targetOffset ); - // force my and at to have valid horizontal and vertical positions + // Force my and at to have valid horizontal and vertical positions // if a value is missing or invalid, it will be converted to center $.each( [ "my", "at" ], function() { var pos = ( options[ this ] || "" ).split( " " ), horizontalOffset, verticalOffset; - if ( pos.length === 1) { + if ( pos.length === 1 ) { pos = rhorizontal.test( pos[ 0 ] ) ? pos.concat( [ "center" ] ) : rvertical.test( pos[ 0 ] ) ? @@ -1209,7 +915,7 @@ $.fn.position = function( options ) { pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - // calculate offsets + // Calculate offsets horizontalOffset = roffset.exec( pos[ 0 ] ); verticalOffset = roffset.exec( pos[ 1 ] ); offsets[ this ] = [ @@ -1217,14 +923,14 @@ $.fn.position = function( options ) { verticalOffset ? verticalOffset[ 0 ] : 0 ]; - // reduce to just the positions without the offsets + // Reduce to just the positions without the offsets options[ this ] = [ rposition.exec( pos[ 0 ] )[ 0 ], rposition.exec( pos[ 1 ] )[ 0 ] ]; - }); + } ); - // normalize collision option + // Normalize collision option if ( collision.length === 1 ) { collision[ 1 ] = collision[ 0 ]; } @@ -1245,15 +951,17 @@ $.fn.position = function( options ) { basePosition.left += atOffset[ 0 ]; basePosition.top += atOffset[ 1 ]; - return this.each(function() { + return this.each( function() { var collisionPosition, using, elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseCss( this, "marginLeft" ), marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, position = $.extend( {}, basePosition ), myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); @@ -1272,12 +980,6 @@ $.fn.position = function( options ) { position.left += myOffset[ 0 ]; position.top += myOffset[ 1 ]; - // if the browser doesn't support fractions, then round for consistent results - if ( !supportsOffsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); - } - collisionPosition = { marginLeft: marginLeft, marginTop: marginTop @@ -1298,12 +1000,13 @@ $.fn.position = function( options ) { at: options.at, within: within, elem: elem - }); + } ); } - }); + } ); if ( options.using ) { - // adds feedback as second argument to using callback, if present + + // Adds feedback as second argument to using callback, if present using = function( props ) { var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, @@ -1343,7 +1046,7 @@ $.fn.position = function( options ) { } elem.offset( $.extend( position, { using: using } ) ); - }); + } ); }; $.ui.position = { @@ -1357,16 +1060,20 @@ $.ui.position = { overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, newOverRight; - // element is wider than within + // Element is wider than within if ( data.collisionWidth > outerWidth ) { - // element is initially over the left side of within + + // Element is initially over the left side of within if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; position.left += overLeft - newOverRight; - // element is initially over right side of within + + // Element is initially over right side of within } else if ( overRight > 0 && overLeft <= 0 ) { position.left = withinOffset; - // element is initially over both left and right sides of within + + // Element is initially over both left and right sides of within } else { if ( overLeft > overRight ) { position.left = withinOffset + outerWidth - data.collisionWidth; @@ -1374,13 +1081,16 @@ $.ui.position = { position.left = withinOffset; } } - // too far left -> align with left edge + + // Too far left -> align with left edge } else if ( overLeft > 0 ) { position.left += overLeft; - // too far right -> align with right edge + + // Too far right -> align with right edge } else if ( overRight > 0 ) { position.left -= overRight; - // adjust based on position and margin + + // Adjust based on position and margin } else { position.left = max( position.left - collisionPosLeft, position.left ); } @@ -1394,16 +1104,20 @@ $.ui.position = { overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, newOverBottom; - // element is taller than within + // Element is taller than within if ( data.collisionHeight > outerHeight ) { - // element is initially over the top of within + + // Element is initially over the top of within if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; position.top += overTop - newOverBottom; - // element is initially over bottom of within + + // Element is initially over bottom of within } else if ( overBottom > 0 && overTop <= 0 ) { position.top = withinOffset; - // element is initially over both top and bottom of within + + // Element is initially over both top and bottom of within } else { if ( overTop > overBottom ) { position.top = withinOffset + outerHeight - data.collisionHeight; @@ -1411,13 +1125,16 @@ $.ui.position = { position.top = withinOffset; } } - // too far up -> align with top + + // Too far up -> align with top } else if ( overTop > 0 ) { position.top += overTop; - // too far down -> align with bottom edge + + // Too far down -> align with bottom edge } else if ( overBottom > 0 ) { position.top -= overBottom; - // adjust based on position and margin + + // Adjust based on position and margin } else { position.top = max( position.top - collisionPosTop, position.top ); } @@ -1447,12 +1164,14 @@ $.ui.position = { newOverLeft; if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { position.left += myOffset + atOffset + offset; } } else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { position.left += myOffset + atOffset + offset; } @@ -1481,12 +1200,14 @@ $.ui.position = { newOverTop, newOverBottom; if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { position.top += myOffset + atOffset + offset; } } else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { position.top += myOffset + atOffset + offset; } @@ -1505,77 +1226,3115 @@ $.ui.position = { } }; -// fraction support test -(function() { - var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); - - //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" +} )(); + +var position = $.ui.position; + + +/*! + * jQuery UI :data 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :data Selector +//>>group: Core +//>>description: Selects elements which have data stored under the specified key. +//>>docs: http://api.jqueryui.com/data-selector/ + + +var data = $.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo( function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + } ) : + + // Support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + } +} ); + +/*! + * jQuery UI Disable Selection 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: disableSelection +//>>group: Core +//>>description: Disable selection of text content within the set of matched elements. +//>>docs: http://api.jqueryui.com/disableSelection/ + +// This file is deprecated + + +var disableSelection = $.fn.extend( { + disableSelection: ( function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.on( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + } ); + }; + } )(), + + enableSelection: function() { + return this.off( ".ui-disableSelection" ); + } +} ); + + +/*! + * jQuery UI Effects 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Effects Core +//>>group: Effects +// jscs:disable maximumLineLength +//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. +// jscs:enable maximumLineLength +//>>docs: http://api.jqueryui.com/category/effects-core/ +//>>demos: http://jqueryui.com/effect/ + + + +var dataSpace = "ui-effects-", + dataSpaceStyle = "ui-effects-style", + dataSpaceAnimated = "ui-effects-animated", + + // Create a local jQuery because jQuery Color relies on it and the + // global may not exist with AMD and a custom build (#10199) + jQuery = $; + +$.effects = { + effect: {} +}; + +/*! + * jQuery Color Animations v2.1.2 + * https://github.com/jquery/jquery-color + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: Wed Jan 16 08:47:09 2013 -0600 + */ +( function( jQuery, undefined ) { + + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + + "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + + // Plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + + // A set of RE's that can match strings and generate color tuples. + stringParsers = [ { + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ], + execResult[ 3 ], + execResult[ 4 ] + ]; + } + }, { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, + execResult[ 4 ] + ]; + } + }, { + + // This regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ) + ]; + } + }, { + + // This regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) + ]; + } + }, { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + space: "hsla", + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] + ]; + } + } ], + + // JQuery.Color( ) + color = jQuery.Color = function( color, green, blue, alpha ) { + return new jQuery.Color.fn.parse( color, green, blue, alpha ); + }, + spaces = { + rgba: { + props: { + red: { + idx: 0, + type: "byte" + }, + green: { + idx: 1, + type: "byte" + }, + blue: { + idx: 2, + type: "byte" + } + } + }, + + hsla: { + props: { + hue: { + idx: 0, + type: "degrees" + }, + saturation: { + idx: 1, + type: "percent" + }, + lightness: { + idx: 2, + type: "percent" + } + } + } + }, + propTypes = { + "byte": { + floor: true, + max: 255 + }, + "percent": { + max: 1 + }, + "degrees": { + mod: 360, + floor: true + } + }, + support = color.support = {}, + + // Element for support tests + supportElem = jQuery( "<p>" )[ 0 ], + + // Colors = jQuery.Color.names + colors, + + // Local aliases of functions called often + each = jQuery.each; + +// Determine rgba support immediately +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + +// Define cache name and alpha properties +// for rgba and hsla spaces +each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 }; - if ( body ) { - $.extend( testElementStyle, { - position: "absolute", - left: "-1000px", - top: "-1000px" - }); +} ); + +function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return ( allowEmpty || !prop.def ) ? null : prop.def; + } + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; + + if ( type.mod ) { + + // We add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return ( value + type.mod ) % type.mod; } - testElement.appendChild( div ); - testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - div.style.cssText = "position: absolute; left: 10.7432222px;"; + // For now all property types without mod have min and max + return 0 > value ? 0 : type.max < value ? type.max : value; +} - offsetLeft = $( div ).offset().left; - supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; +function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); -})(); + string = string.toLowerCase(); -})(); + each( stringParsers, function( i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; -var position = $.ui.position; + if ( values ) { + parsed = inst[ spaceName ]( values ); + + // If this was an rgba parse the assignment might happen twice + // oh well.... + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + rgba = inst._rgba = parsed._rgba; + + // Exit each( stringParsers ) here because we matched + return false; + } + } ); + + // Found a stringParser that handled it + if ( rgba.length ) { + + // If this came from a parsed string, force "transparent" when alpha is 0 + // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) + if ( rgba.join() === "0,0,0,0" ) { + jQuery.extend( rgba, colors.transparent ); + } + return inst; + } + + // Named colors + return colors[ string ]; +} + +color.fn = jQuery.extend( color.prototype, { + parse: function( red, green, blue, alpha ) { + if ( red === undefined ) { + this._rgba = [ null, null, null, null ]; + return this; + } + if ( red.jquery || red.nodeType ) { + red = jQuery( red ).css( green ); + green = undefined; + } + + var inst = this, + type = jQuery.type( red ), + rgba = this._rgba = []; + + // More than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } + + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } + + if ( type === "array" ) { + each( spaces.rgba.props, function( key, prop ) { + rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + } ); + return this; + } + + if ( type === "object" ) { + if ( red instanceof color ) { + each( spaces, function( spaceName, space ) { + if ( red[ space.cache ] ) { + inst[ space.cache ] = red[ space.cache ].slice(); + } + } ); + } else { + each( spaces, function( spaceName, space ) { + var cache = space.cache; + each( space.props, function( key, prop ) { + + // If the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { + + // If the value was null, we don't need to copy it + // if the key was alpha, we don't need to copy it either + if ( key === "alpha" || red[ key ] == null ) { + return; + } + inst[ cache ] = space.to( inst._rgba ); + } + + // This is the only case where we allow nulls for ALL properties. + // call clamp with alwaysAllowEmpty + inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); + } ); + + // Everything defined but alpha? + if ( inst[ cache ] && + jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + + // Use the default of 1 + inst[ cache ][ 3 ] = 1; + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + } ); + } + return this; + } + }, + is: function( compare ) { + var is = color( compare ), + same = true, + inst = this; + + each( spaces, function( _, space ) { + var localCache, + isCache = is[ space.cache ]; + if ( isCache ) { + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; + each( space.props, function( _, prop ) { + if ( isCache[ prop.idx ] != null ) { + same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); + return same; + } + } ); + } + return same; + } ); + return same; + }, + _space: function() { + var used = [], + inst = this; + each( spaces, function( spaceName, space ) { + if ( inst[ space.cache ] ) { + used.push( spaceName ); + } + } ); + return used.pop(); + }, + transition: function( other, distance ) { + var end = color( other ), + spaceName = end._space(), + space = spaces[ spaceName ], + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), + result = start.slice(); + + end = end[ space.cache ]; + each( space.props, function( key, prop ) { + var index = prop.idx, + startValue = start[ index ], + endValue = end[ index ], + type = propTypes[ prop.type ] || {}; + + // If null, don't override start value + if ( endValue === null ) { + return; + } + + // If null - use end + if ( startValue === null ) { + result[ index ] = endValue; + } else { + if ( type.mod ) { + if ( endValue - startValue > type.mod / 2 ) { + startValue += type.mod; + } else if ( startValue - endValue > type.mod / 2 ) { + startValue -= type.mod; + } + } + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + } + } ); + return this[ spaceName ]( result ); + }, + blend: function( opaque ) { + + // If we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } + + var rgb = this._rgba.slice(), + a = rgb.pop(), + blend = color( opaque )._rgba; + + return color( jQuery.map( rgb, function( v, i ) { + return ( 1 - a ) * blend[ i ] + a * v; + } ) ); + }, + toRgbaString: function() { + var prefix = "rgba(", + rgba = jQuery.map( this._rgba, function( v, i ) { + return v == null ? ( i > 2 ? 1 : 0 ) : v; + } ); + + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } + + return prefix + rgba.join() + ")"; + }, + toHslaString: function() { + var prefix = "hsla(", + hsla = jQuery.map( this.hsla(), function( v, i ) { + if ( v == null ) { + v = i > 2 ? 1 : 0; + } + + // Catch 1 and 2 + if ( i && i < 3 ) { + v = Math.round( v * 100 ) + "%"; + } + return v; + } ); + + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; + } + return prefix + hsla.join() + ")"; + }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); + + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); + } + + return "#" + jQuery.map( rgba, function( v ) { + + // Default to 0 when nulls exist + v = ( v || 0 ).toString( 16 ); + return v.length === 1 ? "0" + v : v; + } ).join( "" ); + }, + toString: function() { + return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + } +} ); +color.fn.parse.prototype = color.fn; + +// Hsla conversions adapted from: +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 + +function hue2rgb( p, q, h ) { + h = ( h + 1 ) % 1; + if ( h * 6 < 1 ) { + return p + ( q - p ) * h * 6; + } + if ( h * 2 < 1 ) { + return q; + } + if ( h * 3 < 2 ) { + return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; + } + return p; +} + +spaces.hsla.to = function( rgba ) { + if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { + return [ null, null, null, rgba[ 3 ] ]; + } + var r = rgba[ 0 ] / 255, + g = rgba[ 1 ] / 255, + b = rgba[ 2 ] / 255, + a = rgba[ 3 ], + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + diff = max - min, + add = max + min, + l = add * 0.5, + h, s; + + if ( min === max ) { + h = 0; + } else if ( r === max ) { + h = ( 60 * ( g - b ) / diff ) + 360; + } else if ( g === max ) { + h = ( 60 * ( b - r ) / diff ) + 120; + } else { + h = ( 60 * ( r - g ) / diff ) + 240; + } + + // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0% + // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) + if ( diff === 0 ) { + s = 0; + } else if ( l <= 0.5 ) { + s = diff / add; + } else { + s = diff / ( 2 - add ); + } + return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; +}; + +spaces.hsla.from = function( hsla ) { + if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { + return [ null, null, null, hsla[ 3 ] ]; + } + var h = hsla[ 0 ] / 360, + s = hsla[ 1 ], + l = hsla[ 2 ], + a = hsla[ 3 ], + q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, + p = 2 * l - q; + + return [ + Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), + Math.round( hue2rgb( p, q, h ) * 255 ), + Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), + a + ]; +}; + +each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; + + // Makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { + + // Generate a cache for this space if it doesn't exist + if ( to && !this[ cache ] ) { + this[ cache ] = to( this._rgba ); + } + if ( value === undefined ) { + return this[ cache ].slice(); + } + + var ret, + type = jQuery.type( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); + + each( props, function( key, prop ) { + var val = arr[ type === "object" ? key : prop.idx ]; + if ( val == null ) { + val = local[ prop.idx ]; + } + local[ prop.idx ] = clamp( val, prop ); + } ); + + if ( from ) { + ret = color( from( local ) ); + ret[ cache ] = local; + return ret; + } else { + return color( local ); + } + }; + + // Makes red() green() blue() alpha() hue() saturation() lightness() + each( props, function( key, prop ) { + + // Alpha is included in more than one space + if ( color.fn[ key ] ) { + return; + } + color.fn[ key ] = function( value ) { + var vtype = jQuery.type( value ), + fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), + local = this[ fn ](), + cur = local[ prop.idx ], + match; + + if ( vtype === "undefined" ) { + return cur; + } + + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = jQuery.type( value ); + } + if ( value == null && prop.empty ) { + return this; + } + if ( vtype === "string" ) { + match = rplusequals.exec( value ); + if ( match ) { + value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + } + } + local[ prop.idx ] = value; + return this[ fn ]( local ); + }; + } ); +} ); + +// Add cssHook and .fx.step function for each named hook. +// accept a space separated string of properties +color.hook = function( hook ) { + var hooks = hook.split( " " ); + each( hooks, function( i, hook ) { + jQuery.cssHooks[ hook ] = { + set: function( elem, value ) { + var parsed, curElem, + backgroundColor = ""; + + if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || + ( parsed = stringParse( value ) ) ) ) { + value = color( parsed || value ); + if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + curElem = hook === "backgroundColor" ? elem.parentNode : elem; + while ( + ( backgroundColor === "" || backgroundColor === "transparent" ) && + curElem && curElem.style + ) { + try { + backgroundColor = jQuery.css( curElem, "backgroundColor" ); + curElem = curElem.parentNode; + } catch ( e ) { + } + } + + value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + backgroundColor : + "_default" ); + } + + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch ( e ) { + + // Wrapped to prevent IE from throwing errors on "invalid" values like + // 'auto' or 'inherit' + } + } + }; + jQuery.fx.step[ hook ] = function( fx ) { + if ( !fx.colorInit ) { + fx.start = color( fx.elem, hook ); + fx.end = color( fx.end ); + fx.colorInit = true; + } + jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); + }; + } ); + +}; + +color.hook( stepHooks ); + +jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; + + each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { + expanded[ "border" + part + "Color" ] = value; + } ); + return expanded; + } +}; + +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. +colors = jQuery.Color.names = { + + // 4.1. Basic color keywords + aqua: "#00ffff", + black: "#000000", + blue: "#0000ff", + fuchsia: "#ff00ff", + gray: "#808080", + green: "#008000", + lime: "#00ff00", + maroon: "#800000", + navy: "#000080", + olive: "#808000", + purple: "#800080", + red: "#ff0000", + silver: "#c0c0c0", + teal: "#008080", + white: "#ffffff", + yellow: "#ffff00", + + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], + + _default: "#ffffff" +}; + +} )( jQuery ); + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ +( function() { + +var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + +$.each( + [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], + function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; + } +); + +function getElementStyles( elem ) { + var key, len, + style = elem.ownerDocument.defaultView ? + elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.currentStyle, + styles = {}; + + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + styles[ $.camelCase( key ) ] = style[ key ]; + } + } + + // Support: Opera, IE <9 + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + styles[ key ] = style[ key ]; + } + } + } + + return styles; +} + +function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; + + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] !== value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } + + return diff; +} + +// Support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +$.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + applyClassChange, + allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + + // Map the animated objects to store the original styles. + allAnimations = allAnimations.map( function() { + var el = $( this ); + return { + el: el, + start: getElementStyles( this ) + }; + } ); + + // Apply class change + applyClassChange = function() { + $.each( classAnimationActions, function( i, action ) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + } ); + }; + applyClassChange(); + + // Map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map( function() { + this.end = getElementStyles( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + } ); + + // Apply original class + animated.attr( "class", baseClass ); + + // Map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map( function() { + var styleInfo = this, + dfd = $.Deferred(), + opts = $.extend( {}, o, { + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + } ); + + this.el.animate( this.diff, opts ); + return dfd.promise(); + } ); + + // Once all animations have completed: + $.when.apply( $, allAnimations.get() ).done( function() { + + // Set the final class + applyClassChange(); + + // For each animated element, + // clear all css properties that were animated + $.each( arguments, function() { + var el = this.el; + $.each( this.diff, function( key ) { + el.css( key, "" ); + } ); + } ); + + // This is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + } ); + } ); +}; + +$.fn.extend( { + addClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.call( this, + { add: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.addClass ), + + removeClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return arguments.length > 1 ? + $.effects.animateClass.call( this, + { remove: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.removeClass ), + + toggleClass: ( function( orig ) { + return function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { + + // Without speed parameter + return orig.apply( this, arguments ); + } else { + return $.effects.animateClass.call( this, + ( force ? { add: classNames } : { remove: classNames } ), + speed, easing, callback ); + } + } else { + + // Without force parameter + return $.effects.animateClass.call( this, + { toggle: classNames }, force, speed, easing ); + } + }; + } )( $.fn.toggleClass ), + + switchClass: function( remove, add, speed, easing, callback ) { + return $.effects.animateClass.call( this, { + add: add, + remove: remove + }, speed, easing, callback ); + } +} ); + +} )(); + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +( function() { + +if ( $.expr && $.expr.filters && $.expr.filters.animated ) { + $.expr.filters.animated = ( function( orig ) { + return function( elem ) { + return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); + }; + } )( $.expr.filters.animated ); +} + +if ( $.uiBackCompat !== false ) { + $.extend( $.effects, { + + // Saves a set of properties in a data storage + save: function( element, set ) { + var i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + var val, i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + element.css( set[ i ], val ); + } + } + }, + + setMode: function( el, mode ) { + if ( mode === "toggle" ) { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // 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 + } ), + + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + // Support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + active.id; + } catch ( e ) { + active = document.body; + } + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + + // Hotfix for jQuery 1.4 since some change in wrap() seems to actually + // lose the reference to the wrapped element + wrapper = element.parent(); + + // 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, + right: "auto", + bottom: "auto" + } ); + } + element.css( size ); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + } + + return element; + } + } ); +} + +$.extend( $.effects, { + version: "1.12.1", + + define: function( name, mode, effect ) { + if ( !effect ) { + effect = mode; + mode = "effect"; + } + + $.effects.effect[ name ] = effect; + $.effects.effect[ name ].mode = mode; + + return effect; + }, + + scaledDimensions: function( element, percent, direction ) { + if ( percent === 0 ) { + return { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; + } + + var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, + y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; + + return { + height: element.height() * y, + width: element.width() * x, + outerHeight: element.outerHeight() * y, + outerWidth: element.outerWidth() * x + }; + + }, + + clipToBox: function( animation ) { + return { + width: animation.clip.right - animation.clip.left, + height: animation.clip.bottom - animation.clip.top, + left: animation.clip.left, + top: animation.clip.top + }; + }, + + // Injects recently queued functions to be first in line (after "inprogress") + unshift: function( element, queueLength, count ) { + var queue = element.queue(); + + if ( queueLength > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); + } + element.dequeue(); + }, + + saveStyle: function( element ) { + element.data( dataSpaceStyle, element[ 0 ].style.cssText ); + }, + + restoreStyle: function( element ) { + element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; + element.removeData( dataSpaceStyle ); + }, + + mode: function( element, mode ) { + var hidden = element.is( ":hidden" ); + + if ( mode === "toggle" ) { + mode = hidden ? "show" : "hide"; + } + if ( hidden ? mode === "hide" : mode === "show" ) { + mode = "none"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + getBaseline: function( origin, original ) { + 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 + }; + }, + + // Creates a placeholder element so that the original element can be made absolute + createPlaceholder: function( element ) { + var placeholder, + cssPosition = element.css( "position" ), + position = element.position(); + + // Lock in margins first to account for form elements, which + // will change margin if you explicitly set height + // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 + // Support: Safari + element.css( { + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ); + + if ( /^(static|relative)/.test( cssPosition ) ) { + cssPosition = "absolute"; + + placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { + + // Convert inline to inline block to account for inline elements + // that turn to inline block based on content (like img) + display: /^(inline|ruby)/.test( element.css( "display" ) ) ? + "inline-block" : + "block", + visibility: "hidden", + + // Margins need to be set to account for margin collapse + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ), + "float": element.css( "float" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ) + .addClass( "ui-effects-placeholder" ); + + element.data( dataSpace + "placeholder", placeholder ); + } + + element.css( { + position: cssPosition, + left: position.left, + top: position.top + } ); + + return placeholder; + }, + + removePlaceholder: function( element ) { + var dataKey = dataSpace + "placeholder", + placeholder = element.data( dataKey ); + + if ( placeholder ) { + placeholder.remove(); + element.removeData( dataKey ); + } + }, + + // Removes a placeholder if it exists and restores + // properties that were modified during placeholder creation + cleanUp: function( element ) { + $.effects.restoreStyle( element ); + $.effects.removePlaceholder( element ); + }, + + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function( i, x ) { + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) { + value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + } + } ); + return value; + } +} ); + +// Return an effect options object for the given parameters: +function _normalizeArguments( effect, options, speed, callback ) { + + // Allow passing all options as the first parameter + if ( $.isPlainObject( effect ) ) { + options = effect; + effect = effect.effect; + } + + // Convert to an object + effect = { effect: effect }; + + // Catch (effect, null, ...) + if ( options == null ) { + options = {}; + } + + // Catch (effect, callback) + if ( $.isFunction( options ) ) { + callback = options; + speed = null; + options = {}; + } + + // Catch (effect, speed, ?) + if ( typeof options === "number" || $.fx.speeds[ options ] ) { + callback = speed; + speed = options; + options = {}; + } + + // Catch (effect, options, callback) + if ( $.isFunction( speed ) ) { + callback = speed; + speed = null; + } + + // Add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : + typeof speed === "number" ? speed : + speed in $.fx.speeds ? $.fx.speeds[ speed ] : + $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; +} + +function standardAnimationOption( option ) { + + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + return true; + } + + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } + + // Complete callback + if ( $.isFunction( option ) ) { + return true; + } + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } + + // Didn't match any standard API + return false; +} + +$.fn.extend( { + effect: function( /* effect, options, speed, callback */ ) { + var args = _normalizeArguments.apply( this, arguments ), + effectMethod = $.effects.effect[ args.effect ], + defaultMode = effectMethod.mode, + queue = args.queue, + queueName = queue || "fx", + complete = args.complete, + mode = args.mode, + modes = [], + prefilter = function( next ) { + var el = $( this ), + normalizedMode = $.effects.mode( el, mode ) || defaultMode; + + // Sentinel for duck-punching the :animated psuedo-selector + el.data( dataSpaceAnimated, true ); + + // Save effect mode for later use, + // we can't just call $.effects.mode again later, + // as the .show() below destroys the initial state + modes.push( normalizedMode ); + + // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13 + if ( defaultMode && ( normalizedMode === "show" || + ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { + el.show(); + } + + if ( !defaultMode || normalizedMode !== "none" ) { + $.effects.saveStyle( el ); + } + + if ( $.isFunction( next ) ) { + next(); + } + }; + + if ( $.fx.off || !effectMethod ) { + + // Delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, complete ); + } else { + return this.each( function() { + if ( complete ) { + complete.call( this ); + } + } ); + } + } + + function run( next ) { + var elem = $( this ); + + function cleanup() { + elem.removeData( dataSpaceAnimated ); + + $.effects.cleanUp( elem ); + + if ( args.mode === "hide" ) { + elem.hide(); + } + + done(); + } + + function done() { + if ( $.isFunction( complete ) ) { + complete.call( elem[ 0 ] ); + } + + if ( $.isFunction( next ) ) { + next(); + } + } + + // Override mode option on a per element basis, + // as toggle can be either show or hide depending on element state + args.mode = modes.shift(); + + if ( $.uiBackCompat !== false && !defaultMode ) { + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, done ); + } + } else { + if ( args.mode === "none" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, cleanup ); + } + } + } + + // Run prefilter on all elements first to ensure that + // any showing or hiding happens before placeholder creation, + // which ensures that any layout changes are correctly captured. + return queue === false ? + this.each( prefilter ).each( run ) : + this.queue( queueName, prefilter ).queue( queueName, run ); + }, + + show: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.show ), + + hide: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.hide ), + + toggle: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.toggle ), + + 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; + }, + + cssClip: function( clipObj ) { + if ( clipObj ) { + return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + + clipObj.bottom + "px " + clipObj.left + "px)" ); + } + return parseClip( this.css( "clip" ), this ); + }, + + transfer: function( options, done ) { + var element = $( this ), + target = $( options.to ), + targetFixed = target.css( "position" ) === "fixed", + body = $( "body" ), + fixTop = targetFixed ? body.scrollTop() : 0, + fixLeft = targetFixed ? body.scrollLeft() : 0, + endPosition = target.offset(), + animation = { + top: endPosition.top - fixTop, + left: endPosition.left - fixLeft, + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = element.offset(), + transfer = $( "<div class='ui-effects-transfer'></div>" ) + .appendTo( "body" ) + .addClass( options.className ) + .css( { + top: startPosition.top - fixTop, + left: startPosition.left - fixLeft, + height: element.innerHeight(), + width: element.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + } ) + .animate( animation, options.duration, options.easing, function() { + transfer.remove(); + if ( $.isFunction( done ) ) { + done(); + } + } ); + } +} ); + +function parseClip( str, element ) { + var outerWidth = element.outerWidth(), + outerHeight = element.outerHeight(), + clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, + values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; + + return { + top: parseFloat( values[ 1 ] ) || 0, + right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), + bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), + left: parseFloat( values[ 4 ] ) || 0 + }; +} + +$.fx.step.clip = function( fx ) { + if ( !fx.clipInit ) { + fx.start = $( fx.elem ).cssClip(); + if ( typeof fx.end === "string" ) { + fx.end = parseClip( fx.end, fx.elem ); + } + fx.clipInit = true; + } + + $( fx.elem ).cssClip( { + top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, + right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, + bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, + left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left + } ); +}; + +} )(); + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + +( function() { + +// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) + +var baseEasings = {}; + +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; +} ); + +$.extend( baseEasings, { + Sine: function( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); + }, + Circ: function( p ) { + return 1 - Math.sqrt( 1 - p * p ); + }, + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); + }, + Back: function( p ) { + return p * p * ( 3 * p - 2 ); + }, + Bounce: function( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); + } +} ); + +$.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < 0.5 ? + easeIn( p * 2 ) / 2 : + 1 - easeIn( p * -2 + 2 ) / 2; + }; +} ); + +} )(); + +var effect = $.effects; /*! - * jQuery UI Accordion 1.11.4 + * jQuery UI Effects Blind 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license + */ + +//>>label: Blind Effect +//>>group: Effects +//>>description: Blinds the element. +//>>docs: http://api.jqueryui.com/blind-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { + var map = { + up: [ "bottom", "top" ], + vertical: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + horizontal: [ "right", "left" ], + right: [ "left", "right" ] + }, + element = $( this ), + direction = options.direction || "up", + start = element.cssClip(), + animate = { clip: $.extend( {}, start ) }, + placeholder = $.effects.createPlaceholder( element ); + + animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; + + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animate ) ); + } + + animate.clip = start; + } + + if ( placeholder ) { + placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); + } + + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Bounce 1.12.1 + * http://jqueryui.com * - * http://api.jqueryui.com/accordion/ + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license */ +//>>label: Bounce Effect +//>>group: Effects +//>>description: Bounces an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/bounce-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { + var upAnim, downAnim, refValue, + element = $( this ), + + // Defaults: + mode = options.mode, + hide = mode === "hide", + show = mode === "show", + direction = options.direction || "up", + distance = options.distance, + times = options.times || 5, + + // Number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = options.duration / anims, + easing = options.easing, + + // Utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i = 0, + + queuelen = element.queue().length; + + $.effects.createPlaceholder( element ); + + refValue = element.css( ref ); + + // Default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } + + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = refValue; + + // If we are showing, force opacity 0 and set the initial position + // then do the "first" animation + element + .css( "opacity", 0 ) + .css( ref, motion ? -distance * 2 : distance * 2 ) + .animate( downAnim, speed, easing ); + } + + // Start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); + } + + downAnim = {}; + downAnim[ ref ] = refValue; + + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( ; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + element + .animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); + + distance = hide ? distance * 2 : distance / 2; + } + + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; -var accordion = $.widget( "ui.accordion", { - version: "1.11.4", + element.animate( upAnim, speed, easing ); + } + + element.queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Clip 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Clip Effect +//>>group: Effects +//>>description: Clips the element on and off like an old TV. +//>>docs: http://api.jqueryui.com/clip-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { + var start, + animate = {}, + element = $( this ), + direction = options.direction || "vertical", + both = direction === "both", + horizontal = both || direction === "horizontal", + vertical = both || direction === "vertical"; + + start = element.cssClip(); + animate.clip = { + top: vertical ? ( start.bottom - start.top ) / 2 : start.top, + right: horizontal ? ( start.right - start.left ) / 2 : start.right, + bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, + left: horizontal ? ( start.right - start.left ) / 2 : start.left + }; + + $.effects.createPlaceholder( element ); + + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + animate.clip = start; + } + + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + +} ); + + +/*! + * jQuery UI Effects Drop 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Drop Effect +//>>group: Effects +//>>description: Moves an element in one direction and hides it at the same time. +//>>docs: http://api.jqueryui.com/drop-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { + + var distance, + element = $( this ), + mode = options.mode, + show = mode === "show", + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", + oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", + animation = { + opacity: 0 + }; + + $.effects.createPlaceholder( element ); + + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; + + animation[ ref ] = motion + distance; + + if ( show ) { + element.css( animation ); + + animation[ ref ] = oppositeMotion + distance; + animation.opacity = 1; + } + + // Animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Explode 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Explode Effect +//>>group: Effects +// jscs:disable maximumLineLength +//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. +// jscs:enable maximumLineLength +//>>docs: http://api.jqueryui.com/explode-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { + + var i, j, left, top, mx, my, + rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, + cells = rows, + element = $( this ), + mode = options.mode, + show = mode === "show", + + // Show and then visibility:hidden the element before calculating offset + offset = element.show().css( "visibility", "hidden" ).offset(), + + // Width and height of a piece + width = Math.ceil( element.outerWidth() / cells ), + height = Math.ceil( element.outerHeight() / rows ), + pieces = []; + + // Children animate complete: + function childComplete() { + pieces.push( this ); + if ( pieces.length === rows * cells ) { + animComplete(); + } + } + + // Clone the element for each row and cell. + for ( i = 0; i < rows; i++ ) { // ===> + top = offset.top + i * height; + my = i - ( rows - 1 ) / 2; + + for ( j = 0; j < cells; j++ ) { // ||| + left = offset.left + j * width; + mx = j - ( cells - 1 ) / 2; + + // Create a clone of the now hidden main element that will be absolute positioned + // within a wrapper div off the -left and -top equal to size of our pieces + element + .clone() + .appendTo( "body" ) + .wrap( "<div></div>" ) + .css( { + position: "absolute", + visibility: "visible", + left: -j * width, + top: -i * height + } ) + + // Select the wrapper - make it overflow: hidden and absolute positioned based on + // where the original was located +left and +top equal to the size of pieces + .parent() + .addClass( "ui-effects-explode" ) + .css( { + position: "absolute", + overflow: "hidden", + width: width, + height: height, + left: left + ( show ? mx * width : 0 ), + top: top + ( show ? my * height : 0 ), + opacity: show ? 0 : 1 + } ) + .animate( { + left: left + ( show ? 0 : mx * width ), + top: top + ( show ? 0 : my * height ), + opacity: show ? 1 : 0 + }, options.duration || 500, options.easing, childComplete ); + } + } + + function animComplete() { + element.css( { + visibility: "visible" + } ); + $( pieces ).remove(); + done(); + } +} ); + + +/*! + * jQuery UI Effects Fade 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Fade Effect +//>>group: Effects +//>>description: Fades the element. +//>>docs: http://api.jqueryui.com/fade-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { + var show = options.mode === "show"; + + $( this ) + .css( "opacity", show ? 0 : 1 ) + .animate( { + opacity: show ? 1 : 0 + }, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Fold 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Fold Effect +//>>group: Effects +//>>description: Folds an element first horizontally and then vertically. +//>>docs: http://api.jqueryui.com/fold-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { + + // Create element + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + size = options.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!options.horizFirst, + ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], + duration = options.duration / 2, + + placeholder = $.effects.createPlaceholder( element ), + + start = element.cssClip(), + animation1 = { clip: $.extend( {}, start ) }, + animation2 = { clip: $.extend( {}, start ) }, + + distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], + + queuelen = element.queue().length; + + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + animation1.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 1 ] ] = 0; + + if ( show ) { + element.cssClip( animation2.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animation2 ) ); + } + + animation2.clip = start; + } + + // Animate + element + .queue( function( next ) { + if ( placeholder ) { + placeholder + .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) + .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); + } + + next(); + } ) + .animate( animation1, duration, options.easing ) + .animate( animation2, duration, options.easing ) + .queue( done ); + + $.effects.unshift( element, queuelen, 4 ); +} ); + + +/*! + * jQuery UI Effects Highlight 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Highlight Effect +//>>group: Effects +//>>description: Highlights the background of an element in a defined color for a custom duration. +//>>docs: http://api.jqueryui.com/highlight-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { + var element = $( this ), + animation = { + backgroundColor: element.css( "backgroundColor" ) + }; + + if ( options.mode === "hide" ) { + animation.opacity = 0; + } + + $.effects.saveStyle( element ); + + element + .css( { + backgroundImage: "none", + backgroundColor: options.color || "#ffff99" + } ) + .animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Size 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Size Effect +//>>group: Effects +//>>description: Resize an element to a specified width and height. +//>>docs: http://api.jqueryui.com/size-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectSize = $.effects.define( "size", function( options, done ) { + + // Create element + var baseline, factor, temp, + element = $( this ), + + // Copy for children + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + + // Set options + mode = options.mode, + restore = mode !== "effect", + scale = options.scale || "both", + origin = options.origin || [ "middle", "center" ], + position = element.css( "position" ), + pos = element.position(), + original = $.effects.scaledDimensions( element ), + from = options.from || original, + to = options.to || $.effects.scaledDimensions( element, 0 ); + + $.effects.createPlaceholder( element ); + + if ( mode === "show" ) { + temp = from; + from = to; + to = temp; + } + + // Set scaling factor + factor = { + from: { + y: from.height / original.height, + x: from.width / original.width + }, + to: { + y: to.height / original.height, + x: to.width / original.width + } + }; + + // Scale the css box + if ( scale === "box" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, vProps, factor.from.y, from ); + to = $.effects.setTransition( element, vProps, factor.to.y, to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + from = $.effects.setTransition( element, hProps, factor.from.x, from ); + to = $.effects.setTransition( element, hProps, factor.to.x, to ); + } + } + + // Scale the content + if ( scale === "content" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, cProps, factor.from.y, from ); + to = $.effects.setTransition( element, cProps, factor.to.y, to ); + } + } + + // Adjust the position properties based on the provided origin points + if ( origin ) { + baseline = $.effects.getBaseline( origin, original ); + from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; + from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; + to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; + to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; + } + element.css( from ); + + // Animate the children if desired + if ( scale === "content" || scale === "both" ) { + + vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); + hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); + + // Only animate children with width attributes specified + // TODO: is this right? should we include anything with css width specified as well + element.find( "*[width]" ).each( function() { + var child = $( this ), + childOriginal = $.effects.scaledDimensions( child ), + childFrom = { + height: childOriginal.height * factor.from.y, + width: childOriginal.width * factor.from.x, + outerHeight: childOriginal.outerHeight * factor.from.y, + outerWidth: childOriginal.outerWidth * factor.from.x + }, + childTo = { + height: childOriginal.height * factor.to.y, + width: childOriginal.width * factor.to.x, + outerHeight: childOriginal.height * factor.to.y, + outerWidth: childOriginal.width * factor.to.x + }; + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); + childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); + childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); + } + + if ( restore ) { + $.effects.saveStyle( child ); + } + + // Animate children + child.css( childFrom ); + child.animate( childTo, options.duration, options.easing, function() { + + // Restore children + if ( restore ) { + $.effects.restoreStyle( child ); + } + } ); + } ); + } + + // Animate + element.animate( to, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: function() { + + var offset = element.offset(); + + if ( to.opacity === 0 ) { + element.css( "opacity", from.opacity ); + } + + if ( !restore ) { + element + .css( "position", position === "static" ? "relative" : position ) + .offset( offset ); + + // Need to save style here so that automatic style restoration + // doesn't restore to the original styles from before the animation. + $.effects.saveStyle( element ); + } + + done(); + } + } ); + +} ); + + +/*! + * jQuery UI Effects Scale 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Scale Effect +//>>group: Effects +//>>description: Grows or shrinks an element and its content. +//>>docs: http://api.jqueryui.com/scale-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectScale = $.effects.define( "scale", function( options, done ) { + + // Create element + var el = $( this ), + mode = options.mode, + percent = parseInt( options.percent, 10 ) || + ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), + + newOptions = $.extend( true, { + from: $.effects.scaledDimensions( el ), + to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), + origin: options.origin || [ "middle", "center" ] + }, options ); + + // Fade option to support puff + if ( options.fade ) { + newOptions.from.opacity = 1; + newOptions.to.opacity = 0; + } + + $.effects.effect.size.call( this, newOptions, done ); +} ); + + +/*! + * jQuery UI Effects Puff 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Puff Effect +//>>group: Effects +//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. +//>>docs: http://api.jqueryui.com/puff-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { + var newOptions = $.extend( true, {}, options, { + fade: true, + percent: parseInt( options.percent, 10 ) || 150 + } ); + + $.effects.effect.scale.call( this, newOptions, done ); +} ); + + +/*! + * jQuery UI Effects Pulsate 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Pulsate Effect +//>>group: Effects +//>>description: Pulsates an element n times by changing the opacity to zero and back. +//>>docs: http://api.jqueryui.com/pulsate-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + showhide = show || hide, + + // Showing or hiding leaves off the "last" animation + anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = options.duration / anims, + animateTo = 0, + i = 1, + queuelen = element.queue().length; + + if ( show || !element.is( ":visible" ) ) { + element.css( "opacity", 0 ).show(); + animateTo = 1; + } + + // Anims - 1 opacity "toggles" + for ( ; i < anims; i++ ) { + element.animate( { opacity: animateTo }, duration, options.easing ); + animateTo = 1 - animateTo; + } + + element.animate( { opacity: animateTo }, duration, options.easing ); + + element.queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Shake 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Shake Effect +//>>group: Effects +//>>description: Shakes an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/shake-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectShake = $.effects.define( "shake", function( options, done ) { + + var i = 1, + element = $( this ), + direction = options.direction || "left", + distance = options.distance || 20, + times = options.times || 3, + anims = times * 2 + 1, + speed = Math.round( options.duration / anims ), + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + animation = {}, + animation1 = {}, + animation2 = {}, + + queuelen = element.queue().length; + + $.effects.createPlaceholder( element ); + + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + + // Animate + element.animate( animation, speed, options.easing ); + + // Shakes + for ( ; i < times; i++ ) { + element + .animate( animation1, speed, options.easing ) + .animate( animation2, speed, options.easing ); + } + + element + .animate( animation1, speed, options.easing ) + .animate( animation, speed / 2, options.easing ) + .queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Slide 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Slide Effect +//>>group: Effects +//>>description: Slides an element in and out of the viewport. +//>>docs: http://api.jqueryui.com/slide-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { + var startClip, startRef, + element = $( this ), + map = { + up: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + right: [ "left", "right" ] + }, + mode = options.mode, + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), + animation = {}; + + $.effects.createPlaceholder( element ); + + startClip = element.cssClip(); + startRef = element.position()[ ref ]; + + // Define hide animation + animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; + animation.clip = element.cssClip(); + animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; + + // Reverse the animation if we're showing + if ( mode === "show" ) { + element.cssClip( animation.clip ); + element.css( ref, animation[ ref ] ); + animation.clip = startClip; + animation[ ref ] = startRef; + } + + // Actually animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Transfer 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Transfer Effect +//>>group: Effects +//>>description: Displays a transfer effect from one element to another. +//>>docs: http://api.jqueryui.com/transfer-effect/ +//>>demos: http://jqueryui.com/effect/ + + + +var effect; +if ( $.uiBackCompat !== false ) { + effect = $.effects.define( "transfer", function( options, done ) { + $( this ).transfer( options, done ); + } ); +} +var effectsEffectTransfer = effect; + + +/*! + * jQuery UI Focusable 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :focusable Selector +//>>group: Core +//>>description: Selects elements which can be focused. +//>>docs: http://api.jqueryui.com/focusable-selector/ + + + +// Selectors +$.ui.focusable = function( element, hasTabindex ) { + var map, mapName, img, focusableIfVisible, fieldset, + nodeName = element.nodeName.toLowerCase(); + + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" ); + return img.length > 0 && img.is( ":visible" ); + } + + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { + focusableIfVisible = !element.disabled; + + if ( focusableIfVisible ) { + + // Form controls within a disabled fieldset are disabled. + // However, controls within the fieldset's legend do not get disabled. + // Since controls generally aren't placed inside legends, we skip + // this portion of the check. + fieldset = $( element ).closest( "fieldset" )[ 0 ]; + if ( fieldset ) { + focusableIfVisible = !fieldset.disabled; + } + } + } else if ( "a" === nodeName ) { + focusableIfVisible = element.href || hasTabindex; + } else { + focusableIfVisible = hasTabindex; + } + + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); +}; + +// Support: IE 8 only +// IE 8 doesn't resolve inherit to visible/hidden for computed values +function visible( element ) { + var visibility = element.css( "visibility" ); + while ( visibility === "inherit" ) { + element = element.parent(); + visibility = element.css( "visibility" ); + } + return visibility !== "hidden"; +} + +$.extend( $.expr[ ":" ], { + focusable: function( element ) { + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); + } +} ); + +var focusable = $.ui.focusable; + + + + +// Support: IE8 Only +// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop +// with a string, so we need to find the proper form. +var form = $.fn.form = function() { + return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); +}; + + +/*! + * jQuery UI Form Reset Mixin 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Form Reset Mixin +//>>group: Core +//>>description: Refresh input widgets when their form is reset +//>>docs: http://api.jqueryui.com/form-reset-mixin/ + + + +var formResetMixin = $.ui.formResetMixin = { + _formResetHandler: function() { + var form = $( this ); + + // Wait for the form reset to actually happen before refreshing + setTimeout( function() { + var instances = form.data( "ui-form-reset-instances" ); + $.each( instances, function() { + this.refresh(); + } ); + } ); + }, + + _bindFormResetHandler: function() { + this.form = this.element.form(); + if ( !this.form.length ) { + return; + } + + var instances = this.form.data( "ui-form-reset-instances" ) || []; + if ( !instances.length ) { + + // We don't use _on() here because we use a single event handler per form + this.form.on( "reset.ui-form-reset", this._formResetHandler ); + } + instances.push( this ); + this.form.data( "ui-form-reset-instances", instances ); + }, + + _unbindFormResetHandler: function() { + if ( !this.form.length ) { + return; + } + + var instances = this.form.data( "ui-form-reset-instances" ); + instances.splice( $.inArray( this, instances ), 1 ); + if ( instances.length ) { + this.form.data( "ui-form-reset-instances", instances ); + } else { + this.form + .removeData( "ui-form-reset-instances" ) + .off( "reset.ui-form-reset" ); + } + } +}; + + +/*! + * jQuery UI Support for jQuery core 1.7.x 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + */ + +//>>label: jQuery 1.7 Support +//>>group: Core +//>>description: Support version 1.7.x of jQuery core + + + +// Support: jQuery 1.7 only +// Not a great way to check versions, but since we only support 1.7+ and only +// need to detect <1.8, this is a simple check that should suffice. Checking +// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0 +// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting +// 1.7 anymore). See #11197 for why we're not using feature detection. +if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) { + + // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight() + // Unlike jQuery Core 1.8+, these only support numeric values to set the + // dimensions in pixels + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + } ); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each( function() { + $( this ).css( type, reduce( this, size ) + "px" ); + } ); + }; + + $.fn[ "outer" + name ] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each( function() { + $( this ).css( type, reduce( this, size, true, margin ) + "px" ); + } ); + }; + } ); + + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +; +/*! + * jQuery UI Keycode 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Keycode +//>>group: Core +//>>description: Provide keycodes as keynames +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + + +var keycode = $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 +}; + + + + +// Internal use only +var escapeSelector = $.ui.escapeSelector = ( function() { + var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; + return function( selector ) { + return selector.replace( selectorEscape, "\\$1" ); + }; +} )(); + + +/*! + * jQuery UI Labels 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: labels +//>>group: Core +//>>description: Find all the labels associated with a given input +//>>docs: http://api.jqueryui.com/labels/ + + + +var labels = $.fn.labels = function() { + var ancestor, selector, id, labels, ancestors; + + // Check control.labels first + if ( this[ 0 ].labels && this[ 0 ].labels.length ) { + return this.pushStack( this[ 0 ].labels ); + } + + // Support: IE <= 11, FF <= 37, Android <= 2.3 only + // Above browsers do not support control.labels. Everything below is to support them + // as well as document fragments. control.labels does not work on document fragments + labels = this.eq( 0 ).parents( "label" ); + + // Look for the label based on the id + id = this.attr( "id" ); + if ( id ) { + + // We don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.eq( 0 ).parents().last(); + + // Get a full set of top level ancestors + ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); + + // Create a selector for the label based on the id + selector = "label[for='" + $.ui.escapeSelector( id ) + "']"; + + labels = labels.add( ancestors.find( selector ).addBack( selector ) ); + + } + + // Return whatever we have found for labels + return this.pushStack( labels ); +}; + + +/*! + * jQuery UI Scroll Parent 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: scrollParent +//>>group: Core +//>>description: Get the closest ancestor element that is scrollable. +//>>docs: http://api.jqueryui.com/scrollParent/ + + + +var scrollParent = $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; +}; + + +/*! + * jQuery UI Tabbable 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :tabbable Selector +//>>group: Core +//>>description: Selects elements which can be tabbed to. +//>>docs: http://api.jqueryui.com/tabbable-selector/ + + + +var tabbable = $.extend( $.expr[ ":" ], { + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + hasTabindex = tabIndex != null; + return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); + } +} ); + + +/*! + * jQuery UI Unique ID 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: uniqueId +//>>group: Core +//>>description: Functions to generate and remove uniqueId's +//>>docs: http://api.jqueryui.com/uniqueId/ + + + +var uniqueId = $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; + + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), + + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } +} ); + + +/*! + * jQuery UI Accordion 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Accordion +//>>group: Widgets +// jscs:disable maximumLineLength +//>>description: Displays collapsible content panels for presenting information in a limited amount of space. +// jscs:enable maximumLineLength +//>>docs: http://api.jqueryui.com/accordion/ +//>>demos: http://jqueryui.com/accordion/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/accordion.css +//>>css.theme: ../../themes/base/theme.css + + + +var widgetsAccordion = $.widget( "ui.accordion", { + version: "1.12.1", options: { active: 0, animate: {}, + classes: { + "ui-accordion-header": "ui-corner-top", + "ui-accordion-header-collapsed": "ui-corner-all", + "ui-accordion-content": "ui-corner-bottom" + }, collapsible: false, event: "click", - header: "> li > :first-child,> :not(li):even", + header: "> li > :first-child, > :not(li):even", heightStyle: "auto", icons: { activeHeader: "ui-icon-triangle-1-s", header: "ui-icon-triangle-1-e" }, - // callbacks + // Callbacks activate: null, beforeActivate: null }, @@ -1598,17 +4357,18 @@ var accordion = $.widget( "ui.accordion", { _create: function() { var options = this.options; + this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) - // ARIA - .attr( "role", "tablist" ); + this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); + this.element.attr( "role", "tablist" ); - // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { + // Don't allow collapsible: false and active: false / null + if ( !options.collapsible && ( options.active === false || options.active == null ) ) { options.active = 0; } this._processPanels(); + // handle negative values if ( options.active < 0 ) { options.active += this.headers.length; @@ -1624,54 +4384,42 @@ var accordion = $.widget( "ui.accordion", { }, _createIcons: function() { - var icons = this.options.icons; + var icon, children, + icons = this.options.icons; + if ( icons ) { - $( "<span>" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); + icon = $( "<span>" ); + this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); + icon.prependTo( this.headers ); + children = this.active.children( ".ui-accordion-header-icon" ); + this._removeClass( children, icons.header ) + ._addClass( children, null, icons.activeHeader ) + ._addClass( this.headers, "ui-accordion-icons" ); } }, _destroyIcons: function() { - this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) - .remove(); + this._removeClass( this.headers, "ui-accordion-icons" ); + this.headers.children( ".ui-accordion-header-icon" ).remove(); }, _destroy: function() { var contents; - // clean up main element - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); + // Clean up main element + this.element.removeAttr( "role" ); - // clean up headers + // Clean up headers this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + - "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) + .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) .removeUniqueId(); this._destroyIcons(); - // clean up content panels + // Clean up content panels contents = this.headers.next() - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + - "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) + .removeAttr( "role aria-hidden aria-labelledby" ) .removeUniqueId(); if ( this.options.heightStyle !== "content" ) { @@ -1681,6 +4429,7 @@ var accordion = $.widget( "ui.accordion", { _setOption: function( key, value ) { if ( key === "active" ) { + // _activate() will handle invalid values and update this.options this._activate( value ); return; @@ -1695,7 +4444,7 @@ var accordion = $.widget( "ui.accordion", { this._super( key, value ); - // setting collapsible: false while collapsed; open first panel + // Setting collapsible: false while collapsed; open first panel if ( key === "collapsible" && !value && this.options.active === false ) { this._activate( 0 ); } @@ -1706,16 +4455,19 @@ var accordion = $.widget( "ui.accordion", { this._createIcons(); } } + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", value ); - // #5332 - opacity doesn't cascade to positioned elements in IE + // Support: IE8 Only + // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.element - .toggleClass( "ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); - } + this._toggleClass( null, "ui-state-disabled", !!value ); + this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", + !!value ); }, _keydown: function( event ) { @@ -1729,37 +4481,37 @@ var accordion = $.widget( "ui.accordion", { toFocus = false; switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; } if ( toFocus ) { $( event.target ).attr( "tabIndex", -1 ); $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); + $( toFocus ).trigger( "focus" ); event.preventDefault(); } }, _panelKeyDown: function( event ) { if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); + $( event.currentTarget ).prev().trigger( "focus" ); } }, @@ -1767,25 +4519,32 @@ var accordion = $.widget( "ui.accordion", { var options = this.options; this._processPanels(); - // was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { + // Was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || + !this.headers.length ) { options.active = false; this.active = $(); + // active false only when collapsible is true } else if ( options.active === false ) { this._activate( 0 ); + // was active, but active panel is gone } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + // all remaining panel are disabled - if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { + if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { options.active = false; this.active = $(); + // activate previous panel } else { this._activate( Math.max( 0, options.active - 1 ) ); } + // was active, active panel still exists } else { + // make sure active index is correct options.active = this.headers.index( this.active ); } @@ -1799,13 +4558,12 @@ var accordion = $.widget( "ui.accordion", { var prevHeaders = this.headers, prevPanels = this.panels; - this.headers = this.element.find( this.options.header ) - .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); + this.headers = this.element.find( this.options.header ); + this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", + "ui-state-default" ); - this.panels = this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) - .filter( ":not(.ui-accordion-content-active)" ) - .hide(); + this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); + this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); // Avoid memory leaks (#10056) if ( prevPanels ) { @@ -1820,52 +4578,51 @@ var accordion = $.widget( "ui.accordion", { heightStyle = options.heightStyle, parent = this.element.parent(); - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) - .removeClass( "ui-corner-all" ); - this.active.next() - .addClass( "ui-accordion-content-active" ) - .show(); + this.active = this._findActive( options.active ); + this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) + ._removeClass( this.active, "ui-accordion-header-collapsed" ); + this._addClass( this.active.next(), "ui-accordion-content-active" ); + this.active.next().show(); this.headers .attr( "role", "tab" ) - .each(function() { + .each( function() { var header = $( this ), headerId = header.uniqueId().attr( "id" ), panel = header.next(), panelId = panel.uniqueId().attr( "id" ); header.attr( "aria-controls", panelId ); panel.attr( "aria-labelledby", headerId ); - }) + } ) .next() .attr( "role", "tabpanel" ); this.headers .not( this.active ) - .attr({ - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - }) - .next() - .attr({ - "aria-hidden": "true" - }) - .hide(); + .attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ) + .next() + .attr( { + "aria-hidden": "true" + } ) + .hide(); - // make sure at least one header is in the tab order + // Make sure at least one header is in the tab order if ( !this.active.length ) { this.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { - this.active.attr({ + this.active.attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 - }) - .next() - .attr({ - "aria-hidden": "false" - }); + } ) + .next() + .attr( { + "aria-hidden": "false" + } ); } this._createIcons(); @@ -1874,7 +4631,7 @@ var accordion = $.widget( "ui.accordion", { if ( heightStyle === "fill" ) { maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { + this.element.siblings( ":visible" ).each( function() { var elem = $( this ), position = elem.css( "position" ); @@ -1882,24 +4639,31 @@ var accordion = $.widget( "ui.accordion", { return; } maxHeight -= elem.outerHeight( true ); - }); + } ); - this.headers.each(function() { + this.headers.each( function() { maxHeight -= $( this ).outerHeight( true ); - }); + } ); this.headers.next() - .each(function() { + .each( function() { $( this ).height( Math.max( 0, maxHeight - $( this ).innerHeight() + $( this ).height() ) ); - }) + } ) .css( "overflow", "auto" ); } else if ( heightStyle === "auto" ) { maxHeight = 0; this.headers.next() - .each(function() { + .each( function() { + var isVisible = $( this ).is( ":visible" ); + if ( !isVisible ) { + $( this ).show(); + } maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - }) + if ( !isVisible ) { + $( this ).hide(); + } + } ) .height( maxHeight ); } }, @@ -1907,19 +4671,19 @@ var accordion = $.widget( "ui.accordion", { _activate: function( index ) { var active = this._findActive( index )[ 0 ]; - // trying to activate the already active panel + // Trying to activate the already active panel if ( active === this.active[ 0 ] ) { return; } - // trying to collapse, simulate a click on the currently active header + // Trying to collapse, simulate a click on the currently active header active = active || this.active[ 0 ]; - this._eventHandler({ + this._eventHandler( { target: active, currentTarget: active, preventDefault: $.noop - }); + } ); }, _findActive: function( selector ) { @@ -1933,18 +4697,19 @@ var accordion = $.widget( "ui.accordion", { if ( event ) { $.each( event.split( " " ), function( index, eventName ) { events[ eventName ] = "_eventHandler"; - }); + } ); } this._off( this.headers.add( this.headers.next() ) ); this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); this._hoverable( this.headers ); this._focusable( this.headers ); }, _eventHandler: function( event ) { - var options = this.options, + var activeChildren, clickedChildren, + options = this.options, active = this.active, clicked = $( event.currentTarget ), clickedIsActive = clicked[ 0 ] === active[ 0 ], @@ -1961,8 +4726,10 @@ var accordion = $.widget( "ui.accordion", { event.preventDefault(); if ( + // click on active header, but not collapsible ( clickedIsActive && !options.collapsible ) || + // allow canceling activation ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { return; @@ -1970,33 +4737,30 @@ var accordion = $.widget( "ui.accordion", { options.active = collapsing ? false : this.headers.index( clicked ); - // when the call to ._toggle() comes after the class changes + // When the call to ._toggle() comes after the class changes // it causes a very odd bug in IE 8 (see #6720) this.active = clickedIsActive ? $() : clicked; this._toggle( eventData ); - // switch classes + // Switch classes // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); + this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); + activeChildren = active.children( ".ui-accordion-header-icon" ); + this._removeClass( activeChildren, null, options.icons.activeHeader ) + ._addClass( activeChildren, null, options.icons.header ); } if ( !clickedIsActive ) { - clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + this._removeClass( clicked, "ui-accordion-header-collapsed" ) + ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); + clickedChildren = clicked.children( ".ui-accordion-header-icon" ); + this._removeClass( clickedChildren, null, options.icons.header ) + ._addClass( clickedChildren, null, options.icons.activeHeader ); } - clicked - .next() - .addClass( "ui-accordion-content-active" ); + this._addClass( clicked.next(), "ui-accordion-content-active" ); } }, @@ -2004,7 +4768,7 @@ var accordion = $.widget( "ui.accordion", { var toShow = data.newPanel, toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - // handle activating a panel during the animation for another activation + // Handle activating a panel during the animation for another activation this.prevShow.add( this.prevHide ).stop( true, true ); this.prevShow = toShow; this.prevHide = toHide; @@ -2017,36 +4781,37 @@ var accordion = $.widget( "ui.accordion", { this._toggleComplete( data ); } - toHide.attr({ + toHide.attr( { "aria-hidden": "true" - }); - toHide.prev().attr({ + } ); + toHide.prev().attr( { "aria-selected": "false", "aria-expanded": "false" - }); + } ); + // if we're switching panels, remove the old header from the tab order // if we're opening from collapsed state, remove the previous header from the tab order // if we're collapsing, then keep the collapsing header in the tab order if ( toShow.length && toHide.length ) { - toHide.prev().attr({ + toHide.prev().attr( { "tabIndex": -1, "aria-expanded": "false" - }); + } ); } else if ( toShow.length ) { - this.headers.filter(function() { + this.headers.filter( function() { return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; - }) - .attr( "tabIndex", -1 ); + } ) + .attr( "tabIndex", -1 ); } toShow .attr( "aria-hidden", "false" ) .prev() - .attr({ + .attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 - }); + } ); }, _animate: function( toShow, toHide, data ) { @@ -2068,6 +4833,7 @@ var accordion = $.widget( "ui.accordion", { if ( typeof options === "string" ) { easing = options; } + // fall back from options to animation in case of partial down settings easing = easing || options.easing || animate.easing; duration = duration || options.duration || animate.duration; @@ -2086,7 +4852,7 @@ var accordion = $.widget( "ui.accordion", { step: function( now, fx ) { fx.now = Math.round( now ); } - }); + } ); toShow .hide() .animate( this.showProps, { @@ -2104,17 +4870,16 @@ var accordion = $.widget( "ui.accordion", { adjust = 0; } } - }); + } ); }, _toggleComplete: function( data ) { - var toHide = data.oldPanel; + var toHide = data.oldPanel, + prev = toHide.prev(); - toHide - .removeClass( "ui-accordion-content-active" ) - .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); + this._removeClass( toHide, "ui-accordion-content-active" ); + this._removeClass( prev, "ui-accordion-header-active" ) + ._addClass( prev, "ui-accordion-header-collapsed" ); // Work around for rendering bug in IE (#5421) if ( toHide.length ) { @@ -2122,38 +4887,76 @@ var accordion = $.widget( "ui.accordion", { } this._trigger( "activate", null, data ); } -}); +} ); + + + +var safeActiveElement = $.ui.safeActiveElement = function( document ) { + var activeElement; + + // Support: IE 9 only + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + activeElement = document.activeElement; + } catch ( error ) { + activeElement = document.body; + } + + // Support: IE 9 - 11 only + // IE may return null instead of an element + // Interestingly, this only seems to occur when NOT in an iframe + if ( !activeElement ) { + activeElement = document.body; + } + + // Support: IE 11 only + // IE11 returns a seemingly empty object in some cases when accessing + // document.activeElement from an <iframe> + if ( !activeElement.nodeName ) { + activeElement = document.body; + } + + return activeElement; +}; /*! - * jQuery UI Menu 1.11.4 + * jQuery UI Menu 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/menu/ */ +//>>label: Menu +//>>group: Widgets +//>>description: Creates nestable menus. +//>>docs: http://api.jqueryui.com/menu/ +//>>demos: http://jqueryui.com/menu/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/menu.css +//>>css.theme: ../../themes/base/theme.css + -var menu = $.widget( "ui.menu", { - version: "1.11.4", + +var widgetsMenu = $.widget( "ui.menu", { + version: "1.12.1", defaultElement: "<ul>", delay: 300, options: { icons: { - submenu: "ui-icon-carat-1-e" + submenu: "ui-icon-caret-1-e" }, items: "> *", menus: "ul", position: { - my: "left-1 top", + my: "left top", at: "right top" }, role: "menu", - // callbacks + // Callbacks blur: null, focus: null, select: null @@ -2167,20 +4970,14 @@ var menu = $.widget( "ui.menu", { this.mouseHandled = false; this.element .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content" ) - .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) - .attr({ + .attr( { role: this.options.role, tabIndex: 0 - }); + } ); - if ( this.options.disabled ) { - this.element - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } + this._addClass( "ui-menu", "ui-widget ui-widget-content" ); + this._on( { - this._on({ // Prevent focus from sticking to links inside menu after clicking // them (focus should always stay on UL during navigation). "mousedown .ui-menu-item": function( event ) { @@ -2188,6 +4985,7 @@ var menu = $.widget( "ui.menu", { }, "click .ui-menu-item": function( event ) { var target = $( event.target ); + var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { this.select( event ); @@ -2199,7 +4997,8 @@ var menu = $.widget( "ui.menu", { // Open submenu on click if ( target.has( ".ui-menu" ).length ) { this.expand( event ); - } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { + } else if ( !this.element.is( ":focus" ) && + active.closest( ".ui-menu" ).length ) { // Redirect focus to the menu this.element.trigger( "focus", [ true ] ); @@ -2213,21 +5012,32 @@ var menu = $.widget( "ui.menu", { } }, "mouseenter .ui-menu-item": function( event ) { + // Ignore mouse events while typeahead is active, see #10458. // Prevents focusing the wrong item when typeahead causes a scroll while the mouse // is over an item in the menu if ( this.previousFilter ) { return; } - var target = $( event.currentTarget ); + + var actualTarget = $( event.target ).closest( ".ui-menu-item" ), + target = $( event.currentTarget ); + + // Ignore bubbled events on parent items, see #11641 + if ( actualTarget[ 0 ] !== target[ 0 ] ) { + return; + } + // Remove ui-state-active class from siblings of the newly focused menu item // to avoid a jump caused by adjacent elements both having a class with a border - target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); + this._removeClass( target.siblings().children( ".ui-state-active" ), + null, "ui-state-active" ); this.focus( event, target ); }, mouseleave: "collapseAll", "mouseleave .ui-menu": "collapseAll", focus: function( event, keepActiveItem ) { + // If there's already an active item, keep it active // If not, activate the first item var item = this.active || this.element.find( this.options.items ).eq( 0 ); @@ -2237,14 +5047,18 @@ var menu = $.widget( "ui.menu", { } }, blur: function( event ) { - this._delay(function() { - if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { + this._delay( function() { + var notContained = !$.contains( + this.element[ 0 ], + $.ui.safeActiveElement( this.document[ 0 ] ) + ); + if ( notContained ) { this.collapseAll( event ); } - }); + } ); }, keydown: "_keydown" - }); + } ); this.refresh(); @@ -2258,43 +5072,31 @@ var menu = $.widget( "ui.menu", { // Reset the mouseHandled flag this.mouseHandled = false; } - }); + } ); }, _destroy: function() { + var items = this.element.find( ".ui-menu-item" ) + .removeAttr( "role aria-disabled" ), + submenus = items.children( ".ui-menu-item-wrapper" ) + .removeUniqueId() + .removeAttr( "tabIndex role aria-haspopup" ); + // Destroy (sub)menus this.element .removeAttr( "aria-activedescendant" ) .find( ".ui-menu" ).addBack() - .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-disabled" ) + .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + + "tabIndex" ) .removeUniqueId() .show(); - // Destroy menu items - this.element.find( ".ui-menu-item" ) - .removeClass( "ui-menu-item" ) - .removeAttr( "role" ) - .removeAttr( "aria-disabled" ) - .removeUniqueId() - .removeClass( "ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-carat" ) ) { - elem.remove(); - } - }); - - // Destroy menu dividers - this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); + submenus.children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-caret" ) ) { + elem.remove(); + } + } ); }, _keydown: function( event ) { @@ -2338,9 +5140,12 @@ var menu = $.widget( "ui.menu", { default: preventDefault = false; prev = this.previousFilter || ""; - character = String.fromCharCode( event.keyCode ); skip = false; + // Support number pad values + character = event.keyCode >= 96 && event.keyCode <= 105 ? + ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); + clearTimeout( this.filterTimer ); if ( character === prev ) { @@ -2364,7 +5169,7 @@ var menu = $.widget( "ui.menu", { if ( match.length ) { this.focus( event, match ); this.previousFilter = character; - this.filterTimer = this._delay(function() { + this.filterTimer = this._delay( function() { delete this.previousFilter; }, 1000 ); } else { @@ -2378,8 +5183,8 @@ var menu = $.widget( "ui.menu", { }, _activate: function( event ) { - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.is( "[aria-haspopup='true']" ) ) { + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "[aria-haspopup='true']" ).length ) { this.expand( event ); } else { this.select( event ); @@ -2388,54 +5193,57 @@ var menu = $.widget( "ui.menu", { }, refresh: function() { - var menus, items, + var menus, items, newSubmenus, newItems, newWrappers, that = this, icon = this.options.icons.submenu, submenus = this.element.find( this.options.menus ); - this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); + this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); // Initialize nested menus - submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) + newSubmenus = submenus.filter( ":not(.ui-menu)" ) .hide() - .attr({ + .attr( { role: this.options.role, "aria-hidden": "true", "aria-expanded": "false" - }) - .each(function() { + } ) + .each( function() { var menu = $( this ), - item = menu.parent(), - submenuCarat = $( "<span>" ) - .addClass( "ui-menu-icon ui-icon " + icon ) - .data( "ui-menu-submenu-carat", true ); + item = menu.prev(), + submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); + that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); item .attr( "aria-haspopup", "true" ) - .prepend( submenuCarat ); + .prepend( submenuCaret ); menu.attr( "aria-labelledby", item.attr( "id" ) ); - }); + } ); + + this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); menus = submenus.add( this.element ); items = menus.find( this.options.items ); // Initialize menu-items containing spaces and/or dashes only as dividers - items.not( ".ui-menu-item" ).each(function() { + items.not( ".ui-menu-item" ).each( function() { var item = $( this ); if ( that._isDivider( item ) ) { - item.addClass( "ui-widget-content ui-menu-divider" ); + that._addClass( item, "ui-menu-divider", "ui-widget-content" ); } - }); + } ); // Don't refresh list items that are already adapted - items.not( ".ui-menu-item, .ui-menu-divider" ) - .addClass( "ui-menu-item" ) - .uniqueId() - .attr({ - tabIndex: -1, - role: this._itemRole() - }); + newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); + newWrappers = newItems.children() + .not( ".ui-menu" ) + .uniqueId() + .attr( { + tabIndex: -1, + role: this._itemRole() + } ); + this._addClass( newItems, "ui-menu-item" ) + ._addClass( newWrappers, "ui-menu-item-wrapper" ); // Add aria-disabled attribute to any disabled menu item items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); @@ -2455,26 +5263,31 @@ var menu = $.widget( "ui.menu", { _setOption: function( key, value ) { if ( key === "icons" ) { - this.element.find( ".ui-menu-icon" ) - .removeClass( this.options.icons.submenu ) - .addClass( value.submenu ); - } - if ( key === "disabled" ) { - this.element - .toggleClass( "ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); + var icons = this.element.find( ".ui-menu-icon" ); + this._removeClass( icons, null, this.options.icons.submenu ) + ._addClass( icons, null, value.submenu ); } this._super( key, value ); }, + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", String( value ) ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + focus: function( event, item ) { - var nested, focused; + var nested, focused, activeParent; this.blur( event, event && event.type === "focus" ); this._scrollIntoView( item ); this.active = item.first(); - focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); + + focused = this.active.children( ".ui-menu-item-wrapper" ); + this._addClass( focused, null, "ui-state-active" ); + // Only update aria-activedescendant if there's a role // otherwise we assume focus is managed elsewhere if ( this.options.role ) { @@ -2482,22 +5295,23 @@ var menu = $.widget( "ui.menu", { } // Highlight active parent menu item, if any - this.active + activeParent = this.active .parent() - .closest( ".ui-menu-item" ) - .addClass( "ui-state-active" ); + .closest( ".ui-menu-item" ) + .children( ".ui-menu-item-wrapper" ); + this._addClass( activeParent, null, "ui-state-active" ); if ( event && event.type === "keydown" ) { this._close(); } else { - this.timer = this._delay(function() { + this.timer = this._delay( function() { this._close(); }, this.delay ); } nested = item.children( ".ui-menu" ); if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { - this._startOpening(nested); + this._startOpening( nested ); } this.activeMenu = item.parent(); @@ -2507,8 +5321,8 @@ var menu = $.widget( "ui.menu", { _scrollIntoView: function( item ) { var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; + borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; + paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; scroll = this.activeMenu.scrollTop(); elementHeight = this.activeMenu.height(); @@ -2531,29 +5345,30 @@ var menu = $.widget( "ui.menu", { return; } - this.active.removeClass( "ui-state-focus" ); - this.active = null; + this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), + null, "ui-state-active" ); this._trigger( "blur", event, { item: this.active } ); + this.active = null; }, _startOpening: function( submenu ) { clearTimeout( this.timer ); // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the carat icon + // shift in the submenu position when mousing over the caret icon if ( submenu.attr( "aria-hidden" ) !== "true" ) { return; } - this.timer = this._delay(function() { + this.timer = this._delay( function() { this._close(); this._open( submenu ); }, this.delay ); }, _open: function( submenu ) { - var position = $.extend({ + var position = $.extend( { of: this.active }, this.options.position ); @@ -2571,12 +5386,14 @@ var menu = $.widget( "ui.menu", { collapseAll: function( event, all ) { clearTimeout( this.timer ); - this.timer = this._delay(function() { + this.timer = this._delay( function() { + // If we were passed an event, look for the submenu that contains the event var currentMenu = all ? this.element : $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway + // If we found no valid submenu ancestor, use the main menu to close all + // sub menus anyway if ( !currentMenu.length ) { currentMenu = this.element; } @@ -2584,6 +5401,10 @@ var menu = $.widget( "ui.menu", { this._close( currentMenu ); this.blur( event ); + + // Work around active item staying active after menu is blurred + this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); + this.activeMenu = currentMenu; }, this.delay ); }, @@ -2595,14 +5416,10 @@ var menu = $.widget( "ui.menu", { startMenu = this.active ? this.active.parent() : this.element; } - startMenu - .find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( ".ui-state-active" ).not( ".ui-state-focus" ) - .removeClass( "ui-state-active" ); + startMenu.find( ".ui-menu" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); }, _closeOnDocumentClick: function( event ) { @@ -2628,16 +5445,16 @@ var menu = $.widget( "ui.menu", { var newItem = this.active && this.active .children( ".ui-menu " ) - .find( this.options.items ) - .first(); + .find( this.options.items ) + .first(); if ( newItem && newItem.length ) { this._open( newItem.parent() ); // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay(function() { + this._delay( function() { this.focus( event, newItem ); - }); + } ); } }, @@ -2690,10 +5507,10 @@ var menu = $.widget( "ui.menu", { if ( this._hasScroll() ) { base = this.active.offset().top; height = this.element.height(); - this.active.nextAll( ".ui-menu-item" ).each(function() { + this.active.nextAll( ".ui-menu-item" ).each( function() { item = $( this ); return item.offset().top - base - height < 0; - }); + } ); this.focus( event, item ); } else { @@ -2714,10 +5531,10 @@ var menu = $.widget( "ui.menu", { if ( this._hasScroll() ) { base = this.active.offset().top; height = this.element.height(); - this.active.prevAll( ".ui-menu-item" ).each(function() { + this.active.prevAll( ".ui-menu-item" ).each( function() { item = $( this ); return item.offset().top - base + height > 0; - }); + } ); this.focus( event, item ); } else { @@ -2730,6 +5547,7 @@ var menu = $.widget( "ui.menu", { }, select: function( event ) { + // TODO: It should never be possible to not have an active item at this // point, but the tests don't trigger mouseenter before click. this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); @@ -2740,36 +5558,45 @@ var menu = $.widget( "ui.menu", { this._trigger( "select", event, ui ); }, - _filterMenuItems: function(character) { + _filterMenuItems: function( character ) { var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), regex = new RegExp( "^" + escapedCharacter, "i" ); return this.activeMenu .find( this.options.items ) - // Only match on items, not dividers or other content (#10571) - .filter( ".ui-menu-item" ) - .filter(function() { - return regex.test( $.trim( $( this ).text() ) ); - }); + // Only match on items, not dividers or other content (#10571) + .filter( ".ui-menu-item" ) + .filter( function() { + return regex.test( + $.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); + } ); } -}); +} ); /*! - * jQuery UI Autocomplete 1.11.4 + * jQuery UI Autocomplete 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/autocomplete/ */ +//>>label: Autocomplete +//>>group: Widgets +//>>description: Lists suggested words as the user is typing. +//>>docs: http://api.jqueryui.com/autocomplete/ +//>>demos: http://jqueryui.com/autocomplete/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/autocomplete.css +//>>css.theme: ../../themes/base/theme.css + + $.widget( "ui.autocomplete", { - version: "1.11.4", + version: "1.12.1", defaultElement: "<input>", options: { appendTo: null, @@ -2783,7 +5610,7 @@ $.widget( "ui.autocomplete", { }, source: null, - // callbacks + // Callbacks change: null, close: null, focus: null, @@ -2797,6 +5624,7 @@ $.widget( "ui.autocomplete", { pending: 0, _create: function() { + // Some browsers only repeat keydown events, not keypress events, // so we use the suppressKeyPress flag to determine if we've already // handled the keydown event. #7269 @@ -2809,21 +5637,17 @@ $.widget( "ui.autocomplete", { isTextarea = nodeName === "textarea", isInput = nodeName === "input"; - this.isMultiLine = - // Textareas are always multi-line - isTextarea ? true : - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - isInput ? false : - // All other element types are determined by whether or not they're contentEditable - this.element.prop( "isContentEditable" ); + // Textareas are always multi-line + // Inputs are always single-line, even if inside a contentEditable element + // IE also treats inputs as contentEditable + // All other element types are determined by whether or not they're contentEditable + this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; this.isNewMenu = true; - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); + this._addClass( "ui-autocomplete-input" ); + this.element.attr( "autocomplete", "off" ); this._on( this.element, { keydown: function( event ) { @@ -2856,8 +5680,10 @@ $.widget( "ui.autocomplete", { this._keyEvent( "next", event ); break; case keyCode.ENTER: + // when menu is open and has focus if ( this.menu.active ) { + // #6055 - Opera still allows the keypress to occur // which causes forms to submit suppressKeyPress = true; @@ -2876,6 +5702,7 @@ $.widget( "ui.autocomplete", { this._value( this.term ); } this.close( event ); + // Different browsers have different default behavior for escape // Single press can mean undo or clear // Double press in IE means clear the whole form @@ -2884,6 +5711,7 @@ $.widget( "ui.autocomplete", { break; default: suppressKeyPressRepeat = true; + // search timeout should be triggered before the input value is changed this._searchTimeout( event ); break; @@ -2901,7 +5729,7 @@ $.widget( "ui.autocomplete", { return; } - // replicate some key handlers to allow them to repeat in Firefox and Opera + // Replicate some key handlers to allow them to repeat in Firefox and Opera var keyCode = $.ui.keyCode; switch ( event.keyCode ) { case keyCode.PAGE_UP: @@ -2940,51 +5768,46 @@ $.widget( "ui.autocomplete", { this.close( event ); this._change( event ); } - }); + } ); this._initSource(); this.menu = $( "<ul>" ) - .addClass( "ui-autocomplete ui-front" ) .appendTo( this._appendTo() ) - .menu({ + .menu( { + // disable ARIA support, the live region takes care of that role: null - }) + } ) .hide() .menu( "instance" ); + this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); this._on( this.menu.element, { mousedown: function( event ) { + // prevent moving focus out of the text field event.preventDefault(); // IE doesn't prevent moving focus even with event.preventDefault() // so we set a flag to know when we should ignore the blur event this.cancelBlur = true; - this._delay(function() { + this._delay( function() { delete this.cancelBlur; - }); - - // clicking on the scrollbar causes focus to shift to the body - // but we can't detect a mouseup or a click immediately afterward - // so we have to track the next mousedown and close the menu if - // the user clicks somewhere outside of the autocomplete - var menuElement = this.menu.element[ 0 ]; - if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { - this._delay(function() { - var that = this; - this.document.one( "mousedown", function( event ) { - if ( event.target !== that.element[ 0 ] && - event.target !== menuElement && - !$.contains( menuElement, event.target ) ) { - that.close(); - } - }); - }); - } + + // Support: IE 8 only + // Right clicking a menu item or selecting text from the menu items will + // result in focus moving out of the input. However, we've already received + // and ignored the blur event because of the cancelBlur flag set above. So + // we restore focus to ensure that the menu closes properly based on the user's + // next actions. + if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { + this.element.trigger( "focus" ); + } + } ); }, menufocus: function( event, ui ) { var label, item; + // support: Firefox // Prevent accidental activation of menu items in Firefox (#7024 #9118) if ( this.isNewMenu ) { @@ -2994,7 +5817,7 @@ $.widget( "ui.autocomplete", { this.document.one( "mousemove", function() { $( event.target ).trigger( event.originalEvent ); - }); + } ); return; } @@ -3002,6 +5825,7 @@ $.widget( "ui.autocomplete", { item = ui.item.data( "ui-autocomplete-item" ); if ( false !== this._trigger( "focus", event, { item: item } ) ) { + // use value to match what will end up in the input, if it was a key event if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { this._value( item.value ); @@ -3019,22 +5843,24 @@ $.widget( "ui.autocomplete", { var item = ui.item.data( "ui-autocomplete-item" ), previous = this.previous; - // only trigger when focus was lost (click on menu) - if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { - this.element.focus(); + // Only trigger when focus was lost (click on menu) + if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { + this.element.trigger( "focus" ); this.previous = previous; + // #6109 - IE triggers two focus events and the second // is asynchronous, so we need to reset the previous // term synchronously and asynchronously :-( - this._delay(function() { + this._delay( function() { this.previous = previous; this.selectedItem = item; - }); + } ); } if ( false !== this._trigger( "select", event, { item: item } ) ) { this._value( item.value ); } + // reset the term after the select event // this allows custom select handling to work properly this.term = this._value(); @@ -3042,31 +5868,30 @@ $.widget( "ui.autocomplete", { this.close( event ); this.selectedItem = item; } - }); + } ); - this.liveRegion = $( "<span>", { - role: "status", - "aria-live": "assertive", - "aria-relevant": "additions" - }) - .addClass( "ui-helper-hidden-accessible" ) + this.liveRegion = $( "<div>", { + role: "status", + "aria-live": "assertive", + "aria-relevant": "additions" + } ) .appendTo( this.document[ 0 ].body ); - // turning off autocomplete prevents the browser from remembering the + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); + + // Turning off autocomplete prevents the browser from remembering the // value when navigating through history, so we re-enable autocomplete // if the page is unloaded before the widget is destroyed. #7790 this._on( this.window, { beforeunload: function() { this.element.removeAttr( "autocomplete" ); } - }); + } ); }, _destroy: function() { clearTimeout( this.searching ); - this.element - .removeClass( "ui-autocomplete-input" ) - .removeAttr( "autocomplete" ); + this.element.removeAttr( "autocomplete" ); this.menu.element.remove(); this.liveRegion.remove(); }, @@ -3084,6 +5909,20 @@ $.widget( "ui.autocomplete", { } }, + _isEventTargetInWidget: function( event ) { + var menuElement = this.menu.element[ 0 ]; + + return event.target === this.element[ 0 ] || + event.target === menuElement || + $.contains( menuElement, event.target ); + }, + + _closeOnClickOutside: function( event ) { + if ( !this._isEventTargetInWidget( event ) ) { + this.close(); + } + }, + _appendTo: function() { var element = this.options.appendTo; @@ -3094,7 +5933,7 @@ $.widget( "ui.autocomplete", { } if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front" ); + element = this.element.closest( ".ui-front, dialog" ); } if ( !element.length ) { @@ -3118,7 +5957,7 @@ $.widget( "ui.autocomplete", { if ( that.xhr ) { that.xhr.abort(); } - that.xhr = $.ajax({ + that.xhr = $.ajax( { url: url, data: request, dataType: "json", @@ -3126,9 +5965,9 @@ $.widget( "ui.autocomplete", { response( data ); }, error: function() { - response([]); + response( [] ); } - }); + } ); }; } else { this.source = this.options.source; @@ -3137,7 +5976,7 @@ $.widget( "ui.autocomplete", { _searchTimeout: function( event ) { clearTimeout( this.searching ); - this.searching = this._delay(function() { + this.searching = this._delay( function() { // Search if the value has changed, or if the user retypes the same value (see #7434) var equalValues = this.term === this._value(), @@ -3154,7 +5993,7 @@ $.widget( "ui.autocomplete", { search: function( value, event ) { value = value != null ? value : this._value(); - // always save the actual value, not the one passed as an argument + // Always save the actual value, not the one passed as an argument this.term = this._value(); if ( value.length < this.options.minLength ) { @@ -3170,7 +6009,7 @@ $.widget( "ui.autocomplete", { _search: function( value ) { this.pending++; - this.element.addClass( "ui-autocomplete-loading" ); + this._addClass( "ui-autocomplete-loading" ); this.cancelSearch = false; this.source( { term: value }, this._response() ); @@ -3179,14 +6018,14 @@ $.widget( "ui.autocomplete", { _response: function() { var index = ++this.requestIndex; - return $.proxy(function( content ) { + return $.proxy( function( content ) { if ( index === this.requestIndex ) { this.__response( content ); } this.pending--; if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); + this._removeClass( "ui-autocomplete-loading" ); } }, this ); }, @@ -3200,6 +6039,7 @@ $.widget( "ui.autocomplete", { this._suggest( content ); this._trigger( "open" ); } else { + // use ._close() instead of .close() so we don't cancel future searches this._close(); } @@ -3211,6 +6051,10 @@ $.widget( "ui.autocomplete", { }, _close: function( event ) { + + // Remove the handler that closes the menu on outside clicks + this._off( this.document, "mousedown" ); + if ( this.menu.element.is( ":visible" ) ) { this.menu.element.hide(); this.menu.blur(); @@ -3226,6 +6070,7 @@ $.widget( "ui.autocomplete", { }, _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; @@ -3240,8 +6085,8 @@ $.widget( "ui.autocomplete", { return $.extend( {}, item, { label: item.label || item.value, value: item.value || item.label - }); - }); + } ); + } ); }, _suggest: function( items ) { @@ -3250,21 +6095,27 @@ $.widget( "ui.autocomplete", { this.isNewMenu = true; this.menu.refresh(); - // size and position menu + // Size and position menu ul.show(); this._resizeMenu(); - ul.position( $.extend({ + ul.position( $.extend( { of: this.element }, this.options.position ) ); if ( this.options.autoFocus ) { this.menu.next(); } + + // Listen for interactions outside of the widget (#6642) + this._on( this.document, { + mousedown: "_closeOnClickOutside" + } ); }, _resizeMenu: function() { var ul = this.menu.element; ul.outerWidth( Math.max( + // Firefox wraps long text (possibly a rounding bug) // so we add 1px to avoid the wrapping (#7513) ul.width( "" ).outerWidth() + 1, @@ -3276,7 +6127,7 @@ $.widget( "ui.autocomplete", { var that = this; $.each( items, function( index, item ) { that._renderItemData( ul, item ); - }); + } ); }, _renderItemData: function( ul, item ) { @@ -3284,7 +6135,9 @@ $.widget( "ui.autocomplete", { }, _renderItem: function( ul, item ) { - return $( "<li>" ).text( item.label ).appendTo( ul ); + return $( "<li>" ) + .append( $( "<div>" ).text( item.label ) ) + .appendTo( ul ); }, _move: function( direction, event ) { @@ -3317,11 +6170,29 @@ $.widget( "ui.autocomplete", { if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { this._move( keyEvent, event ); - // prevents moving cursor to beginning/end of the text field in some browsers + // Prevents moving cursor to beginning/end of the text field in some browsers event.preventDefault(); } + }, + + // Support: Chrome <=50 + // We should be able to just use this.element.prop( "isContentEditable" ) + // but hidden elements always report false in Chrome. + // https://code.google.com/p/chromium/issues/detail?id=313082 + _isContentEditable: function( element ) { + if ( !element.length ) { + return false; + } + + var editable = element.prop( "contentEditable" ); + + if ( editable === "inherit" ) { + return this._isContentEditable( element.parent() ); + } + + return editable === "true"; } -}); +} ); $.extend( $.ui.autocomplete, { escapeRegex: function( value ) { @@ -3331,11 +6202,11 @@ $.extend( $.ui.autocomplete, { var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); return $.grep( array, function( value ) { return matcher.test( value.label || value.value || value ); - }); + } ); } -}); +} ); -// live region extension, adding a `messages` option +// Live region extension, adding a `messages` option // NOTE: This is an experimental API. We are still investigating // a full solution for string manipulation and internationalization. $.widget( "ui.autocomplete", $.ui.autocomplete, { @@ -3363,432 +6234,968 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { this.liveRegion.children().hide(); $( "<div>" ).text( message ).appendTo( this.liveRegion ); } -}); +} ); -var autocomplete = $.ui.autocomplete; +var widgetsAutocomplete = $.ui.autocomplete; /*! - * jQuery UI Button 1.11.4 + * jQuery UI Controlgroup 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/button/ */ +//>>label: Controlgroup +//>>group: Widgets +//>>description: Visually groups form control widgets +//>>docs: http://api.jqueryui.com/controlgroup/ +//>>demos: http://jqueryui.com/controlgroup/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/controlgroup.css +//>>css.theme: ../../themes/base/theme.css -var lastActive, - baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", - typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", - formResetHandler = function() { - var form = $( this ); - setTimeout(function() { - form.find( ":ui-button" ).button( "refresh" ); - }, 1 ); - }, - radioGroup = function( radio ) { - var name = radio.name, - form = radio.form, - radios = $( [] ); - if ( name ) { - name = name.replace( /'/g, "\\'" ); - if ( form ) { - radios = $( form ).find( "[name='" + name + "'][type=radio]" ); + +var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; + +var widgetsControlgroup = $.widget( "ui.controlgroup", { + version: "1.12.1", + defaultElement: "<div>", + options: { + direction: "horizontal", + disabled: null, + onlyVisible: true, + items: { + "button": "input[type=button], input[type=submit], input[type=reset], button, a", + "controlgroupLabel": ".ui-controlgroup-label", + "checkboxradio": "input[type='checkbox'], input[type='radio']", + "selectmenu": "select", + "spinner": ".ui-spinner-input" + } + }, + + _create: function() { + this._enhance(); + }, + + // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation + _enhance: function() { + this.element.attr( "role", "toolbar" ); + this.refresh(); + }, + + _destroy: function() { + this._callChildMethod( "destroy" ); + this.childWidgets.removeData( "ui-controlgroup-data" ); + this.element.removeAttr( "role" ); + if ( this.options.items.controlgroupLabel ) { + this.element + .find( this.options.items.controlgroupLabel ) + .find( ".ui-controlgroup-label-contents" ) + .contents().unwrap(); + } + }, + + _initWidgets: function() { + var that = this, + childWidgets = []; + + // First we iterate over each of the items options + $.each( this.options.items, function( widget, selector ) { + var labels; + var options = {}; + + // Make sure the widget has a selector set + if ( !selector ) { + return; + } + + if ( widget === "controlgroupLabel" ) { + labels = that.element.find( selector ); + labels.each( function() { + var element = $( this ); + + if ( element.children( ".ui-controlgroup-label-contents" ).length ) { + return; + } + element.contents() + .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); + } ); + that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); + childWidgets = childWidgets.concat( labels.get() ); + return; + } + + // Make sure the widget actually exists + if ( !$.fn[ widget ] ) { + return; + } + + // We assume everything is in the middle to start because we can't determine + // first / last elements until all enhancments are done. + if ( that[ "_" + widget + "Options" ] ) { + options = that[ "_" + widget + "Options" ]( "middle" ); } else { - radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument ) - .filter(function() { - return !this.form; - }); + options = { classes: {} }; } + + // Find instances of this widget inside controlgroup and init them + that.element + .find( selector ) + .each( function() { + var element = $( this ); + var instance = element[ widget ]( "instance" ); + + // We need to clone the default options for this type of widget to avoid + // polluting the variable options which has a wider scope than a single widget. + var instanceOptions = $.widget.extend( {}, options ); + + // If the button is the child of a spinner ignore it + // TODO: Find a more generic solution + if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { + return; + } + + // Create the widget if it doesn't exist + if ( !instance ) { + instance = element[ widget ]()[ widget ]( "instance" ); + } + if ( instance ) { + instanceOptions.classes = + that._resolveClassesValues( instanceOptions.classes, instance ); + } + element[ widget ]( instanceOptions ); + + // Store an instance of the controlgroup to be able to reference + // from the outermost element for changing options and refresh + var widgetElement = element[ widget ]( "widget" ); + $.data( widgetElement[ 0 ], "ui-controlgroup-data", + instance ? instance : element[ widget ]( "instance" ) ); + + childWidgets.push( widgetElement[ 0 ] ); + } ); + } ); + + this.childWidgets = $( $.unique( childWidgets ) ); + this._addClass( this.childWidgets, "ui-controlgroup-item" ); + }, + + _callChildMethod: function( method ) { + this.childWidgets.each( function() { + var element = $( this ), + data = element.data( "ui-controlgroup-data" ); + if ( data && data[ method ] ) { + data[ method ](); + } + } ); + }, + + _updateCornerClass: function( element, position ) { + var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; + var add = this._buildSimpleOptions( position, "label" ).classes.label; + + this._removeClass( element, null, remove ); + this._addClass( element, null, add ); + }, + + _buildSimpleOptions: function( position, key ) { + var direction = this.options.direction === "vertical"; + var result = { + classes: {} + }; + result.classes[ key ] = { + "middle": "", + "first": "ui-corner-" + ( direction ? "top" : "left" ), + "last": "ui-corner-" + ( direction ? "bottom" : "right" ), + "only": "ui-corner-all" + }[ position ]; + + return result; + }, + + _spinnerOptions: function( position ) { + var options = this._buildSimpleOptions( position, "ui-spinner" ); + + options.classes[ "ui-spinner-up" ] = ""; + options.classes[ "ui-spinner-down" ] = ""; + + return options; + }, + + _buttonOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-button" ); + }, + + _checkboxradioOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); + }, + + _selectmenuOptions: function( position ) { + var direction = this.options.direction === "vertical"; + return { + width: direction ? "auto" : false, + classes: { + middle: { + "ui-selectmenu-button-open": "", + "ui-selectmenu-button-closed": "" + }, + first: { + "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) + }, + last: { + "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) + }, + only: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + } + + }[ position ] + }; + }, + + _resolveClassesValues: function( classes, instance ) { + var result = {}; + $.each( classes, function( key ) { + var current = instance.options.classes[ key ] || ""; + current = $.trim( current.replace( controlgroupCornerRegex, "" ) ); + result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); + } ); + return result; + }, + + _setOption: function( key, value ) { + if ( key === "direction" ) { + this._removeClass( "ui-controlgroup-" + this.options.direction ); } - return radios; - }; -$.widget( "ui.button", { - version: "1.11.4", - defaultElement: "<button>", + this._super( key, value ); + if ( key === "disabled" ) { + this._callChildMethod( value ? "disable" : "enable" ); + return; + } + + this.refresh(); + }, + + refresh: function() { + var children, + that = this; + + this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); + + if ( this.options.direction === "horizontal" ) { + this._addClass( null, "ui-helper-clearfix" ); + } + this._initWidgets(); + + children = this.childWidgets; + + // We filter here because we need to track all childWidgets not just the visible ones + if ( this.options.onlyVisible ) { + children = children.filter( ":visible" ); + } + + if ( children.length ) { + + // We do this last because we need to make sure all enhancment is done + // before determining first and last + $.each( [ "first", "last" ], function( index, value ) { + var instance = children[ value ]().data( "ui-controlgroup-data" ); + + if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { + var options = that[ "_" + instance.widgetName + "Options" ]( + children.length === 1 ? "only" : value + ); + options.classes = that._resolveClassesValues( options.classes, instance ); + instance.element[ instance.widgetName ]( options ); + } else { + that._updateCornerClass( children[ value ](), value ); + } + } ); + + // Finally call the refresh method on each of the child widgets. + this._callChildMethod( "refresh" ); + } + } +} ); + +/*! + * jQuery UI Checkboxradio 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Checkboxradio +//>>group: Widgets +//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. +//>>docs: http://api.jqueryui.com/checkboxradio/ +//>>demos: http://jqueryui.com/checkboxradio/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/button.css +//>>css.structure: ../../themes/base/checkboxradio.css +//>>css.theme: ../../themes/base/theme.css + + + +$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { + version: "1.12.1", options: { disabled: null, - text: true, label: null, - icons: { - primary: null, - secondary: null + icon: true, + classes: { + "ui-checkboxradio-label": "ui-corner-all", + "ui-checkboxradio-icon": "ui-corner-all" } }, + + _getCreateOptions: function() { + var disabled, labels; + var that = this; + var options = this._super() || {}; + + // We read the type here, because it makes more sense to throw a element type error first, + // rather then the error for lack of a label. Often if its the wrong type, it + // won't have a label (e.g. calling on a div, btn, etc) + this._readType(); + + labels = this.element.labels(); + + // If there are multiple labels, use the last one + this.label = $( labels[ labels.length - 1 ] ); + if ( !this.label.length ) { + $.error( "No label found for checkboxradio widget" ); + } + + this.originalLabel = ""; + + // We need to get the label text but this may also need to make sure it does not contain the + // input itself. + this.label.contents().not( this.element[ 0 ] ).each( function() { + + // The label contents could be text, html, or a mix. We concat each element to get a + // string representation of the label, without the input as part of it. + that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; + } ); + + // Set the label option if we found label text + if ( this.originalLabel ) { + options.label = this.originalLabel; + } + + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; + } + return options; + }, + _create: function() { - this.element.closest( "form" ) - .unbind( "reset" + this.eventNamespace ) - .bind( "reset" + this.eventNamespace, formResetHandler ); + var checked = this.element[ 0 ].checked; - if ( typeof this.options.disabled !== "boolean" ) { - this.options.disabled = !!this.element.prop( "disabled" ); - } else { - this.element.prop( "disabled", this.options.disabled ); + this._bindFormResetHandler(); + + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled; } - this._determineButtonType(); - this.hasTitle = !!this.buttonElement.attr( "title" ); + this._setOption( "disabled", this.options.disabled ); + this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); + this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); - var that = this, - options = this.options, - toggleButton = this.type === "checkbox" || this.type === "radio", - activeClass = !toggleButton ? "ui-state-active" : ""; + if ( this.type === "radio" ) { + this._addClass( this.label, "ui-checkboxradio-radio-label" ); + } - if ( options.label === null ) { - options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); + if ( this.options.label && this.options.label !== this.originalLabel ) { + this._updateLabel(); + } else if ( this.originalLabel ) { + this.options.label = this.originalLabel; } - this._hoverable( this.buttonElement ); + this._enhance(); - this.buttonElement - .addClass( baseClasses ) - .attr( "role", "button" ) - .bind( "mouseenter" + this.eventNamespace, function() { - if ( options.disabled ) { - return; - } - if ( this === lastActive ) { - $( this ).addClass( "ui-state-active" ); - } - }) - .bind( "mouseleave" + this.eventNamespace, function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( activeClass ); - }) - .bind( "click" + this.eventNamespace, function( event ) { - if ( options.disabled ) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - }); + if ( checked ) { + this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); + if ( this.icon ) { + this._addClass( this.icon, null, "ui-state-hover" ); + } + } - // Can't use _focusable() because the element that receives focus - // and the element that gets the ui-state-focus class are different - this._on({ + this._on( { + change: "_toggleClasses", focus: function() { - this.buttonElement.addClass( "ui-state-focus" ); + this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); }, blur: function() { - this.buttonElement.removeClass( "ui-state-focus" ); + this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); } - }); + } ); + }, - if ( toggleButton ) { - this.element.bind( "change" + this.eventNamespace, function() { - that.refresh(); - }); + _readType: function() { + var nodeName = this.element[ 0 ].nodeName.toLowerCase(); + this.type = this.element[ 0 ].type; + if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { + $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + + " and element.type=" + this.type ); } + }, - if ( this.type === "checkbox" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - }); - } else if ( this.type === "radio" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - that.buttonElement.attr( "aria-pressed", "true" ); - - var radio = that.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" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - lastActive = this; - that.document.one( "mouseup", function() { - lastActive = null; - }); - }) - .bind( "mouseup" + this.eventNamespace, function() { - if ( options.disabled ) { - return false; - } - $( this ).removeClass( "ui-state-active" ); - }) - .bind( "keydown" + this.eventNamespace, function(event) { - if ( options.disabled ) { - return false; - } - if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { - $( this ).addClass( "ui-state-active" ); - } - }) - // see #8559, we bind to blur here in case the button element loses - // focus between keydown and keyup, it would be left in an "active" state - .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, 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(); - } - }); - } - } + // Support jQuery Mobile enhanced option + _enhance: function() { + this._updateIcon( this.element[ 0 ].checked ); + }, - this._setOption( "disabled", options.disabled ); - this._resetButton(); + widget: function() { + return this.label; }, - _determineButtonType: function() { - var ancestor, labelSelector, checked; + _getRadioGroup: function() { + var group; + var name = this.element[ 0 ].name; + var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']"; - if ( this.element.is("[type=checkbox]") ) { - this.type = "checkbox"; - } else if ( this.element.is("[type=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 - ancestor = this.element.parents().last(); - labelSelector = "label[for='" + this.element.attr("id") + "']"; - this.buttonElement = ancestor.find( labelSelector ); - if ( !this.buttonElement.length ) { - ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); - this.buttonElement = ancestor.filter( labelSelector ); - if ( !this.buttonElement.length ) { - this.buttonElement = ancestor.find( labelSelector ); - } - } - this.element.addClass( "ui-helper-hidden-accessible" ); + if ( !name ) { + return $( [] ); + } - checked = this.element.is( ":checked" ); - if ( checked ) { - this.buttonElement.addClass( "ui-state-active" ); - } - this.buttonElement.prop( "aria-pressed", checked ); + if ( this.form.length ) { + group = $( this.form[ 0 ].elements ).filter( nameSelector ); } else { - this.buttonElement = this.element; + + // Not inside a form, check all inputs that also are not inside a form + group = $( nameSelector ).filter( function() { + return $( this ).form().length === 0; + } ); } + + return group.not( this.element ); }, - widget: function() { - return this.buttonElement; + _toggleClasses: function() { + var checked = this.element[ 0 ].checked; + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + + if ( this.options.icon && this.type === "checkbox" ) { + this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) + ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); + } + + if ( this.type === "radio" ) { + this._getRadioGroup() + .each( function() { + var instance = $( this ).checkboxradio( "instance" ); + + if ( instance ) { + instance._removeClass( instance.label, + "ui-checkboxradio-checked", "ui-state-active" ); + } + } ); + } }, _destroy: function() { - this.element - .removeClass( "ui-helper-hidden-accessible" ); - this.buttonElement - .removeClass( baseClasses + " ui-state-active " + typeClasses ) - .removeAttr( "role" ) - .removeAttr( "aria-pressed" ) - .html( this.buttonElement.find(".ui-button-text").html() ); + this._unbindFormResetHandler(); - if ( !this.hasTitle ) { - this.buttonElement.removeAttr( "title" ); + if ( this.icon ) { + this.icon.remove(); + this.iconSpace.remove(); } }, _setOption: function( key, value ) { + + // We don't allow the value to be set to nothing + if ( key === "label" && !value ) { + return; + } + this._super( key, value ); + if ( key === "disabled" ) { - this.widget().toggleClass( "ui-state-disabled", !!value ); - this.element.prop( "disabled", !!value ); - if ( value ) { - if ( this.type === "checkbox" || this.type === "radio" ) { - this.buttonElement.removeClass( "ui-state-focus" ); - } else { - this.buttonElement.removeClass( "ui-state-focus ui-state-active" ); - } - } + this._toggleClass( this.label, null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; + + // Don't refresh when setting disabled return; } - this._resetButton(); + this.refresh(); + }, + + _updateIcon: function( checked ) { + var toAdd = "ui-icon ui-icon-background "; + + if ( this.options.icon ) { + if ( !this.icon ) { + this.icon = $( "<span>" ); + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); + } + + if ( this.type === "checkbox" ) { + toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; + this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); + } else { + toAdd += "ui-icon-blank"; + } + this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); + if ( !checked ) { + this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); + } + this.icon.prependTo( this.label ).after( this.iconSpace ); + } else if ( this.icon !== undefined ) { + this.icon.remove(); + this.iconSpace.remove(); + delete this.icon; + } + }, + + _updateLabel: function() { + + // Remove the contents of the label ( minus the icon, icon space, and input ) + var contents = this.label.contents().not( this.element[ 0 ] ); + if ( this.icon ) { + contents = contents.not( this.icon[ 0 ] ); + } + if ( this.iconSpace ) { + contents = contents.not( this.iconSpace[ 0 ] ); + } + contents.remove(); + + this.label.append( this.options.label ); }, refresh: function() { - //See #8237 & #8828 - var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); + var checked = this.element[ 0 ].checked, + isDisabled = this.element[ 0 ].disabled; + + this._updateIcon( checked ); + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + if ( this.options.label !== null ) { + this._updateLabel(); + } if ( isDisabled !== this.options.disabled ) { - this._setOption( "disabled", isDisabled ); + this._setOptions( { "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" ); - } + } + +} ] ); + +var widgetsCheckboxradio = $.ui.checkboxradio; + + +/*! + * jQuery UI Button 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Button +//>>group: Widgets +//>>description: Enhances a form with themeable buttons. +//>>docs: http://api.jqueryui.com/button/ +//>>demos: http://jqueryui.com/button/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/button.css +//>>css.theme: ../../themes/base/theme.css + + + +$.widget( "ui.button", { + version: "1.12.1", + defaultElement: "<button>", + options: { + classes: { + "ui-button": "ui-corner-all" + }, + disabled: null, + icon: null, + iconPosition: "beginning", + label: null, + showLabel: true + }, + + _getCreateOptions: function() { + var disabled, + + // This is to support cases like in jQuery Mobile where the base widget does have + // an implementation of _getCreateOptions + options = this._super() || {}; + + this.isInput = this.element.is( "input" ); + + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; + } + + this.originalLabel = this.isInput ? this.element.val() : this.element.html(); + if ( this.originalLabel ) { + options.label = this.originalLabel; } + + return options; }, - _resetButton: function() { - if ( this.type === "input" ) { - if ( this.options.label ) { + _create: function() { + if ( !this.option.showLabel & !this.options.icon ) { + this.options.showLabel = true; + } + + // We have to check the option again here even though we did in _getCreateOptions, + // because null may have been passed on init which would override what was set in + // _getCreateOptions + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled || false; + } + + this.hasTitle = !!this.element.attr( "title" ); + + // Check to see if the label needs to be set or if its already correct + if ( this.options.label && this.options.label !== this.originalLabel ) { + if ( this.isInput ) { this.element.val( this.options.label ); + } else { + this.element.html( this.options.label ); } - return; } - var buttonElement = this.buttonElement.removeClass( typeClasses ), - buttonText = $( "<span></span>", this.document[0] ) - .addClass( "ui-button-text" ) - .html( this.options.label ) - .appendTo( buttonElement.empty() ) - .text(), - icons = this.options.icons, - multipleIcons = icons.primary && icons.secondary, - buttonClasses = []; + this._addClass( "ui-button", "ui-widget" ); + this._setOption( "disabled", this.options.disabled ); + this._enhance(); - if ( icons.primary || icons.secondary ) { - if ( this.options.text ) { - buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); - } + if ( this.element.is( "a" ) ) { + this._on( { + "keyup": function( event ) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + event.preventDefault(); - if ( icons.primary ) { - buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); - } + // Support: PhantomJS <= 1.9, IE 8 Only + // If a native click is available use it so we actually cause navigation + // otherwise just trigger a click event + if ( this.element[ 0 ].click ) { + this.element[ 0 ].click(); + } else { + this.element.trigger( "click" ); + } + } + } + } ); + } + }, + + _enhance: function() { + if ( !this.element.is( "button" ) ) { + this.element.attr( "role", "button" ); + } + + if ( this.options.icon ) { + this._updateIcon( "icon", this.options.icon ); + this._updateTooltip(); + } + }, + + _updateTooltip: function() { + this.title = this.element.attr( "title" ); + + if ( !this.options.showLabel && !this.title ) { + this.element.attr( "title", this.options.label ); + } + }, + + _updateIcon: function( option, value ) { + var icon = option !== "iconPosition", + position = icon ? this.options.iconPosition : value, + displayBlock = position === "top" || position === "bottom"; + + // Create icon + if ( !this.icon ) { + this.icon = $( "<span>" ); + + this._addClass( this.icon, "ui-button-icon", "ui-icon" ); - if ( icons.secondary ) { - buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); + if ( !this.options.showLabel ) { + this._addClass( "ui-button-icon-only" ); } + } else if ( icon ) { - if ( !this.options.text ) { - buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); + // If we are updating the icon remove the old icon class + this._removeClass( this.icon, null, this.options.icon ); + } - if ( !this.hasTitle ) { - buttonElement.attr( "title", $.trim( buttonText ) ); - } + // If we are updating the icon add the new icon class + if ( icon ) { + this._addClass( this.icon, null, value ); + } + + this._attachIcon( position ); + + // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove + // the iconSpace if there is one. + if ( displayBlock ) { + this._addClass( this.icon, null, "ui-widget-icon-block" ); + if ( this.iconSpace ) { + this.iconSpace.remove(); } } else { - buttonClasses.push( "ui-button-text-only" ); + + // Position is beginning or end so remove the ui-widget-icon-block class and add the + // space if it does not exist + if ( !this.iconSpace ) { + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-button-icon-space" ); + } + this._removeClass( this.icon, null, "ui-wiget-icon-block" ); + this._attachIconSpace( position ); } - buttonElement.addClass( buttonClasses.join( " " ) ); - } -}); + }, -$.widget( "ui.buttonset", { - version: "1.11.4", - options: { - items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" + _destroy: function() { + this.element.removeAttr( "role" ); + + if ( this.icon ) { + this.icon.remove(); + } + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + if ( !this.hasTitle ) { + this.element.removeAttr( "title" ); + } }, - _create: function() { - this.element.addClass( "ui-buttonset" ); + _attachIconSpace: function( iconPosition ) { + this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); }, - _init: function() { - this.refresh(); + _attachIcon: function( iconPosition ) { + this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); + }, + + _setOptions: function( options ) { + var newShowLabel = options.showLabel === undefined ? + this.options.showLabel : + options.showLabel, + newIcon = options.icon === undefined ? this.options.icon : options.icon; + + if ( !newShowLabel && !newIcon ) { + options.showLabel = true; + } + this._super( options ); }, _setOption: function( key, value ) { - if ( key === "disabled" ) { - this.buttons.button( "option", key, value ); + if ( key === "icon" ) { + if ( value ) { + this._updateIcon( key, value ); + } else if ( this.icon ) { + this.icon.remove(); + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + } + } + + if ( key === "iconPosition" ) { + this._updateIcon( key, value ); + } + + // Make sure we can't end up with a button that has neither text nor icon + if ( key === "showLabel" ) { + this._toggleClass( "ui-button-icon-only", null, !value ); + this._updateTooltip(); + } + + if ( key === "label" ) { + if ( this.isInput ) { + this.element.val( value ); + } else { + + // If there is an icon, append it, else nothing then append the value + // this avoids removal of the icon when setting label text + this.element.html( value ); + if ( this.icon ) { + this._attachIcon( this.options.iconPosition ); + this._attachIconSpace( this.options.iconPosition ); + } + } } this._super( key, value ); + + if ( key === "disabled" ) { + this._toggleClass( null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; + if ( value ) { + this.element.blur(); + } + } }, refresh: function() { - var rtl = this.element.css( "direction" ) === "rtl", - allButtons = this.element.find( this.options.items ), - existingButtons = allButtons.filter( ":ui-button" ); - - // Initialize new buttons - allButtons.not( ":ui-button" ).button(); - - // Refresh existing buttons - existingButtons.button( "refresh" ); - - this.buttons = allButtons - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) - .filter( ":first" ) - .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) - .end() - .filter( ":last" ) - .addClass( rtl ? "ui-corner-left" : "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" ); + // Make sure to only check disabled if its an element that supports this otherwise + // check for the disabled class to determine state + var isDisabled = this.element.is( "input, button" ) ? + this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); + + if ( isDisabled !== this.options.disabled ) { + this._setOptions( { disabled: isDisabled } ); + } + + this._updateTooltip(); } -}); +} ); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + + // Text and Icons options + $.widget( "ui.button", $.ui.button, { + options: { + text: true, + icons: { + primary: null, + secondary: null + } + }, + + _create: function() { + if ( this.options.showLabel && !this.options.text ) { + this.options.showLabel = this.options.text; + } + if ( !this.options.showLabel && this.options.text ) { + this.options.text = this.options.showLabel; + } + if ( !this.options.icon && ( this.options.icons.primary || + this.options.icons.secondary ) ) { + if ( this.options.icons.primary ) { + this.options.icon = this.options.icons.primary; + } else { + this.options.icon = this.options.icons.secondary; + this.options.iconPosition = "end"; + } + } else if ( this.options.icon ) { + this.options.icons.primary = this.options.icon; + } + this._super(); + }, + + _setOption: function( key, value ) { + if ( key === "text" ) { + this._super( "showLabel", value ); + return; + } + if ( key === "showLabel" ) { + this.options.text = value; + } + if ( key === "icon" ) { + this.options.icons.primary = value; + } + if ( key === "icons" ) { + if ( value.primary ) { + this._super( "icon", value.primary ); + this._super( "iconPosition", "beginning" ); + } else if ( value.secondary ) { + this._super( "icon", value.secondary ); + this._super( "iconPosition", "end" ); + } + } + this._superApply( arguments ); + } + } ); + + $.fn.button = ( function( orig ) { + return function() { + if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) || + ( this.length && this[ 0 ].tagName === "INPUT" && ( + this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio" + ) ) ) { + return orig.apply( this, arguments ); + } + if ( !$.ui.checkboxradio ) { + $.error( "Checkboxradio widget missing" ); + } + if ( arguments.length === 0 ) { + return this.checkboxradio( { + "icon": false + } ); + } + return this.checkboxradio.apply( this, arguments ); + }; + } )( $.fn.button ); + + $.fn.buttonset = function() { + if ( !$.ui.controlgroup ) { + $.error( "Controlgroup widget missing" ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { + return this.controlgroup.apply( this, + [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { + return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); + } + if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { + arguments[ 0 ].items = { + button: arguments[ 0 ].items + }; + } + return this.controlgroup.apply( this, arguments ); + }; +} -var button = $.ui.button; +var widgetsButton = $.ui.button; +// jscs:disable maximumLineLength +/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */ /*! - * jQuery UI Datepicker 1.11.4 + * jQuery UI Datepicker 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/datepicker/ */ +//>>label: Datepicker +//>>group: Widgets +//>>description: Displays a calendar from an input or inline for selecting dates. +//>>docs: http://api.jqueryui.com/datepicker/ +//>>demos: http://jqueryui.com/datepicker/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/datepicker.css +//>>css.theme: ../../themes/base/theme.css + -$.extend($.ui, { datepicker: { version: "1.11.4" } }); + +$.extend( $.ui, { datepicker: { version: "1.12.1" } } ); var datepicker_instActive; function datepicker_getZindex( elem ) { var 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 @@ -3824,17 +7231,17 @@ function Datepicker() { this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class this.regional = []; // Available regional settings, indexed by language code - this.regional[""] = { // Default regional settings + this.regional[ "" ] = { // Default regional settings closeText: "Done", // Display text for close link prevText: "Prev", // Display text for previous month link nextText: "Next", // Display text for next month link currentText: "Today", // Display text for current month link - monthNames: ["January","February","March","April","May","June", - "July","August","September","October","November","December"], // Names of months for drop-down and formatting - monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting - 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 + monthNames: [ "January","February","March","April","May","June", + "July","August","September","October","November","December" ], // Names of months for drop-down and formatting + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting + 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, ... @@ -3892,13 +7299,13 @@ function Datepicker() { autoSize: false, // True to size the input for the date format, false to leave as is disabled: false // The initial disabled state }; - $.extend(this._defaults, this.regional[""]); - this.regional.en = $.extend( true, {}, this.regional[ "" ]); + $.extend( this._defaults, this.regional[ "" ] ); + this.regional.en = $.extend( true, {}, this.regional[ "" ] ); this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); - this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); + this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); } -$.extend(Datepicker.prototype, { +$.extend( Datepicker.prototype, { /* Class name added to elements to indicate already configured with a date picker. */ markerClassName: "hasDatepicker", @@ -3914,8 +7321,8 @@ $.extend(Datepicker.prototype, { * @param settings object - the new settings to use as defaults (anonymous object) * @return the manager object */ - setDefaults: function(settings) { - datepicker_extendRemove(this._defaults, settings || {}); + setDefaults: function( settings ) { + datepicker_extendRemove( this._defaults, settings || {} ); return this; }, @@ -3923,144 +7330,147 @@ $.extend(Datepicker.prototype, { * @param target element - the target input field or division or span * @param settings object - the new settings to use for this date picker instance (anonymous) */ - _attachDatepicker: function(target, settings) { + _attachDatepicker: function( target, settings ) { var nodeName, inline, inst; nodeName = target.nodeName.toLowerCase(); - inline = (nodeName === "div" || nodeName === "span"); - if (!target.id) { + inline = ( nodeName === "div" || nodeName === "span" ); + if ( !target.id ) { this.uuid += 1; target.id = "dp" + this.uuid; } - inst = this._newInst($(target), inline); - inst.settings = $.extend({}, settings || {}); - if (nodeName === "input") { - this._connectDatepicker(target, inst); - } else if (inline) { - this._inlineDatepicker(target, inst); + inst = this._newInst( $( target ), inline ); + inst.settings = $.extend( {}, settings || {} ); + if ( nodeName === "input" ) { + this._connectDatepicker( target, inst ); + } else if ( inline ) { + this._inlineDatepicker( target, inst ); } }, /* Create a new instance object. */ - _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars - return {id: id, input: target, // associated target + _newInst: function( target, inline ) { + 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 inline: inline, // is datepicker inline or not - dpDiv: (!inline ? this.dpDiv : // presentation div - datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; + dpDiv: ( !inline ? this.dpDiv : // presentation div + datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; }, /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); - inst.append = $([]); - inst.trigger = $([]); - if (input.hasClass(this.markerClassName)) { + _connectDatepicker: function( target, inst ) { + var input = $( target ); + inst.append = $( [] ); + 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); - this._autoSize(inst); - $.data(target, "datepicker", inst); + this._attachments( input, inst ); + input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). + on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); + this._autoSize( inst ); + $.data( target, "datepicker", inst ); + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if( inst.settings.disabled ) { + if ( inst.settings.disabled ) { this._disableDatepicker( target ); } }, /* Make attachments based on settings. */ - _attachments: function(input, inst) { + _attachments: function( input, inst ) { var showOn, buttonText, buttonImage, - appendText = this._get(inst, "appendText"), - isRTL = this._get(inst, "isRTL"); + appendText = this._get( inst, "appendText" ), + isRTL = this._get( inst, "isRTL" ); - if (inst.append) { + if ( inst.append ) { inst.append.remove(); } - if (appendText) { - inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); - input[isRTL ? "before" : "after"](inst.append); + if ( appendText ) { + inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" ); + input[ isRTL ? "before" : "after" ]( inst.append ); } - input.unbind("focus", this._showDatepicker); + input.off( "focus", this._showDatepicker ); - if (inst.trigger) { + if ( inst.trigger ) { inst.trigger.remove(); } - showOn = this._get(inst, "showOn"); - if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field - input.focus(this._showDatepicker); - } - if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked - buttonText = this._get(inst, "buttonText"); - buttonImage = this._get(inst, "buttonImage"); - inst.trigger = $(this._get(inst, "buttonImageOnly") ? - $("<img/>").addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $("<button type='button'></button>").addClass(this._triggerClass). - html(!buttonImage ? buttonText : $("<img/>").attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); - input[isRTL ? "before" : "after"](inst.trigger); - inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { + showOn = this._get( inst, "showOn" ); + if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field + input.on( "focus", this._showDatepicker ); + } + if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked + buttonText = this._get( inst, "buttonText" ); + buttonImage = this._get( inst, "buttonImage" ); + inst.trigger = $( this._get( inst, "buttonImageOnly" ) ? + $( "<img/>" ).addClass( this._triggerClass ). + attr( { src: buttonImage, alt: buttonText, title: buttonText } ) : + $( "<button type='button'></button>" ).addClass( this._triggerClass ). + html( !buttonImage ? buttonText : $( "<img/>" ).attr( + { src:buttonImage, alt:buttonText, title:buttonText } ) ) ); + input[ isRTL ? "before" : "after" ]( inst.trigger ); + inst.trigger.on( "click", function() { + if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { $.datepicker._hideDatepicker(); - } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { + } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker(input[0]); + $.datepicker._showDatepicker( input[ 0 ] ); } else { - $.datepicker._showDatepicker(input[0]); + $.datepicker._showDatepicker( input[ 0 ] ); } return false; - }); + } ); } }, /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { - if (this._get(inst, "autoSize") && !inst.inline) { + _autoSize: function( inst ) { + if ( this._get( inst, "autoSize" ) && !inst.inline ) { var findMax, max, maxI, i, - date = new Date(2009, 12 - 1, 20), // Ensure double digits - dateFormat = this._get(inst, "dateFormat"); + date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits + dateFormat = this._get( inst, "dateFormat" ); - if (dateFormat.match(/[DM]/)) { - findMax = function(names) { + if ( dateFormat.match( /[DM]/ ) ) { + findMax = function( names ) { max = 0; maxI = 0; - for (i = 0; i < names.length; i++) { - if (names[i].length > max) { - max = names[i].length; + for ( 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()); + 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); + inst.input.attr( "size", this._formatDate( inst, date ).length ); } }, /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var divSpan = $(target); - if (divSpan.hasClass(this.markerClassName)) { + _inlineDatepicker: function( target, inst ) { + var divSpan = $( target ); + if ( divSpan.hasClass( this.markerClassName ) ) { return; } - divSpan.addClass(this.markerClassName).append(inst.dpDiv); - $.data(target, "datepicker", inst); - this._setDate(inst, this._getDefaultDate(inst), true); - this._updateDatepicker(inst); - this._updateAlternate(inst); + divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); + $.data( target, "datepicker", inst ); + this._setDate( inst, this._getDefaultDate( inst ), true ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if( inst.settings.disabled ) { + if ( inst.settings.disabled ) { this._disableDatepicker( target ); } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height inst.dpDiv.css( "display", "block" ); @@ -4076,72 +7486,72 @@ $.extend(Datepicker.prototype, { * leave empty for default (screen centre) * @return the manager object */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { + _dialogDatepicker: function( input, date, onSelect, settings, pos ) { var id, browserWidth, browserHeight, scrollX, scrollY, inst = this._dialogInst; // internal instance - if (!inst) { + if ( !inst ) { this.uuid += 1; id = "dp" + this.uuid; - this._dialogInput = $("<input type='text' id='" + id + - "' style='position: absolute; top: -100px; width: 0px;'/>"); - this._dialogInput.keydown(this._doKeyDown); - $("body").append(this._dialogInput); - inst = this._dialogInst = this._newInst(this._dialogInput, false); + this._dialogInput = $( "<input type='text' id='" + id + + "' style='position: absolute; top: -100px; width: 0px;'/>" ); + this._dialogInput.on( "keydown", this._doKeyDown ); + $( "body" ).append( this._dialogInput ); + inst = this._dialogInst = this._newInst( this._dialogInput, false ); inst.settings = {}; - $.data(this._dialogInput[0], "datepicker", inst); + $.data( this._dialogInput[ 0 ], "datepicker", inst ); } - datepicker_extendRemove(inst.settings, settings || {}); - date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); - this._dialogInput.val(date); + datepicker_extendRemove( inst.settings, settings || {} ); + 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) { + this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); + if ( !this._pos ) { browserWidth = document.documentElement.clientWidth; browserHeight = document.documentElement.clientHeight; scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; scrollY = document.documentElement.scrollTop || document.body.scrollTop; this._pos = // should use actual width/height below - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; } - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); + // Move input on screen for focus, but hidden behind dialog + 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); - this._showDatepicker(this._dialogInput[0]); - if ($.blockUI) { - $.blockUI(this.dpDiv); + this.dpDiv.addClass( this._dialogClass ); + this._showDatepicker( this._dialogInput[ 0 ] ); + if ( $.blockUI ) { + $.blockUI( this.dpDiv ); } - $.data(this._dialogInput[0], "datepicker", inst); + $.data( this._dialogInput[ 0 ], "datepicker", inst ); return this; }, /* Detach a datepicker from its control. * @param target element - the target input field or division or span */ - _destroyDatepicker: function(target) { + _destroyDatepicker: function( target ) { var nodeName, - $target = $(target), - inst = $.data(target, "datepicker"); + $target = $( target ), + inst = $.data( target, "datepicker" ); - if (!$target.hasClass(this.markerClassName)) { + if ( !$target.hasClass( this.markerClassName ) ) { return; } nodeName = target.nodeName.toLowerCase(); - $.removeData(target, "datepicker"); - if (nodeName === "input") { + $.removeData( target, "datepicker" ); + if ( nodeName === "input" ) { inst.append.remove(); inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind("focus", this._showDatepicker). - unbind("keydown", this._doKeyDown). - unbind("keypress", this._doKeyPress). - unbind("keyup", this._doKeyUp); - } else if (nodeName === "div" || nodeName === "span") { - $target.removeClass(this.markerClassName).empty(); + $target.removeClass( this.markerClassName ). + off( "focus", this._showDatepicker ). + off( "keydown", this._doKeyDown ). + off( "keypress", this._doKeyPress ). + off( "keyup", this._doKeyUp ); + } else if ( nodeName === "div" || nodeName === "span" ) { + $target.removeClass( this.markerClassName ).empty(); } if ( datepicker_instActive === inst ) { @@ -4152,70 +7562,70 @@ $.extend(Datepicker.prototype, { /* Enable the date picker to a jQuery selection. * @param target element - the target input field or division or span */ - _enableDatepicker: function(target) { + _enableDatepicker: function( target ) { var nodeName, inline, - $target = $(target), - inst = $.data(target, "datepicker"); + $target = $( target ), + inst = $.data( target, "datepicker" ); - if (!$target.hasClass(this.markerClassName)) { + if ( !$target.hasClass( this.markerClassName ) ) { return; } nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { + if ( nodeName === "input" ) { target.disabled = false; - inst.trigger.filter("button"). - each(function() { this.disabled = false; }).end(). - filter("img").css({opacity: "1.0", cursor: ""}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().removeClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", false); + inst.trigger.filter( "button" ). + each( function() { this.disabled = false; } ).end(). + filter( "img" ).css( { opacity: "1.0", cursor: "" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().removeClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", false ); } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry + this._disabledInputs = $.map( this._disabledInputs, + function( value ) { return ( value === target ? null : value ); } ); // delete entry }, /* Disable the date picker to a jQuery selection. * @param target element - the target input field or division or span */ - _disableDatepicker: function(target) { + _disableDatepicker: function( target ) { var nodeName, inline, - $target = $(target), - inst = $.data(target, "datepicker"); + $target = $( target ), + inst = $.data( target, "datepicker" ); - if (!$target.hasClass(this.markerClassName)) { + if ( !$target.hasClass( this.markerClassName ) ) { return; } nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { + if ( nodeName === "input" ) { target.disabled = true; - inst.trigger.filter("button"). - each(function() { this.disabled = true; }).end(). - filter("img").css({opacity: "0.5", cursor: "default"}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().addClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", true); + inst.trigger.filter( "button" ). + each( function() { this.disabled = true; } ).end(). + filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().addClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", true ); } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry - this._disabledInputs[this._disabledInputs.length] = target; + this._disabledInputs = $.map( this._disabledInputs, + function( value ) { return ( value === target ? null : value ); } ); // delete entry + this._disabledInputs[ this._disabledInputs.length ] = target; }, /* Is the first field in a jQuery collection disabled as a datepicker? * @param target element - the target input field or division or span * @return boolean - true if disabled, false if enabled */ - _isDisabledDatepicker: function(target) { - if (!target) { + _isDisabledDatepicker: function( target ) { + if ( !target ) { return false; } - for (var i = 0; i < this._disabledInputs.length; i++) { - if (this._disabledInputs[i] === target) { + for ( var i = 0; i < this._disabledInputs.length; i++ ) { + if ( this._disabledInputs[ i ] === target ) { return true; } } @@ -4227,11 +7637,11 @@ $.extend(Datepicker.prototype, { * @return object - the associated instance data * @throws error if a jQuery problem getting data */ - _getInst: function(target) { + _getInst: function( target ) { try { - return $.data(target, "datepicker"); + return $.data( target, "datepicker" ); } - catch (err) { + catch ( err ) { throw "Missing instance data for this datepicker"; } }, @@ -4245,65 +7655,66 @@ $.extend(Datepicker.prototype, { * @param value any - the new value for the setting * (omit if above is an object or to retrieve a value) */ - _optionDatepicker: function(target, name, value) { + _optionDatepicker: function( target, name, value ) { var settings, date, minDate, maxDate, - inst = this._getInst(target); + inst = this._getInst( target ); - if (arguments.length === 2 && typeof name === "string") { - return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : - (inst ? (name === "all" ? $.extend({}, inst.settings) : - this._get(inst, name)) : null)); + if ( arguments.length === 2 && typeof name === "string" ) { + return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : + ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : + this._get( inst, name ) ) : null ) ); } settings = name || {}; - if (typeof name === "string") { + if ( typeof name === "string" ) { settings = {}; - settings[name] = value; + settings[ name ] = value; } - if (inst) { - if (this._curInst === inst) { + if ( inst ) { + if ( this._curInst === inst ) { this._hideDatepicker(); } - date = this._getDateDatepicker(target, true); - minDate = this._getMinMaxDate(inst, "min"); - maxDate = this._getMinMaxDate(inst, "max"); - datepicker_extendRemove(inst.settings, settings); + date = this._getDateDatepicker( target, true ); + minDate = this._getMinMaxDate( inst, "min" ); + maxDate = this._getMinMaxDate( inst, "max" ); + datepicker_extendRemove( inst.settings, settings ); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { - inst.settings.minDate = this._formatDate(inst, minDate); + if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { + inst.settings.minDate = this._formatDate( inst, minDate ); } - if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { - inst.settings.maxDate = this._formatDate(inst, maxDate); + if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { + inst.settings.maxDate = this._formatDate( inst, maxDate ); } if ( "disabled" in settings ) { if ( settings.disabled ) { - this._disableDatepicker(target); + this._disableDatepicker( target ); } else { - this._enableDatepicker(target); + this._enableDatepicker( target ); } } - this._attachments($(target), inst); - this._autoSize(inst); - this._setDate(inst, date); - this._updateAlternate(inst); - this._updateDatepicker(inst); + this._attachments( $( target ), inst ); + this._autoSize( inst ); + this._setDate( inst, date ); + this._updateAlternate( inst ); + this._updateDatepicker( inst ); } }, - // change method deprecated - _changeDatepicker: function(target, name, value) { - this._optionDatepicker(target, name, value); + // Change method deprecated + _changeDatepicker: function( target, name, value ) { + this._optionDatepicker( target, name, value ); }, /* Redraw the date picker attached to an input field or division. * @param target element - the target input field or division or span */ - _refreshDatepicker: function(target) { - var inst = this._getInst(target); - if (inst) { - this._updateDatepicker(inst); + _refreshDatepicker: function( target ) { + var inst = this._getInst( target ); + if ( inst ) { + this._updateDatepicker( inst ); } }, @@ -4311,12 +7722,12 @@ $.extend(Datepicker.prototype, { * @param target element - the target input field or division or span * @param date Date - the new date */ - _setDateDatepicker: function(target, date) { - var inst = this._getInst(target); - if (inst) { - this._setDate(inst, date); - this._updateDatepicker(inst); - this._updateAlternate(inst); + _setDateDatepicker: function( target, date ) { + var inst = this._getInst( target ); + if ( inst ) { + this._setDate( inst, date ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); } }, @@ -4325,39 +7736,39 @@ $.extend(Datepicker.prototype, { * @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, noDefault); + _getDateDatepicker: function( target, noDefault ) { + var inst = this._getInst( target ); + if ( inst && !inst.inline ) { + this._setDateFromField( inst, noDefault ); } - return (inst ? this._getDate(inst) : null); + return ( inst ? this._getDate( inst ) : null ); }, /* Handle keystrokes. */ - _doKeyDown: function(event) { + _doKeyDown: function( event ) { var onSelect, dateStr, sel, - inst = $.datepicker._getInst(event.target), + inst = $.datepicker._getInst( event.target ), handled = true, - isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); + isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); inst._keyEvent = true; - if ($.datepicker._datepickerShowing) { - switch (event.keyCode) { + if ( $.datepicker._datepickerShowing ) { + switch ( event.keyCode ) { case 9: $.datepicker._hideDatepicker(); handled = false; break; // hide on tab out - case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv); - if (sel[0]) { - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv ); + if ( sel[ 0 ] ) { + $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); } - onSelect = $.datepicker._get(inst, "onSelect"); - if (onSelect) { - dateStr = $.datepicker._formatDate(inst); + onSelect = $.datepicker._get( inst, "onSelect" ); + if ( onSelect ) { + dateStr = $.datepicker._formatDate( inst ); - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + // Trigger custom callback + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); } else { $.datepicker._hideDatepicker(); } @@ -4365,102 +7776,106 @@ $.extend(Datepicker.prototype, { return false; // don't submit the form case 27: $.datepicker._hideDatepicker(); break; // hide on escape - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); + case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); + case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); break; // next month/year on page down/+ ctrl - case 35: if (event.ctrlKey || event.metaKey) { - $.datepicker._clearDate(event.target); + case 35: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._clearDate( event.target ); } handled = event.ctrlKey || event.metaKey; break; // clear on ctrl or command +end - case 36: if (event.ctrlKey || event.metaKey) { - $.datepicker._gotoToday(event.target); + case 36: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._gotoToday( event.target ); } handled = event.ctrlKey || event.metaKey; break; // current on ctrl or command +home - case 37: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); + case 37: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); } handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); } + // next month/year on alt +left on Mac break; - case 38: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, -7, "D"); + case 38: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, -7, "D" ); } handled = event.ctrlKey || event.metaKey; break; // -1 week on ctrl or command +up - case 39: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); + case 39: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); } handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); } + // next month/year on alt +right break; - case 40: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, +7, "D"); + case 40: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, +7, "D" ); } handled = event.ctrlKey || event.metaKey; break; // +1 week on ctrl or command +down default: handled = false; } - } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home - $.datepicker._showDatepicker(this); + } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home + $.datepicker._showDatepicker( this ); } else { handled = false; } - if (handled) { + if ( handled ) { event.preventDefault(); event.stopPropagation(); } }, /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { + _doKeyPress: function( event ) { var chars, chr, - inst = $.datepicker._getInst(event.target); + inst = $.datepicker._getInst( event.target ); - if ($.datepicker._get(inst, "constrainInput")) { - chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); - chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); - return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); + if ( $.datepicker._get( inst, "constrainInput" ) ) { + chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); + chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); + return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); } }, /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { + _doKeyUp: function( event ) { var date, - inst = $.datepicker._getInst(event.target); + inst = $.datepicker._getInst( event.target ); - if (inst.input.val() !== inst.lastVal) { + if ( inst.input.val() !== inst.lastVal ) { try { - 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); + 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 (err) { + catch ( err ) { } } return true; @@ -4471,80 +7886,83 @@ $.extend(Datepicker.prototype, { * @param input element - the input field attached to the date picker or * event - if triggered by focus */ - _showDatepicker: function(input) { + _showDatepicker: function( input ) { input = input.target || input; - if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger - input = $("input", input.parentNode)[0]; + if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger + input = $( "input", input.parentNode )[ 0 ]; } - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here + if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here return; } var inst, beforeShow, beforeShowSettings, isFixed, offset, showAnim, duration; - inst = $.datepicker._getInst(input); - if ($.datepicker._curInst && $.datepicker._curInst !== inst) { - $.datepicker._curInst.dpDiv.stop(true, true); + inst = $.datepicker._getInst( input ); + if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { + $.datepicker._curInst.dpDiv.stop( true, true ); if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); } } - beforeShow = $.datepicker._get(inst, "beforeShow"); - beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; - if(beforeShowSettings === false){ + beforeShow = $.datepicker._get( inst, "beforeShow" ); + beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; + if ( beforeShowSettings === false ) { return; } - datepicker_extendRemove(inst.settings, beforeShowSettings); + datepicker_extendRemove( inst.settings, beforeShowSettings ); inst.lastVal = null; $.datepicker._lastInput = input; - $.datepicker._setDateFromField(inst); + $.datepicker._setDateFromField( inst ); - if ($.datepicker._inDialog) { // hide cursor + if ( $.datepicker._inDialog ) { // hide cursor input.value = ""; } - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height + if ( !$.datepicker._pos ) { // position below input + $.datepicker._pos = $.datepicker._findPos( input ); + $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height } isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css("position") === "fixed"; + $( input ).parents().each( function() { + isFixed |= $( this ).css( "position" ) === "fixed"; return !isFixed; - }); + } ); - offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; $.datepicker._pos = null; + //to avoid flashes on Firefox inst.dpDiv.empty(); + // determine sizing offscreen - inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); - $.datepicker._updateDatepicker(inst); + inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); + $.datepicker._updateDatepicker( inst ); + // fix width for dynamic number of date pickers // and adjust position before showing - offset = $.datepicker._checkOffset(inst, offset, isFixed); - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? - "static" : (isFixed ? "fixed" : "absolute")), display: "none", - left: offset.left + "px", top: offset.top + "px"}); - - if (!inst.inline) { - showAnim = $.datepicker._get(inst, "showAnim"); - duration = $.datepicker._get(inst, "duration"); + offset = $.datepicker._checkOffset( inst, offset, isFixed ); + inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? + "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", + left: offset.left + "px", top: offset.top + "px" } ); + + if ( !inst.inline ) { + showAnim = $.datepicker._get( inst, "showAnim" ); + duration = $.datepicker._get( inst, "duration" ); inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); $.datepicker._datepickerShowing = true; if ( $.effects && $.effects.effect[ showAnim ] ) { - inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); + inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); } else { - inst.dpDiv[showAnim || "show"](showAnim ? duration : null); + inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); } if ( $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); + inst.input.trigger( "focus" ); } $.datepicker._curInst = inst; @@ -4552,15 +7970,15 @@ $.extend(Datepicker.prototype, { }, /* Generate the date picker content. */ - _updateDatepicker: function(inst) { + _updateDatepicker: function( inst ) { this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) datepicker_instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - this._attachHandlers(inst); + inst.dpDiv.empty().append( this._generateHTML( inst ) ); + this._attachHandlers( inst ); var origyearshtml, - numMonths = this._getNumberOfMonths(inst), - cols = numMonths[1], + numMonths = this._getNumberOfMonths( inst ), + cols = numMonths[ 1 ], width = 17, activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); @@ -4568,29 +7986,30 @@ $.extend(Datepicker.prototype, { datepicker_handleMouseover.apply( activeCell.get( 0 ) ); } - inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); - if (cols > 1) { - inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); + inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); + if ( cols > 1 ) { + inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); } - 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"); + 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 === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); + if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.trigger( "focus" ); } - // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ + // Deffered render of the years select (to avoid flashes on Firefox) + if ( inst.yearshtml ) { origyearshtml = inst.yearshtml; - setTimeout(function(){ + setTimeout( function() { + //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ - inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); + if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { + inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml ); } origyearshtml = inst.yearshtml = null; - }, 0); + }, 0 ); } }, @@ -4602,83 +8021,83 @@ $.extend(Datepicker.prototype, { }, /* Check positioning to remain on screen. */ - _checkOffset: function(inst, offset, isFixed) { + _checkOffset: function( inst, offset, isFixed ) { var dpWidth = inst.dpDiv.outerWidth(), dpHeight = inst.dpDiv.outerHeight(), inputWidth = inst.input ? inst.input.outerWidth() : 0, inputHeight = inst.input ? inst.input.outerHeight() : 0, - viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), - viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); + viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), + viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( 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; + 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 -= 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); + // Now check if datepicker is showing outside window viewport - move to a better place if so. + 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) { + _findPos: function( obj ) { var position, - inst = this._getInst(obj), - isRTL = this._get(inst, "isRTL"); + inst = this._getInst( obj ), + isRTL = this._get( inst, "isRTL" ); - while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { - obj = obj[isRTL ? "previousSibling" : "nextSibling"]; + while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) { + obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; } - position = $(obj).offset(); - return [position.left, position.top]; + 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 */ - _hideDatepicker: function(input) { + _hideDatepicker: function( input ) { var showAnim, duration, postProcess, onClose, inst = this._curInst; - if (!inst || (input && inst !== $.data(input, "datepicker"))) { + if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { return; } - if (this._datepickerShowing) { - showAnim = this._get(inst, "showAnim"); - duration = this._get(inst, "duration"); + if ( this._datepickerShowing ) { + showAnim = this._get( inst, "showAnim" ); + duration = this._get( inst, "duration" ); postProcess = function() { - $.datepicker._tidyDialog(inst); + $.datepicker._tidyDialog( inst ); }; // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); + inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); } else { - inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : - (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); + inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : + ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); } - if (!showAnim) { + if ( !showAnim ) { postProcess(); } this._datepickerShowing = false; - onClose = this._get(inst, "onClose"); - if (onClose) { - onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); + onClose = this._get( inst, "onClose" ); + if ( onClose ) { + onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); } this._lastInput = null; - if (this._inDialog) { - this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); - if ($.blockUI) { + if ( this._inDialog ) { + this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); + if ( $.blockUI ) { $.unblockUI(); - $("body").append(this.dpDiv); + $( "body" ).append( this.dpDiv ); } } this._inDialog = false; @@ -4686,50 +8105,50 @@ $.extend(Datepicker.prototype, { }, /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { - inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); + _tidyDialog: function( inst ) { + inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); }, /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { - if (!$.datepicker._curInst) { + _checkExternalClick: function( event ) { + if ( !$.datepicker._curInst ) { return; } - var $target = $(event.target), - inst = $.datepicker._getInst($target[0]); + var $target = $( event.target ), + inst = $.datepicker._getInst( $target[ 0 ] ); - if ( ( ( $target[0].id !== $.datepicker._mainDivId && - $target.parents("#" + $.datepicker._mainDivId).length === 0 && - !$target.hasClass($.datepicker.markerClassName) && - !$target.closest("." + $.datepicker._triggerClass).length && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || - ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { + if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && + $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && + !$target.hasClass( $.datepicker.markerClassName ) && + !$target.closest( "." + $.datepicker._triggerClass ).length && + $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || + ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { $.datepicker._hideDatepicker(); } }, /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { - var target = $(id), - inst = this._getInst(target[0]); + _adjustDate: function( id, offset, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); - if (this._isDisabledDatepicker(target[0])) { + if ( this._isDisabledDatepicker( target[ 0 ] ) ) { return; } - this._adjustInstDate(inst, offset + - (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning - period); - this._updateDatepicker(inst); + this._adjustInstDate( inst, offset + + ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning + period ); + this._updateDatepicker( inst ); }, /* Action for current link. */ - _gotoToday: function(id) { + _gotoToday: function( id ) { var date, - target = $(id), - inst = this._getInst(target[0]); + target = $( id ), + inst = this._getInst( target[ 0 ] ); - if (this._get(inst, "gotoCurrent") && inst.currentDay) { + if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { inst.selectedDay = inst.currentDay; inst.drawMonth = inst.selectedMonth = inst.currentMonth; inst.drawYear = inst.selectedYear = inst.currentYear; @@ -4739,87 +8158,87 @@ $.extend(Datepicker.prototype, { inst.drawMonth = inst.selectedMonth = date.getMonth(); inst.drawYear = inst.selectedYear = date.getFullYear(); } - this._notifyChange(inst); - this._adjustDate(target); + this._notifyChange( inst ); + this._adjustDate( target ); }, /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { - var target = $(id), - inst = this._getInst(target[0]); + _selectMonthYear: function( id, select, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); - inst["selected" + (period === "M" ? "Month" : "Year")] = - inst["draw" + (period === "M" ? "Month" : "Year")] = - parseInt(select.options[select.selectedIndex].value,10); + inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = + inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = + parseInt( select.options[ select.selectedIndex ].value, 10 ); - this._notifyChange(inst); - this._adjustDate(target); + this._notifyChange( inst ); + this._adjustDate( target ); }, /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { + _selectDay: function( id, month, year, td ) { var inst, - target = $(id); + target = $( id ); - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { return; } - inst = this._getInst(target[0]); - inst.selectedDay = inst.currentDay = $("a", td).html(); + inst = this._getInst( target[ 0 ] ); + inst.selectedDay = inst.currentDay = $( "a", td ).html(); inst.selectedMonth = inst.currentMonth = month; inst.selectedYear = inst.currentYear = year; - this._selectDate(id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); + this._selectDate( id, this._formatDate( inst, + inst.currentDay, inst.currentMonth, inst.currentYear ) ); }, /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { - var target = $(id); - this._selectDate(target, ""); + _clearDate: function( id ) { + var target = $( id ); + this._selectDate( target, "" ); }, /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { + _selectDate: function( id, dateStr ) { var onSelect, - target = $(id), - inst = this._getInst(target[0]); + target = $( id ), + inst = this._getInst( target[ 0 ] ); - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); - if (inst.input) { - inst.input.val(dateStr); + dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); + if ( inst.input ) { + inst.input.val( dateStr ); } - this._updateAlternate(inst); + this._updateAlternate( inst ); - onSelect = this._get(inst, "onSelect"); - if (onSelect) { - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback - } else if (inst.input) { - inst.input.trigger("change"); // fire the change event + onSelect = this._get( inst, "onSelect" ); + if ( onSelect ) { + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback + } else if ( inst.input ) { + inst.input.trigger( "change" ); // fire the change event } - if (inst.inline){ - this._updateDatepicker(inst); + if ( inst.inline ) { + this._updateDatepicker( inst ); } else { this._hideDatepicker(); - this._lastInput = inst.input[0]; - if (typeof(inst.input[0]) !== "object") { - inst.input.focus(); // restore focus + this._lastInput = inst.input[ 0 ]; + if ( typeof( inst.input[ 0 ] ) !== "object" ) { + inst.input.trigger( "focus" ); // restore focus } this._lastInput = null; } }, /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { + _updateAlternate: function( inst ) { var altFormat, date, dateStr, - altField = this._get(inst, "altField"); + altField = this._get( inst, "altField" ); - if (altField) { // update alternate field too - altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); - date = this._getDate(inst); - dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); + if ( altField ) { // update alternate field too + altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); + date = this._getDate( inst ); + dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); + $( altField ).val( dateStr ); } }, @@ -4827,26 +8246,26 @@ $.extend(Datepicker.prototype, { * @param date Date - the date to customise * @return [boolean, string] - is this date selectable?, what is its CSS class? */ - noWeekends: function(date) { + noWeekends: function( date ) { var day = date.getDay(); - return [(day > 0 && day < 6), ""]; + return [ ( day > 0 && day < 6 ), "" ]; }, /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. * @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) { + iso8601Week: function( date ) { var time, - checkDate = new Date(date.getTime()); + checkDate = new Date( date.getTime() ); // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + 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. @@ -4862,125 +8281,129 @@ $.extend(Datepicker.prototype, { * monthNames string[12] - names of the months (optional) * @return Date - the extracted date value or null if value is blank */ - parseDate: function (format, value, settings) { - if (format == null || value == null) { + parseDate: function( format, value, settings ) { + if ( format == null || value == null ) { throw "Invalid arguments"; } - value = (typeof value === "object" ? value.toString() : value + ""); - if (value === "") { + value = ( typeof value === "object" ? value.toString() : value + "" ); + if ( value === "" ) { return null; } var iFormat, dim, extra, iValue = 0, - shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, - shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : - new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, + shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, year = -1, month = -1, day = -1, doy = -1, literal = false, date, + // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { iFormat++; } return matches; }, + // Extract a number from the string value - getNumber = function(match) { - var isDoubled = lookAhead(match), - size = (match === "@" ? 14 : (match === "!" ? 20 : - (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), - minSize = (match === "y" ? size : 1), - digits = new RegExp("^\\d{" + minSize + "," + size + "}"), - num = value.substring(iValue).match(digits); - if (!num) { + getNumber = function( match ) { + var isDoubled = lookAhead( match ), + size = ( match === "@" ? 14 : ( match === "!" ? 20 : + ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), + minSize = ( match === "y" ? size : 1 ), + digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), + num = value.substring( iValue ).match( digits ); + if ( !num ) { throw "Missing number at position " + iValue; } - iValue += num[0].length; - return parseInt(num[0], 10); + iValue += num[ 0 ].length; + return parseInt( num[ 0 ], 10 ); }, + // Extract a name from the string value and convert to an index - getName = function(match, shortNames, longNames) { + getName = function( match, shortNames, longNames ) { var index = -1, - names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; - }).sort(function (a, b) { - return -(a[1].length - b[1].length); - }); - - $.each(names, function (i, pair) { - var name = pair[1]; - if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { - index = pair[0]; + names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { + return [ [ k, v ] ]; + } ).sort( function( a, b ) { + return -( a[ 1 ].length - b[ 1 ].length ); + } ); + + $.each( names, function( i, pair ) { + var name = pair[ 1 ]; + if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { + index = pair[ 0 ]; iValue += name.length; return false; } - }); - if (index !== -1) { + } ); + if ( index !== -1 ) { return index + 1; } else { throw "Unknown name at position " + iValue; } }, + // Confirm that a literal character matches the string value checkLiteral = function() { - if (value.charAt(iValue) !== format.charAt(iFormat)) { + if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { throw "Unexpected literal at position " + iValue; } iValue++; }; - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { literal = false; } else { checkLiteral(); } } else { - switch (format.charAt(iFormat)) { + switch ( format.charAt( iFormat ) ) { case "d": - day = getNumber("d"); + day = getNumber( "d" ); break; case "D": - getName("D", dayNamesShort, dayNames); + getName( "D", dayNamesShort, dayNames ); break; case "o": - doy = getNumber("o"); + doy = getNumber( "o" ); break; case "m": - month = getNumber("m"); + month = getNumber( "m" ); break; case "M": - month = getName("M", monthNamesShort, monthNames); + month = getName( "M", monthNamesShort, monthNames ); break; case "y": - year = getNumber("y"); + year = getNumber( "y" ); break; case "@": - date = new Date(getNumber("@")); + date = new Date( getNumber( "@" ) ); year = date.getFullYear(); month = date.getMonth() + 1; day = date.getDate(); break; case "!": - date = new Date((getNumber("!") - this._ticksTo1970) / 10000); + date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); year = date.getFullYear(); month = date.getMonth() + 1; day = date.getDate(); break; case "'": - if (lookAhead("'")){ + if ( lookAhead( "'" ) ) { checkLiteral(); } else { literal = true; @@ -4992,35 +8415,35 @@ $.extend(Datepicker.prototype, { } } - if (iValue < value.length){ - extra = value.substr(iValue); - if (!/^\s+/.test(extra)) { + if ( iValue < value.length ) { + extra = value.substr( iValue ); + if ( !/^\s+/.test( extra ) ) { throw "Extra/unparsed characters found in date: " + extra; } } - if (year === -1) { + if ( year === -1 ) { year = new Date().getFullYear(); - } else if (year < 100) { + } else if ( year < 100 ) { year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); + ( year <= shortYearCutoff ? 0 : -100 ); } - if (doy > -1) { + if ( doy > -1 ) { month = 1; day = doy; do { - dim = this._getDaysInMonth(year, month - 1); - if (day <= dim) { + dim = this._getDaysInMonth( year, month - 1 ); + if ( day <= dim ) { break; } month++; day -= dim; - } while (true); + } while ( true ); } - date = this._daylightSavingAdjust(new Date(year, month - 1, day)); - if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { + date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); + if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { throw "Invalid date"; // E.g. 31/02/00 } return date; @@ -5040,8 +8463,8 @@ $.extend(Datepicker.prototype, { 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), + _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: @@ -5071,70 +8494,73 @@ $.extend(Datepicker.prototype, { * monthNames string[12] - names of the months (optional) * @return string - the date in the above format */ - formatDate: function (format, date, settings) { - if (!date) { + formatDate: function( format, date, settings ) { + if ( !date ) { return ""; } var iFormat, - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, + // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { iFormat++; } return matches; }, + // Format a number, with leading zero if necessary - formatNumber = function(match, value, len) { + formatNumber = function( match, value, len ) { var num = "" + value; - if (lookAhead(match)) { - while (num.length < len) { + if ( lookAhead( match ) ) { + while ( num.length < len ) { num = "0" + num; } } return num; }, + // Format a name, short or long as requested - formatName = function(match, value, shortNames, longNames) { - return (lookAhead(match) ? longNames[value] : shortNames[value]); + formatName = function( match, value, shortNames, longNames ) { + return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); }, output = "", literal = false; - if (date) { - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + if ( date ) { + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { literal = false; } else { - output += format.charAt(iFormat); + output += format.charAt( iFormat ); } } else { - switch (format.charAt(iFormat)) { + switch ( format.charAt( iFormat ) ) { case "d": - output += formatNumber("d", date.getDate(), 2); + output += formatNumber( "d", date.getDate(), 2 ); break; case "D": - output += formatName("D", date.getDay(), dayNamesShort, dayNames); + output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); break; case "o": - output += formatNumber("o", - Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + output += formatNumber( "o", + Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); break; case "m": - output += formatNumber("m", date.getMonth() + 1, 2); + output += formatNumber( "m", date.getMonth() + 1, 2 ); break; case "M": - output += formatName("M", date.getMonth(), monthNamesShort, monthNames); + output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); break; case "y": - output += (lookAhead("y") ? date.getFullYear() : - (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); + output += ( lookAhead( "y" ) ? date.getFullYear() : + ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); break; case "@": output += date.getTime(); @@ -5143,14 +8569,14 @@ $.extend(Datepicker.prototype, { output += date.getTime() * 10000 + this._ticksTo1970; break; case "'": - if (lookAhead("'")) { + if ( lookAhead( "'" ) ) { output += "'"; } else { literal = true; } break; default: - output += format.charAt(iFormat); + output += format.charAt( iFormat ); } } } @@ -5159,42 +8585,43 @@ $.extend(Datepicker.prototype, { }, /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { + _possibleChars: function( format ) { var iFormat, chars = "", literal = false, + // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { iFormat++; } return matches; }; - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { literal = false; } else { - chars += format.charAt(iFormat); + chars += format.charAt( iFormat ); } } else { - switch (format.charAt(iFormat)) { + switch ( format.charAt( iFormat ) ) { case "d": case "m": case "y": case "@": chars += "0123456789"; break; case "D": case "M": return null; // Accept anything case "'": - if (lookAhead("'")) { + if ( lookAhead( "'" ) ) { chars += "'"; } else { literal = true; } break; default: - chars += format.charAt(iFormat); + chars += format.charAt( iFormat ); } } } @@ -5202,97 +8629,98 @@ $.extend(Datepicker.prototype, { }, /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { - return inst.settings[name] !== undefined ? - inst.settings[name] : this._defaults[name]; + _get: function( inst, name ) { + return inst.settings[ name ] !== undefined ? + inst.settings[ name ] : this._defaults[ name ]; }, /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst, noDefault) { - if (inst.input.val() === inst.lastVal) { + _setDateFromField: function( inst, noDefault ) { + if ( inst.input.val() === inst.lastVal ) { return; } - var dateFormat = this._get(inst, "dateFormat"), + var dateFormat = this._get( inst, "dateFormat" ), dates = inst.lastVal = inst.input ? inst.input.val() : null, - defaultDate = this._getDefaultDate(inst), + defaultDate = this._getDefaultDate( inst ), date = defaultDate, - settings = this._getFormatConfig(inst); + settings = this._getFormatConfig( inst ); try { - date = this.parseDate(dateFormat, dates, settings) || defaultDate; - } catch (event) { - dates = (noDefault ? "" : dates); + date = this.parseDate( dateFormat, dates, settings ) || defaultDate; + } catch ( event ) { + dates = ( noDefault ? "" : dates ); } inst.selectedDay = date.getDate(); inst.drawMonth = inst.selectedMonth = date.getMonth(); inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = (dates ? date.getDate() : 0); - inst.currentMonth = (dates ? date.getMonth() : 0); - inst.currentYear = (dates ? date.getFullYear() : 0); - this._adjustInstDate(inst); + inst.currentDay = ( dates ? date.getDate() : 0 ); + inst.currentMonth = ( dates ? date.getMonth() : 0 ); + inst.currentYear = ( dates ? date.getFullYear() : 0 ); + this._adjustInstDate( inst ); }, /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { - return this._restrictMinMax(inst, - this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); + _getDefaultDate: function( inst ) { + 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(inst, date, defaultDate) { - var offsetNumeric = function(offset) { + _determineDate: function( inst, date, defaultDate ) { + var offsetNumeric = function( offset ) { var date = new Date(); - date.setDate(date.getDate() + offset); + date.setDate( date.getDate() + offset ); return date; }, - offsetString = function(offset) { + offsetString = function( offset ) { try { - return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), - offset, $.datepicker._getFormatConfig(inst)); + return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), + offset, $.datepicker._getFormatConfig( inst ) ); } - catch (e) { + catch ( e ) { + // Ignore } - var date = (offset.toLowerCase().match(/^c/) ? - $.datepicker._getDate(inst) : null) || new Date(), + var date = ( offset.toLowerCase().match( /^c/ ) ? + $.datepicker._getDate( inst ) : null ) || new Date(), year = date.getFullYear(), month = date.getMonth(), day = date.getDate(), pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, - matches = pattern.exec(offset); + matches = pattern.exec( offset ); - while (matches) { - switch (matches[2] || "d") { + while ( matches ) { + switch ( matches[ 2 ] || "d" ) { case "d" : case "D" : - day += parseInt(matches[1],10); break; + day += parseInt( matches[ 1 ], 10 ); break; case "w" : case "W" : - day += parseInt(matches[1],10) * 7; break; + day += parseInt( matches[ 1 ], 10 ) * 7; break; case "m" : case "M" : - month += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + month += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); break; case "y": case "Y" : - year += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + year += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); break; } - matches = pattern.exec(offset); + matches = pattern.exec( offset ); } - return new Date(year, month, day); + return new Date( year, month, day ); }, - newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : - (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : + ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); - newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); - if (newDate) { - newDate.setHours(0); - newDate.setMinutes(0); - newDate.setSeconds(0); - newDate.setMilliseconds(0); + newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); + if ( newDate ) { + newDate.setHours( 0 ); + newDate.setMinutes( 0 ); + newDate.setSeconds( 0 ); + newDate.setMilliseconds( 0 ); } - return this._daylightSavingAdjust(newDate); + return this._daylightSavingAdjust( newDate ); }, /* Handle switch to/from daylight saving. @@ -5302,80 +8730,80 @@ $.extend(Datepicker.prototype, { * @param date (Date) the date to check * @return (Date) the corrected date */ - _daylightSavingAdjust: function(date) { - if (!date) { + _daylightSavingAdjust: function( date ) { + if ( !date ) { return null; } - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); return date; }, /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { + _setDate: function( inst, date, noChange ) { var clear = !date, origMonth = inst.selectedMonth, origYear = inst.selectedYear, - newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); inst.selectedDay = inst.currentDay = newDate.getDate(); inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { - this._notifyChange(inst); + if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { + this._notifyChange( inst ); } - this._adjustInstDate(inst); - if (inst.input) { - inst.input.val(clear ? "" : this._formatDate(inst)); + this._adjustInstDate( inst ); + if ( inst.input ) { + inst.input.val( clear ? "" : this._formatDate( inst ) ); } }, /* Retrieve the date(s) directly. */ - _getDate: function(inst) { - var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : - this._daylightSavingAdjust(new Date( - inst.currentYear, inst.currentMonth, inst.currentDay))); + _getDate: function( inst ) { + var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : + this._daylightSavingAdjust( new Date( + inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); return startDate; }, /* Attach the onxxx handlers. These are declared statically so * they work with static code transformers like Caja. */ - _attachHandlers: function(inst) { - var stepMonths = this._get(inst, "stepMonths"), + _attachHandlers: function( inst ) { + var stepMonths = this._get( inst, "stepMonths" ), id = "#" + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find("[data-handler]").map(function () { + inst.dpDiv.find( "[data-handler]" ).map( function() { var handler = { - prev: function () { - $.datepicker._adjustDate(id, -stepMonths, "M"); + prev: function() { + $.datepicker._adjustDate( id, -stepMonths, "M" ); }, - next: function () { - $.datepicker._adjustDate(id, +stepMonths, "M"); + next: function() { + $.datepicker._adjustDate( id, +stepMonths, "M" ); }, - hide: function () { + hide: function() { $.datepicker._hideDatepicker(); }, - today: function () { - $.datepicker._gotoToday(id); + today: function() { + $.datepicker._gotoToday( id ); }, - selectDay: function () { - $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); + selectDay: function() { + $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); return false; }, - selectMonth: function () { - $.datepicker._selectMonthYear(id, this, "M"); + selectMonth: function() { + $.datepicker._selectMonthYear( id, this, "M" ); return false; }, - selectYear: function () { - $.datepicker._selectMonthYear(id, this, "Y"); + selectYear: function() { + $.datepicker._selectMonthYear( id, this, "Y" ); return false; } }; - $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); - }); + $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); + } ); }, /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { + _generateHTML: function( inst ) { var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, monthNames, monthNamesShort, beforeShowDay, showOtherMonths, @@ -5384,33 +8812,33 @@ $.extend(Datepicker.prototype, { printDate, dRow, tbody, daySettings, otherMonth, unselectable, tempDate = new Date(), today = this._daylightSavingAdjust( - new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time - isRTL = this._get(inst, "isRTL"), - showButtonPanel = this._get(inst, "showButtonPanel"), - hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), - navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), - numMonths = this._getNumberOfMonths(inst), - showCurrentAtPos = this._get(inst, "showCurrentAtPos"), - stepMonths = this._get(inst, "stepMonths"), - isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), - currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), + new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time + isRTL = this._get( inst, "isRTL" ), + showButtonPanel = this._get( inst, "showButtonPanel" ), + hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), + navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), + numMonths = this._getNumberOfMonths( inst ), + showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), + stepMonths = this._get( inst, "stepMonths" ), + isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), + currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : + new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), drawMonth = inst.drawMonth - showCurrentAtPos, drawYear = inst.drawYear; - if (drawMonth < 0) { + if ( drawMonth < 0 ) { drawMonth += 12; drawYear--; } - if (maxDate) { - maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + if ( maxDate ) { + maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), + 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--; - if (drawMonth < 0) { + if ( drawMonth < 0 ) { drawMonth = 11; drawYear--; } @@ -5419,136 +8847,137 @@ $.extend(Datepicker.prototype, { inst.drawMonth = drawMonth; inst.drawYear = drawYear; - prevText = this._get(inst, "prevText"); - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), - this._getFormatConfig(inst))); + prevText = this._get( inst, "prevText" ); + prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); - prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ? "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + - " 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>")); + " 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>" ) ); - nextText = this._get(inst, "nextText"); - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), - this._getFormatConfig(inst))); + nextText = this._get( inst, "nextText" ); + nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); - next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ? "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + - " 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>")); - - currentText = this._get(inst, "currentText"); - gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); - currentText = (!navigationAsDateFormat ? currentText : - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - - controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + - this._get(inst, "closeText") + "</button>" : ""); - - 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' data-handler='today' data-event='click'" + - ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; - - firstDay = parseInt(this._get(inst, "firstDay"),10); - firstDay = (isNaN(firstDay) ? 0 : firstDay); - - showWeek = this._get(inst, "showWeek"); - dayNames = this._get(inst, "dayNames"); - dayNamesMin = this._get(inst, "dayNamesMin"); - monthNames = this._get(inst, "monthNames"); - monthNamesShort = this._get(inst, "monthNamesShort"); - beforeShowDay = this._get(inst, "beforeShowDay"); - showOtherMonths = this._get(inst, "showOtherMonths"); - selectOtherMonths = this._get(inst, "selectOtherMonths"); - defaultDate = this._getDefaultDate(inst); + " 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>" ) ); + + currentText = this._get( inst, "currentText" ); + gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); + currentText = ( !navigationAsDateFormat ? currentText : + this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); + + controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + + this._get( inst, "closeText" ) + "</button>" : "" ); + + 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' data-handler='today' data-event='click'" + + ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : ""; + + firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); + firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); + + showWeek = this._get( inst, "showWeek" ); + dayNames = this._get( inst, "dayNames" ); + dayNamesMin = this._get( inst, "dayNamesMin" ); + monthNames = this._get( inst, "monthNames" ); + monthNamesShort = this._get( inst, "monthNamesShort" ); + beforeShowDay = this._get( inst, "beforeShowDay" ); + showOtherMonths = this._get( inst, "showOtherMonths" ); + selectOtherMonths = this._get( inst, "selectOtherMonths" ); + defaultDate = this._getDefaultDate( inst ); html = ""; - dow; - for (row = 0; row < numMonths[0]; row++) { + + for ( row = 0; row < numMonths[ 0 ]; row++ ) { group = ""; this.maxRows = 4; - for (col = 0; col < numMonths[1]; col++) { - selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + for ( col = 0; col < numMonths[ 1 ]; col++ ) { + selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); cornerClass = " ui-corner-all"; calender = ""; - if (isMultiMonth) { + if ( isMultiMonth ) { calender += "<div class='ui-datepicker-group"; - if (numMonths[1] > 1) { - switch (col) { + 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; + 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, - row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + ( /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, + row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers "</div><table class='ui-datepicker-calendar'><thead>" + "<tr>"; - thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; + thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); + for ( dow = 0; dow < 7; dow++ ) { // days of the week + day = ( dow + firstDay ) % 7; + thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + + "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; } calender += thead + "</tr></thead><tbody>"; - daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); + if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { + inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); } - leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; + curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate + numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) this.maxRows = numRows; - printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows + printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); + for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows calender += "<tr>"; - tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + - this._get(inst, "calculateWeek")(printDate) + "</td>"); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + + this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); + for ( dow = 0; dow < 7; dow++ ) { // create date picker days + daySettings = ( beforeShowDay ? + beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); + otherMonth = ( printDate.getMonth() !== drawMonth ); + 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 - (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months - ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key - (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends + ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months + ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key + ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? + // or defaultDate is current printedDate and defaultDate is selectedDate - " " + 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() ? " " + this._currentClass : "") + // highlight selected day - (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) - ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title - (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // 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() ? " 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); + " " + 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() ? " " + this._currentClass : "" ) + // highlight selected day + ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) + ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title + ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // 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() ? " 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 ); } calender += tbody + "</tr>"; } drawMonth++; - if (drawMonth > 11) { + if ( drawMonth > 11 ) { drawMonth = 0; drawYear++; } - calender += "</tbody></table>" + (isMultiMonth ? "</div>" + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); + calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + + ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); group += calender; } html += group; @@ -5559,60 +8988,61 @@ $.extend(Datepicker.prototype, { }, /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { + _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort ) { var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get(inst, "changeMonth"), - changeYear = this._get(inst, "changeYear"), - showMonthAfterYear = this._get(inst, "showMonthAfterYear"), + changeMonth = this._get( inst, "changeMonth" ), + changeYear = this._get( inst, "changeYear" ), + showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), html = "<div class='ui-datepicker-title'>", monthHtml = ""; - // month selection - if (secondary || !changeMonth) { - monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; + // Month selection + if ( secondary || !changeMonth ) { + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; } else { - inMinYear = (minDate && minDate.getFullYear() === drawYear); - inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); + inMinYear = ( minDate && minDate.getFullYear() === drawYear ); + inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; - for ( month = 0; month < 12; month++) { - if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { + for ( month = 0; month < 12; month++ ) { + if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { monthHtml += "<option value='" + month + "'" + - (month === drawMonth ? " selected='selected'" : "") + - ">" + monthNamesShort[month] + "</option>"; + ( month === drawMonth ? " selected='selected'" : "" ) + + ">" + monthNamesShort[ month ] + "</option>"; } } monthHtml += "</select>"; } - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); + if ( !showMonthAfterYear ) { + html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); } - // year selection + // Year selection if ( !inst.yearshtml ) { inst.yearshtml = ""; - if (secondary || !changeYear) { + if ( secondary || !changeYear ) { html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; } else { + // determine range of years to display - years = this._get(inst, "yearRange").split(":"); + years = this._get( inst, "yearRange" ).split( ":" ); thisYear = new Date().getFullYear(); - 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); + 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 ); }; - year = determineYear(years[0]); - endYear = Math.max(year, determineYear(years[1] || "")); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + year = determineYear( years[ 0 ] ); + endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); + year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); + endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; - for (; year <= endYear; year++) { + for ( ; year <= endYear; year++ ) { inst.yearshtml += "<option value='" + year + "'" + - (year === drawYear ? " selected='selected'" : "") + + ( year === drawYear ? " selected='selected'" : "" ) + ">" + year + "</option>"; } inst.yearshtml += "</select>"; @@ -5622,168 +9052,168 @@ $.extend(Datepicker.prototype, { } } - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; + html += this._get( inst, "yearSuffix" ); + if ( showMonthAfterYear ) { + html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; } html += "</div>"; // Close datepicker_header return html; }, /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period === "Y" ? offset : 0), - month = inst.drawMonth + (period === "M" ? offset : 0), - day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), - date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); + _adjustInstDate: function( inst, offset, period ) { + var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), + month = inst.selectedMonth + ( period === "M" ? offset : 0 ), + day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), + 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(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); + if ( period === "M" || period === "Y" ) { + this._notifyChange( inst ); } }, /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - newDate = (minDate && date < minDate ? minDate : date); - return (maxDate && newDate > maxDate ? maxDate : newDate); + _restrictMinMax: function( inst, date ) { + var minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + newDate = ( minDate && date < minDate ? minDate : date ); + return ( maxDate && newDate > maxDate ? maxDate : newDate ); }, /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, "onChangeMonthYear"); - if (onChange) { - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); + _notifyChange: function( inst ) { + var onChange = this._get( inst, "onChangeMonthYear" ); + if ( onChange ) { + onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), + [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); } }, /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, "numberOfMonths"); - return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); + _getNumberOfMonths: function( inst ) { + var numMonths = this._get( inst, "numberOfMonths" ); + return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); }, /* 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); + _getMinMaxDate: function( inst, minMax ) { + return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); }, /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + _getDaysInMonth: function( year, month ) { + return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); }, /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); + _getFirstDayOfMonth: function( year, month ) { + return new Date( year, month, 1 ).getDay(); }, /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst), - date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + _canAdjustMonth: function( inst, offset, curYear, curMonth ) { + var numMonths = this._getNumberOfMonths( inst ), + 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())); + if ( offset < 0 ) { + date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); } - return this._isInRange(inst, date); + return this._isInRange( inst, date ); }, /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { + _isInRange: function( inst, date ) { var yearSplit, currentYear, - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), minYear = null, maxYear = null, - years = this._get(inst, "yearRange"); - if (years){ - yearSplit = years.split(":"); + years = this._get( inst, "yearRange" ); + if ( years ) { + yearSplit = years.split( ":" ); currentYear = new Date().getFullYear(); - minYear = parseInt(yearSplit[0], 10); - maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { + minYear = parseInt( yearSplit[ 0 ], 10 ); + maxYear = parseInt( yearSplit[ 1 ], 10 ); + if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { minYear += currentYear; } - if ( yearSplit[1].match(/[+\-].*/) ) { + if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { maxYear += currentYear; } } - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime()) && - (!minYear || date.getFullYear() >= minYear) && - (!maxYear || date.getFullYear() <= maxYear)); + return ( ( !minDate || date.getTime() >= minDate.getTime() ) && + ( !maxDate || date.getTime() <= maxDate.getTime() ) && + ( !minYear || date.getFullYear() >= minYear ) && + ( !maxYear || date.getFullYear() <= maxYear ) ); }, /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, "shortYearCutoff"); - shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + _getFormatConfig: function( inst ) { + var shortYearCutoff = this._get( inst, "shortYearCutoff" ); + shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); + return { shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), + monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; }, /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { + _formatDate: function( inst, day, month, year ) { + if ( !day ) { inst.currentDay = inst.selectedDay; inst.currentMonth = inst.selectedMonth; inst.currentYear = inst.selectedYear; } - var date = (day ? (typeof day === "object" ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); + var date = ( day ? ( typeof day === "object" ? day : + this._daylightSavingAdjust( new Date( year, month, day ) ) ) : + this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); + return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); } -}); +} ); /* * Bind hover events for datepicker elements. * Done via delegate so the binding only occurs once in the lifetime of the parent div. * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. */ -function datepicker_bindHover(dpDiv) { +function datepicker_bindHover( dpDiv ) { var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { - $(this).removeClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).removeClass("ui-datepicker-prev-hover"); + return dpDiv.on( "mouseout", selector, function() { + $( this ).removeClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-prev-hover" ); } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).removeClass("ui-datepicker-next-hover"); + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-next-hover" ); } - }) - .delegate( selector, "mouseover", datepicker_handleMouseover ); + } ) + .on( "mouseover", selector, datepicker_handleMouseover ); } function datepicker_handleMouseover() { - if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); + if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { + $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); + $( this ).addClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-prev-hover" ); } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-next-hover" ); } } } /* jQuery extend now ignores nulls! */ -function datepicker_extendRemove(target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] == null) { - target[name] = props[name]; +function datepicker_extendRemove( target, props ) { + $.extend( target, props ); + for ( var name in props ) { + if ( props[ name ] == null ) { + target[ name ] = props[ name ]; } } return target; @@ -5793,7 +9223,7 @@ function datepicker_extendRemove(target, props) { @param options string - a command, optionally followed by additional parameters or Object - settings for attaching new datepicker functionality @return jQuery object */ -$.fn.datepicker = function(options){ +$.fn.datepicker = function( options ) { /* Verify an empty collection wasn't passed - Fixes #6976 */ if ( !this.length ) { @@ -5801,55 +9231,322 @@ $.fn.datepicker = function(options){ } /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick); + if ( !$.datepicker.initialized ) { + $( document ).on( "mousedown", $.datepicker._checkExternalClick ); $.datepicker.initialized = true; } /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { - $("body").append($.datepicker.dpDiv); + if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { + $( "body" ).append( $.datepicker.dpDiv ); } - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); + var otherArgs = Array.prototype.slice.call( arguments, 1 ); + 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") { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); + if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { + return $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); } - return this.each(function() { + return this.each( function() { typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); + $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this ].concat( otherArgs ) ) : + $.datepicker._attachDatepicker( this, options ); + } ); }; $.datepicker = new Datepicker(); // singleton instance $.datepicker.initialized = false; $.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.11.4"; +$.datepicker.version = "1.12.1"; -var datepicker = $.datepicker; +var widgetsDatepicker = $.datepicker; + + +// This file is deprecated +var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + /*! - * jQuery UI Draggable 1.11.4 + * jQuery UI Mouse 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license + */ + +//>>label: Mouse +//>>group: Widgets +//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. +//>>docs: http://api.jqueryui.com/mouse/ + + + +var mouseHandled = false; +$( document ).on( "mouseup", function() { + mouseHandled = false; +} ); + +var widgetsMouse = $.widget( "ui.mouse", { + version: "1.12.1", + options: { + cancel: "input, textarea, button, select, option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .on( "mousedown." + this.widgetName, function( event ) { + return that._mouseDown( event ); + } ) + .on( "click." + this.widgetName, function( event ) { + if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, that.widgetName + ".preventClickEvent" ); + event.stopImmediatePropagation(); + return false; + } + } ); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.off( "." + this.widgetName ); + if ( this._mouseMoveDelegate ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + } + }, + + _mouseDown: function( event ) { + + // don't let more than one widget handle mouseStart + if ( mouseHandled ) { + return; + } + + this._mouseMoved = false; + + // We may have missed mouseup (out of window) + ( this._mouseStarted && this._mouseUp( event ) ); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = ( event.which === 1 ), + + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? + $( event.target ).closest( this.options.cancel ).length : false ); + if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if ( !this.mouseDelayMet ) { + this._mouseDelayTimer = setTimeout( function() { + that.mouseDelayMet = true; + }, this.options.delay ); + } + + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = ( this._mouseStart( event ) !== false ); + if ( !this._mouseStarted ) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, this.widgetName + ".preventClickEvent" ); + } + + // These delegates are required to keep context + this._mouseMoveDelegate = function( event ) { + return that._mouseMove( event ); + }; + this._mouseUpDelegate = function( event ) { + return that._mouseUp( event ); + }; + + this.document + .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function( event ) { + + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + + // IE mouseup check - mouseup happened when mouse was out of window + if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && + !event.button ) { + return this._mouseUp( event ); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + + // Support: Safari <=8 - 9 + // Safari sets which to 0 if you press any of the following keys + // during a drag (#14461) + if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || + event.originalEvent.metaKey || event.originalEvent.shiftKey ) { + this.ignoreMissingWhich = true; + } else if ( !this.ignoreMissingWhich ) { + return this._mouseUp( event ); + } + } + } + + if ( event.which || event.button ) { + this._mouseMoved = true; + } + + if ( this._mouseStarted ) { + this._mouseDrag( event ); + return event.preventDefault(); + } + + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = + ( this._mouseStart( this._mouseDownEvent, event ) !== false ); + ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); + } + + return !this._mouseStarted; + }, + + _mouseUp: function( event ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + if ( this._mouseStarted ) { + this._mouseStarted = false; + + if ( event.target === this._mouseDownEvent.target ) { + $.data( event.target, this.widgetName + ".preventClickEvent", true ); + } + + this._mouseStop( event ); + } + + if ( this._mouseDelayTimer ) { + clearTimeout( this._mouseDelayTimer ); + delete this._mouseDelayTimer; + } + + this.ignoreMissingWhich = false; + mouseHandled = false; + event.preventDefault(); + }, + + _mouseDistanceMet: function( event ) { + return ( Math.max( + Math.abs( this._mouseDownEvent.pageX - event.pageX ), + Math.abs( this._mouseDownEvent.pageY - event.pageY ) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function( /* event */ ) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function( /* event */ ) {}, + _mouseDrag: function( /* event */ ) {}, + _mouseStop: function( /* event */ ) {}, + _mouseCapture: function( /* event */ ) { return true; } +} ); + + + + +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +var plugin = $.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; + + if ( !set ) { + return; + } + + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || + instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } +}; + + + +var safeBlur = $.ui.safeBlur = function( element ) { + + // Support: IE9 - 10 only + // If the <body> is blurred, IE will switch windows, see #9420 + if ( element && element.nodeName.toLowerCase() !== "body" ) { + $( element ).trigger( "blur" ); + } +}; + + +/*! + * jQuery UI Draggable 1.12.1 + * http://jqueryui.com * - * http://api.jqueryui.com/draggable/ + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license */ +//>>label: Draggable +//>>group: Interactions +//>>description: Enables dragging functionality for any element. +//>>docs: http://api.jqueryui.com/draggable/ +//>>demos: http://jqueryui.com/draggable/ +//>>css.structure: ../../themes/base/draggable.css + + -$.widget("ui.draggable", $.ui.mouse, { - version: "1.11.4", +$.widget( "ui.draggable", $.ui.mouse, { + version: "1.12.1", widgetEventPrefix: "drag", options: { addClasses: true, @@ -5877,7 +9574,7 @@ $.widget("ui.draggable", $.ui.mouse, { stack: false, zIndex: false, - // callbacks + // Callbacks drag: null, start: null, stop: null @@ -5887,11 +9584,8 @@ $.widget("ui.draggable", $.ui.mouse, { if ( this.options.helper === "original" ) { this._setPositionRelative(); } - if (this.options.addClasses){ - this.element.addClass("ui-draggable"); - } - if (this.options.disabled){ - this.element.addClass("ui-draggable-disabled"); + if ( this.options.addClasses ) { + this._addClass( "ui-draggable" ); } this._setHandleClassName(); @@ -5911,27 +9605,27 @@ $.widget("ui.draggable", $.ui.mouse, { this.destroyOnClear = true; return; } - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); this._removeHandleClassName(); this._mouseDestroy(); }, - _mouseCapture: function(event) { + _mouseCapture: function( event ) { var o = this.options; - this._blurActiveElement( event ); - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { + // Among others, prevent a drag on a resizable-handle + if ( this.helper || o.disabled || + $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { return false; } //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) { + this.handle = this._getHandle( event ); + if ( !this.handle ) { return false; } + this._blurActiveElement( event ); + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); return true; @@ -5939,7 +9633,7 @@ $.widget("ui.draggable", $.ui.mouse, { }, _blockFrames: function( selector ) { - this.iframeBlocks = this.document.find( selector ).map(function() { + this.iframeBlocks = this.document.find( selector ).map( function() { var iframe = $( this ); return $( "<div>" ) @@ -5948,7 +9642,7 @@ $.widget("ui.draggable", $.ui.mouse, { .outerWidth( iframe.outerWidth() ) .outerHeight( iframe.outerHeight() ) .offset( iframe.offset() )[ 0 ]; - }); + } ); }, _unblockFrames: function() { @@ -5959,41 +9653,34 @@ $.widget("ui.draggable", $.ui.mouse, { }, _blurActiveElement: function( event ) { - var document = this.document[ 0 ]; + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + target = $( event.target ); - // Only need to blur if the event occurred on the draggable itself, see #10527 - if ( !this.handleElement.is( event.target ) ) { + // Don't blur if the event occurred on an element that is within + // the currently focused element + // See #10527, #12472 + if ( target.closest( activeElement ).length ) { return; } - // support: IE9 - // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> - try { - - // Support: IE9, IE10 - // If the <body> is blurred, IE will switch windows, see #9520 - if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { - - // Blur any element that currently has focus, see #4261 - $( document.activeElement ).blur(); - } - } catch ( error ) {} + // Blur any element that currently has focus, see #4261 + $.ui.safeBlur( activeElement ); }, - _mouseStart: function(event) { + _mouseStart: function( event ) { var o = this.options; //Create and append the visible helper - this.helper = this._createHelper(event); + this.helper = this._createHelper( event ); - this.helper.addClass("ui-draggable-dragging"); + this._addClass( this.helper, "ui-draggable-dragging" ); //Cache the helper size this._cacheHelperProportions(); //If ddmanager is used for droppables, set the global draggable - if ($.ui.ddmanager) { + if ( $.ui.ddmanager ) { $.ui.ddmanager.current = this; } @@ -6009,9 +9696,9 @@ $.widget("ui.draggable", $.ui.mouse, { this.cssPosition = this.helper.css( "position" ); this.scrollParent = this.helper.scrollParent( true ); this.offsetParent = this.helper.offsetParent(); - this.hasFixedAncestor = this.helper.parents().filter(function() { + this.hasFixedAncestor = this.helper.parents().filter( function() { return $( this ).css( "position" ) === "fixed"; - }).length > 0; + } ).length > 0; //The element's absolute position on the page minus margins this.positionAbs = this.element.offset(); @@ -6023,13 +9710,13 @@ $.widget("ui.draggable", $.ui.mouse, { this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); //Set a containment if given in the options this._setContainment(); //Trigger event + callbacks - if (this._trigger("start", event) === false) { + if ( this._trigger( "start", event ) === false ) { this._clear(); return false; } @@ -6038,19 +9725,18 @@ $.widget("ui.draggable", $.ui.mouse, { this._cacheHelperProportions(); //Prepare the droppable offsets - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); } - // Reset helper's right/bottom css if they're set and set explicit width/height instead - // as this prevents resizing of elements with right/bottom set (see #7772) - this._normalizeRightBottom(); + // Execute the drag once - this causes the helper not to be visible before getting its + // correct position + this._mouseDrag( event, true ); - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position - - //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) + // If the ddmanager is used for droppables, inform the manager that dragging has started + // (see #5003) if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStart(this, event); + $.ui.ddmanager.dragStart( this, event ); } return true; @@ -6071,7 +9757,8 @@ $.widget("ui.draggable", $.ui.mouse, { }; }, - _mouseDrag: function(event, noPropagation) { + _mouseDrag: function( event, noPropagation ) { + // reset any necessary cached properties (see #5009) if ( this.hasFixedAncestor ) { this.offset.parent = this._getParentOffset(); @@ -6079,13 +9766,13 @@ $.widget("ui.draggable", $.ui.mouse, { //Compute the helpers position this.position = this._generatePosition( event, true ); - this.positionAbs = this._convertPositionTo("absolute"); + this.positionAbs = this._convertPositionTo( "absolute" ); //Call plugins and callbacks and use the resulting position if something is returned - if (!noPropagation) { + if ( !noPropagation ) { var ui = this._uiHash(); - if (this._trigger("drag", event, ui) === false) { - this._mouseUp({}); + if ( this._trigger( "drag", event, ui ) === false ) { + this._mouseUp( new $.Event( "mouseup", event ) ); return false; } this.position = ui.position; @@ -6094,36 +9781,44 @@ $.widget("ui.draggable", $.ui.mouse, { this.helper[ 0 ].style.left = this.position.left + "px"; this.helper[ 0 ].style.top = this.position.top + "px"; - if ($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); } return false; }, - _mouseStop: function(event) { + _mouseStop: function( event ) { //If we are using droppables, inform the manager about the drop var that = this, dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) { - dropped = $.ui.ddmanager.drop(this, event); + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + dropped = $.ui.ddmanager.drop( this, event ); } //if a drop comes from outside (a sortable) - if (this.dropped) { + if ( this.dropped ) { dropped = this.dropped; this.dropped = false; } - if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if (that._trigger("stop", event) !== false) { - that._clear(); + 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 ) ) + ) { + $( this.helper ).animate( + this.originalPosition, + parseInt( this.options.revertDuration, 10 ), + function() { + if ( that._trigger( "stop", event ) !== false ) { + that._clear(); + } } - }); + ); } else { - if (this._trigger("stop", event) !== false) { + if ( this._trigger( "stop", event ) !== false ) { this._clear(); } } @@ -6134,24 +9829,27 @@ $.widget("ui.draggable", $.ui.mouse, { _mouseUp: function( event ) { this._unblockFrames(); - //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + // If the ddmanager is used for droppables, inform the manager that dragging has stopped + // (see #5003) if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStop(this, event); + $.ui.ddmanager.dragStop( this, event ); } // Only need to focus if the event occurred on the draggable itself, see #10527 if ( this.handleElement.is( event.target ) ) { - // The interaction is over; whether or not the click resulted in a drag, focus the element - this.element.focus(); + + // The interaction is over; whether or not the click resulted in a drag, + // focus the element + this.element.trigger( "focus" ); } - return $.ui.mouse.prototype._mouseUp.call(this, event); + return $.ui.mouse.prototype._mouseUp.call( this, event ); }, cancel: function() { - if (this.helper.is(".ui-draggable-dragging")) { - this._mouseUp({}); + if ( this.helper.is( ".ui-draggable-dragging" ) ) { + this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); } else { this._clear(); } @@ -6160,7 +9858,7 @@ $.widget("ui.draggable", $.ui.mouse, { }, - _getHandle: function(event) { + _getHandle: function( event ) { return this.options.handle ? !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : true; @@ -6169,14 +9867,14 @@ $.widget("ui.draggable", $.ui.mouse, { _setHandleClassName: function() { this.handleElement = this.options.handle ? this.element.find( this.options.handle ) : this.element; - this.handleElement.addClass( "ui-draggable-handle" ); + this._addClass( this.handleElement, "ui-draggable-handle" ); }, _removeHandleClassName: function() { - this.handleElement.removeClass( "ui-draggable-handle" ); + this._removeClass( this.handleElement, "ui-draggable-handle" ); }, - _createHelper: function(event) { + _createHelper: function( event ) { var o = this.options, helperIsFunction = $.isFunction( o.helper ), @@ -6186,19 +9884,22 @@ $.widget("ui.draggable", $.ui.mouse, { this.element.clone().removeAttr( "id" ) : this.element ); - if (!helper.parents("body").length) { - helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); + if ( !helper.parents( "body" ).length ) { + helper.appendTo( ( o.appendTo === "parent" ? + this.element[ 0 ].parentNode : + o.appendTo ) ); } - // http://bugs.jqueryui.com/ticket/9446 + // Http://bugs.jqueryui.com/ticket/9446 // a helper function can return the original element // which wouldn't have been set to relative in _create if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { this._setPositionRelative(); } - if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { - helper.css("position", "absolute"); + if ( helper[ 0 ] !== this.element[ 0 ] && + !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { + helper.css( "position", "absolute" ); } return helper; @@ -6211,23 +9912,23 @@ $.widget("ui.draggable", $.ui.mouse, { } }, - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); } - if ($.isArray(obj)) { - obj = { left: +obj[0], top: +obj[1] || 0 }; + if ( $.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; } - if ("left" in obj) { + if ( "left" in obj ) { this.offset.click.left = obj.left + this.margins.left; } - if ("right" in obj) { + if ( "right" in obj ) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } - if ("top" in obj) { + if ( "top" in obj ) { this.offset.click.top = obj.top + this.margins.top; } - if ("bottom" in obj) { + if ( "bottom" in obj ) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, @@ -6242,11 +9943,15 @@ $.widget("ui.draggable", $.ui.mouse, { var po = this.offsetParent.offset(), document = this.document[ 0 ]; - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } @@ -6256,8 +9961,8 @@ $.widget("ui.draggable", $.ui.mouse, { } return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) }; }, @@ -6271,18 +9976,20 @@ $.widget("ui.draggable", $.ui.mouse, { scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); return { - top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), - left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) }; }, _cacheMargins: function() { this.margins = { - left: (parseInt(this.element.css("marginLeft"), 10) || 0), - top: (parseInt(this.element.css("marginTop"), 10) || 0), - right: (parseInt(this.element.css("marginRight"), 10) || 0), - bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) + left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), + right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), + bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) }; }, @@ -6310,18 +10017,22 @@ $.widget("ui.draggable", $.ui.mouse, { this.containment = [ $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, - $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, - $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top + $( window ).scrollLeft() + $( window ).width() - + this.helperProportions.width - this.margins.left, + $( window ).scrollTop() + + ( $( window ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top ]; return; } - if ( o.containment === "document") { + if ( o.containment === "document" ) { this.containment = [ 0, 0, $( document ).width() - this.helperProportions.width - this.margins.left, - ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top + ( $( document ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top ]; return; } @@ -6345,8 +10056,10 @@ $.widget("ui.draggable", $.ui.mouse, { isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); this.containment = [ - ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), - ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), + ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), + ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - @@ -6363,9 +10076,9 @@ $.widget("ui.draggable", $.ui.mouse, { this.relativeContainer = c; }, - _convertPositionTo: function(d, pos) { + _convertPositionTo: function( d, pos ) { - if (!pos) { + if ( !pos ) { pos = this.position; } @@ -6374,16 +10087,32 @@ $.widget("ui.draggable", $.ui.mouse, { return { top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) + + // The absolute mouse position + pos.top + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) ), left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) + + // The absolute mouse position + pos.left + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) ) }; @@ -6413,7 +10142,7 @@ $.widget("ui.draggable", $.ui.mouse, { // If we are not dragging yet, we won't check for options if ( constrainPosition ) { if ( this.containment ) { - if ( this.relativeContainer ){ + if ( this.relativeContainer ) { co = this.relativeContainer.offset(); containment = [ this.containment[ 0 ] + co.left, @@ -6425,27 +10154,40 @@ $.widget("ui.draggable", $.ui.mouse, { containment = this.containment; } - if (event.pageX - this.offset.click.left < containment[0]) { - pageX = containment[0] + this.offset.click.left; + if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { + pageX = containment[ 0 ] + this.offset.click.left; } - if (event.pageY - this.offset.click.top < containment[1]) { - pageY = containment[1] + this.offset.click.top; + if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { + pageY = containment[ 1 ] + this.offset.click.top; } - if (event.pageX - this.offset.click.left > containment[2]) { - pageX = containment[2] + this.offset.click.left; + if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { + pageX = containment[ 2 ] + this.offset.click.left; } - if (event.pageY - this.offset.click.top > containment[3]) { - pageY = containment[3] + this.offset.click.top; + if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { + pageY = containment[ 3 ] + this.offset.click.top; } } - if (o.grid) { - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) - top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; - pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + if ( o.grid ) { + + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid + // argument errors in IE (see ticket #6950) + top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - + this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; + pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || + top - this.offset.click.top > containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; - left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; - pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + left = o.grid[ 0 ] ? this.originalPageX + + Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : + this.originalPageX; + pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || + left - this.offset.click.left > containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; } if ( o.axis === "y" ) { @@ -6459,26 +10201,46 @@ $.widget("ui.draggable", $.ui.mouse, { return { top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) + + // The absolute mouse position + pageY - + + // Click offset (relative to the element) + this.offset.click.top - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) ), left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) + + // The absolute mouse position + pageX - + + // Click offset (relative to the element) + this.offset.click.left - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) ) }; }, _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); - if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { + this._removeClass( this.helper, "ui-draggable-dragging" ); + if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { this.helper.remove(); } this.helper = null; @@ -6488,17 +10250,6 @@ $.widget("ui.draggable", $.ui.mouse, { } }, - _normalizeRightBottom: function() { - if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { - this.helper.width( this.helper.width() ); - this.helper.css( "right", "auto" ); - } - if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { - this.helper.height( this.helper.height() ); - this.helper.css( "bottom", "auto" ); - } - }, - // From now on bulk stuff - mainly helpers _trigger: function( type, event, ui ) { @@ -6524,33 +10275,33 @@ $.widget("ui.draggable", $.ui.mouse, { }; } -}); +} ); $.ui.plugin.add( "draggable", "connectToSortable", { start: function( event, ui, draggable ) { var uiSortable = $.extend( {}, ui, { item: draggable.element - }); + } ); draggable.sortables = []; - $( draggable.options.connectToSortable ).each(function() { + $( draggable.options.connectToSortable ).each( function() { var sortable = $( this ).sortable( "instance" ); if ( sortable && !sortable.options.disabled ) { draggable.sortables.push( sortable ); - // refreshPositions is called at drag start to refresh the containerCache + // RefreshPositions is called at drag start to refresh the containerCache // which is used in drag. This ensures it's initialized and synchronized // with any changes that might have happened on the page since initialization. sortable.refreshPositions(); - sortable._trigger("activate", event, uiSortable); + sortable._trigger( "activate", event, uiSortable ); } - }); + } ); }, stop: function( event, ui, draggable ) { var uiSortable = $.extend( {}, ui, { item: draggable.element - }); + } ); draggable.cancelHelperRemoval = false; @@ -6573,12 +10324,13 @@ $.ui.plugin.add( "draggable", "connectToSortable", { left: sortable.placeholder.css( "left" ) }; - sortable._mouseStop(event); + sortable._mouseStop( event ); // Once drag has ended, the sortable should return to using // its original helper, not the shared helper from draggable sortable.options.helper = sortable.options._helper; } else { + // Prevent this Sortable from removing the helper. // However, don't set the draggable to remove the helper // either as another connected Sortable may yet handle the removal. @@ -6586,7 +10338,7 @@ $.ui.plugin.add( "draggable", "connectToSortable", { sortable._trigger( "deactivate", event, uiSortable ); } - }); + } ); }, drag: function( event, ui, draggable ) { $.each( draggable.sortables, function() { @@ -6602,6 +10354,7 @@ $.ui.plugin.add( "draggable", "connectToSortable", { innermostIntersecting = true; $.each( draggable.sortables, function() { + // Copy over variables that sortable's _intersectsWith uses this.positionAbs = draggable.positionAbs; this.helperProportions = draggable.helperProportions; @@ -6614,10 +10367,11 @@ $.ui.plugin.add( "draggable", "connectToSortable", { } return innermostIntersecting; - }); + } ); } if ( innermostIntersecting ) { + // If it intersects, we use a little isOver variable and set it once, // so that the move-in stuff gets fired only once. if ( !sortable.isOver ) { @@ -6662,21 +10416,23 @@ $.ui.plugin.add( "draggable", "connectToSortable", { // adding to one sortable changes the location of the other sortables (#9675) $.each( draggable.sortables, function() { this.refreshPositions(); - }); + } ); - // hack so receive/update callbacks work (mostly) + // Hack so receive/update callbacks work (mostly) draggable.currentItem = draggable.element; sortable.fromOutside = draggable; } if ( sortable.currentItem ) { sortable._mouseDrag( event ); + // Copy the sortable's position because the draggable's can potentially reflect // a relative position, while sortable is always absolute, which the dragged // element has now become. (#8809) ui.position = sortable.position; } } else { + // If it doesn't intersect with the sortable, and it intersected before, // we fake the drag stop of the sortable, but make sure it doesn't remove // the helper by using cancelHelperRemoval. @@ -6693,7 +10449,7 @@ $.ui.plugin.add( "draggable", "connectToSortable", { sortable._trigger( "out", event, sortable._uiHash( sortable ) ); sortable._mouseStop( event, true ); - // restore sortable behaviors that were modfied + // Restore sortable behaviors that were modfied // when the draggable entered the sortable area (#9481) sortable.options.revert = sortable.options._revert; sortable.options.helper = sortable.options._helper; @@ -6717,55 +10473,56 @@ $.ui.plugin.add( "draggable", "connectToSortable", { // from one sortable changes the location of other sortables (#9675) $.each( draggable.sortables, function() { this.refreshPositions(); - }); + } ); } } - }); + } ); } -}); +} ); -$.ui.plugin.add("draggable", "cursor", { +$.ui.plugin.add( "draggable", "cursor", { start: function( event, ui, instance ) { var t = $( "body" ), o = instance.options; - if (t.css("cursor")) { - o._cursor = t.css("cursor"); + if ( t.css( "cursor" ) ) { + o._cursor = t.css( "cursor" ); } - t.css("cursor", o.cursor); + t.css( "cursor", o.cursor ); }, stop: function( event, ui, instance ) { var o = instance.options; - if (o._cursor) { - $("body").css("cursor", o._cursor); + if ( o._cursor ) { + $( "body" ).css( "cursor", o._cursor ); } } -}); +} ); -$.ui.plugin.add("draggable", "opacity", { +$.ui.plugin.add( "draggable", "opacity", { start: function( event, ui, instance ) { var t = $( ui.helper ), o = instance.options; - if (t.css("opacity")) { - o._opacity = t.css("opacity"); + if ( t.css( "opacity" ) ) { + o._opacity = t.css( "opacity" ); } - t.css("opacity", o.opacity); + t.css( "opacity", o.opacity ); }, stop: function( event, ui, instance ) { var o = instance.options; - if (o._opacity) { - $(ui.helper).css("opacity", o._opacity); + if ( o._opacity ) { + $( ui.helper ).css( "opacity", o._opacity ); } } -}); +} ); -$.ui.plugin.add("draggable", "scroll", { +$.ui.plugin.add( "draggable", "scroll", { start: function( event, ui, i ) { if ( !i.scrollParentNotHidden ) { i.scrollParentNotHidden = i.helper.scrollParent( false ); } - if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && + i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { i.overflowOffset = i.scrollParentNotHidden.offset(); } }, @@ -6778,7 +10535,8 @@ $.ui.plugin.add("draggable", "scroll", { if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { if ( !o.axis || o.axis !== "x" ) { - if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < + o.scrollSensitivity ) { scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; @@ -6786,7 +10544,8 @@ $.ui.plugin.add("draggable", "scroll", { } if ( !o.axis || o.axis !== "y" ) { - if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < + o.scrollSensitivity ) { scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; @@ -6795,49 +10554,56 @@ $.ui.plugin.add("draggable", "scroll", { } else { - if (!o.axis || o.axis !== "x") { - if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + if ( !o.axis || o.axis !== "x" ) { + if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); + } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); } } - if (!o.axis || o.axis !== "y") { - if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + if ( !o.axis || o.axis !== "y" ) { + if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() - o.scrollSpeed + ); + } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() + o.scrollSpeed + ); } } } - if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(i, event); + if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( i, event ); } } -}); +} ); -$.ui.plugin.add("draggable", "snap", { +$.ui.plugin.add( "draggable", "snap", { start: function( event, ui, i ) { var o = i.options; i.snapElements = []; - $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { - var $t = $(this), - $o = $t.offset(); - if (this !== i.element[0]) { - i.snapElements.push({ - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - }); - } - }); + $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) + .each( function() { + var $t = $( this ), + $o = $t.offset(); + if ( this !== i.element[ 0 ] ) { + i.snapElements.push( { + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + } ); + } + } ); }, drag: function( event, ui, inst ) { @@ -6848,125 +10614,171 @@ $.ui.plugin.add("draggable", "snap", { x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - for (i = inst.snapElements.length - 1; i >= 0; i--){ - - l = inst.snapElements[i].left - inst.margins.left; - r = l + inst.snapElements[i].width; - t = inst.snapElements[i].top - inst.margins.top; - b = t + inst.snapElements[i].height; - - if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { - if (inst.snapElements[i].snapping) { - (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { + + l = inst.snapElements[ i ].left - inst.margins.left; + r = l + inst.snapElements[ i ].width; + t = inst.snapElements[ i ].top - inst.margins.top; + b = t + inst.snapElements[ i ].height; + + if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || + !$.contains( inst.snapElements[ i ].item.ownerDocument, + inst.snapElements[ i ].item ) ) { + if ( inst.snapElements[ i ].snapping ) { + ( inst.options.snap.release && + inst.options.snap.release.call( + inst.element, + event, + $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) + ) ); } - inst.snapElements[i].snapping = false; + inst.snapElements[ i ].snapping = false; continue; } - if (o.snapMode !== "inner") { - ts = Math.abs(t - y2) <= d; - bs = Math.abs(b - y1) <= d; - ls = Math.abs(l - x2) <= d; - rs = Math.abs(r - x1) <= d; - if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; + if ( o.snapMode !== "inner" ) { + ts = Math.abs( t - y2 ) <= d; + bs = Math.abs( b - y1 ) <= d; + ls = Math.abs( l - x2 ) <= d; + rs = Math.abs( r - x1 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t - inst.helperProportions.height, + left: 0 + } ).top; } - if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b, + left: 0 + } ).top; } - if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l - inst.helperProportions.width + } ).left; } - if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r + } ).left; } } - first = (ts || bs || ls || rs); + first = ( ts || bs || ls || rs ); - if (o.snapMode !== "outer") { - ts = Math.abs(t - y1) <= d; - bs = Math.abs(b - y2) <= d; - ls = Math.abs(l - x1) <= d; - rs = Math.abs(r - x2) <= d; - if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; + if ( o.snapMode !== "outer" ) { + ts = Math.abs( t - y1 ) <= d; + bs = Math.abs( b - y2 ) <= d; + ls = Math.abs( l - x1 ) <= d; + rs = Math.abs( r - x2 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t, + left: 0 + } ).top; } - if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b - inst.helperProportions.height, + left: 0 + } ).top; } - if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l + } ).left; } - if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r - inst.helperProportions.width + } ).left; } } - if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { + ( inst.options.snap.snap && + inst.options.snap.snap.call( + inst.element, + event, + $.extend( inst._uiHash(), { + snapItem: inst.snapElements[ i ].item + } ) ) ); } - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); + inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); } } -}); +} ); -$.ui.plugin.add("draggable", "stack", { +$.ui.plugin.add( "draggable", "stack", { start: function( event, ui, instance ) { var min, o = instance.options, - 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; } - - min = parseInt($(group[0]).css("zIndex"), 10) || 0; - $(group).each(function(i) { - $(this).css("zIndex", min + i); - }); - this.css("zIndex", (min + group.length)); + 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; } + + min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; + $( group ).each( function( i ) { + $( this ).css( "zIndex", min + i ); + } ); + this.css( "zIndex", ( min + group.length ) ); } -}); +} ); -$.ui.plugin.add("draggable", "zIndex", { +$.ui.plugin.add( "draggable", "zIndex", { start: function( event, ui, instance ) { var t = $( ui.helper ), o = instance.options; - if (t.css("zIndex")) { - o._zIndex = t.css("zIndex"); + if ( t.css( "zIndex" ) ) { + o._zIndex = t.css( "zIndex" ); } - t.css("zIndex", o.zIndex); + t.css( "zIndex", o.zIndex ); }, stop: function( event, ui, instance ) { var o = instance.options; - if (o._zIndex) { - $(ui.helper).css("zIndex", o._zIndex); + if ( o._zIndex ) { + $( ui.helper ).css( "zIndex", o._zIndex ); } } -}); +} ); -var draggable = $.ui.draggable; +var widgetsDraggable = $.ui.draggable; /*! - * jQuery UI Resizable 1.11.4 + * jQuery UI Resizable 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/resizable/ */ +//>>label: Resizable +//>>group: Interactions +//>>description: Enables resize functionality for any element. +//>>docs: http://api.jqueryui.com/resizable/ +//>>demos: http://jqueryui.com/resizable/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/resizable.css +//>>css.theme: ../../themes/base/theme.css + -$.widget("ui.resizable", $.ui.mouse, { - version: "1.11.4", + +$.widget( "ui.resizable", $.ui.mouse, { + version: "1.12.1", widgetEventPrefix: "resize", options: { alsoResize: false, @@ -6975,6 +10787,9 @@ $.widget("ui.resizable", $.ui.mouse, { animateEasing: "swing", aspectRatio: false, autoHide: false, + classes: { + "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" + }, containment: false, ghost: false, grid: false, @@ -6984,26 +10799,27 @@ $.widget("ui.resizable", $.ui.mouse, { maxWidth: null, minHeight: 10, minWidth: 10, + // See #7960 zIndex: 90, - // callbacks + // Callbacks resize: null, start: null, stop: null }, _num: function( value ) { - return parseInt( value, 10 ) || 0; + return parseFloat( value ) || 0; }, _isNumber: function( value ) { - return !isNaN( parseInt( value, 10 ) ); + return !isNaN( parseFloat( value ) ); }, _hasScroll: function( el, a ) { - if ( $( el ).css( "overflow" ) === "hidden") { + if ( $( el ).css( "overflow" ) === "hidden" ) { return false; } @@ -7025,30 +10841,30 @@ $.widget("ui.resizable", $.ui.mouse, { _create: function() { - var n, i, handle, axis, hname, - that = this, - o = this.options; - this.element.addClass("ui-resizable"); + var margins, + o = this.options, + that = this; + this._addClass( "ui-resizable" ); - $.extend(this, { - _aspectRatio: !!(o.aspectRatio), + $.extend( this, { + _aspectRatio: !!( o.aspectRatio ), aspectRatio: o.aspectRatio, originalElement: this.element, _proportionallyResizeElements: [], _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null - }); + } ); // Wrap the element if it cannot hold child nodes - if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) { + if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { this.element.wrap( - $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ - position: this.element.css("position"), + $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( { + position: this.element.css( "position" ), width: this.element.outerWidth(), height: this.element.outerHeight(), - top: this.element.css("top"), - left: this.element.css("left") - }) + top: this.element.css( "top" ), + left: this.element.css( "left" ) + } ) ); this.element = this.element.parent().data( @@ -7057,38 +10873,110 @@ $.widget("ui.resizable", $.ui.mouse, { this.elementIsWrapper = true; - this.element.css({ - marginLeft: this.originalElement.css("marginLeft"), - marginTop: this.originalElement.css("marginTop"), - marginRight: this.originalElement.css("marginRight"), - marginBottom: this.originalElement.css("marginBottom") - }); - this.originalElement.css({ - marginLeft: 0, - marginTop: 0, - marginRight: 0, - marginBottom: 0 - }); + margins = { + marginTop: this.originalElement.css( "marginTop" ), + marginRight: this.originalElement.css( "marginRight" ), + marginBottom: this.originalElement.css( "marginBottom" ), + marginLeft: this.originalElement.css( "marginLeft" ) + }; + + this.element.css( margins ); + this.originalElement.css( "margin", 0 ); + // support: Safari // Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css("resize"); - this.originalElement.css("resize", "none"); + this.originalResizeStyle = this.originalElement.css( "resize" ); + this.originalElement.css( "resize", "none" ); - this._proportionallyResizeElements.push( this.originalElement.css({ + this._proportionallyResizeElements.push( this.originalElement.css( { position: "static", zoom: 1, display: "block" - }) ); + } ) ); - // support: IE9 + // Support: IE9 // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css("margin") }); + this.originalElement.css( margins ); this._proportionallyResize(); } + this._setupHandles(); + + if ( o.autoHide ) { + $( this.element ) + .on( "mouseenter", function() { + if ( o.disabled ) { + return; + } + that._removeClass( "ui-resizable-autohide" ); + that._handles.show(); + } ) + .on( "mouseleave", function() { + if ( o.disabled ) { + return; + } + if ( !that.resizing ) { + that._addClass( "ui-resizable-autohide" ); + that._handles.hide(); + } + } ); + } + + this._mouseInit(); + }, + + _destroy: function() { + + this._mouseDestroy(); + + var wrapper, + _destroy = function( exp ) { + $( exp ) + .removeData( "resizable" ) + .removeData( "ui-resizable" ) + .off( ".resizable" ) + .find( ".ui-resizable-handle" ) + .remove(); + }; + + // TODO: Unwrap at same DOM position + if ( this.elementIsWrapper ) { + _destroy( this.element ); + wrapper = this.element; + this.originalElement.css( { + position: wrapper.css( "position" ), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css( "top" ), + left: wrapper.css( "left" ) + } ).insertAfter( wrapper ); + wrapper.remove(); + } + + this.originalElement.css( "resize", this.originalResizeStyle ); + _destroy( this.originalElement ); + + return this; + }, + + _setOption: function( key, value ) { + this._super( key, value ); + + switch ( key ) { + case "handles": + this._removeHandles(); + this._setupHandles(); + break; + default: + break; + } + }, + + _setupHandles: function() { + var o = this.options, handle, i, n, hname, axis, that = this; this.handles = o.handles || - ( !$(".ui-resizable-handle", this.element).length ? + ( !$( ".ui-resizable-handle", this.element ).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", @@ -7103,59 +10991,59 @@ $.widget("ui.resizable", $.ui.mouse, { this._handles = $(); if ( this.handles.constructor === String ) { - if ( this.handles === "all") { + if ( this.handles === "all" ) { this.handles = "n,e,s,w,se,sw,ne,nw"; } - n = this.handles.split(","); + n = this.handles.split( "," ); this.handles = {}; - for (i = 0; i < n.length; i++) { + for ( i = 0; i < n.length; i++ ) { - handle = $.trim(n[i]); + handle = $.trim( n[ i ] ); hname = "ui-resizable-" + handle; - axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); - - axis.css({ zIndex: o.zIndex }); + axis = $( "<div>" ); + this._addClass( axis, "ui-resizable-handle " + hname ); - // TODO : What's going on here? - if ("se" === handle) { - axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); - } + axis.css( { zIndex: o.zIndex } ); - this.handles[handle] = ".ui-resizable-" + handle; - this.element.append(axis); + this.handles[ handle ] = ".ui-resizable-" + handle; + this.element.append( axis ); } } - this._renderAxis = function(target) { + this._renderAxis = function( target ) { var i, axis, padPos, padWrapper; target = target || this.element; - for (i in this.handles) { + for ( i in this.handles ) { - if (this.handles[i].constructor === String) { - this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); + if ( this.handles[ i ].constructor === String ) { + this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { this.handles[ i ] = $( this.handles[ i ] ); - this._on( this.handles[ i ], { "mousedown": that._mouseDown }); + this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); } - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) { - - axis = $(this.handles[i], this.element); + if ( this.elementIsWrapper && + this.originalElement[ 0 ] + .nodeName + .match( /^(textarea|input|select|button)$/i ) ) { + axis = $( this.handles[ i ], this.element ); - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); + padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? + axis.outerHeight() : + axis.outerWidth(); padPos = [ "padding", - /ne|nw|n/.test(i) ? "Top" : - /se|sw|s/.test(i) ? "Bottom" : - /^e$/.test(i) ? "Right" : "Left" ].join(""); + /ne|nw|n/.test( i ) ? "Top" : + /se|sw|s/.test( i ) ? "Bottom" : + /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); - target.css(padPos, padWrapper); + target.css( padPos, padWrapper ); this._proportionallyResize(); } @@ -7165,87 +11053,37 @@ $.widget("ui.resizable", $.ui.mouse, { }; // TODO: make renderAxis a prototype function - this._renderAxis(this.element); + this._renderAxis( this.element ); this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); this._handles.disableSelection(); - this._handles.mouseover(function() { - if (!that.resizing) { - if (this.className) { - axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + this._handles.on( "mouseover", function() { + if ( !that.resizing ) { + if ( this.className ) { + axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); } - that.axis = axis && axis[1] ? axis[1] : "se"; + that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; } - }); + } ); - if (o.autoHide) { + if ( o.autoHide ) { this._handles.hide(); - $(this.element) - .addClass("ui-resizable-autohide") - .mouseenter(function() { - if (o.disabled) { - return; - } - $(this).removeClass("ui-resizable-autohide"); - that._handles.show(); - }) - .mouseleave(function() { - if (o.disabled) { - return; - } - if (!that.resizing) { - $(this).addClass("ui-resizable-autohide"); - that._handles.hide(); - } - }); + this._addClass( "ui-resizable-autohide" ); } - - this._mouseInit(); }, - _destroy: function() { - - this._mouseDestroy(); - - var wrapper, - _destroy = function(exp) { - $(exp) - .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable") - .removeData("ui-resizable") - .unbind(".resizable") - .find(".ui-resizable-handle") - .remove(); - }; - - // TODO: Unwrap at same DOM position - if (this.elementIsWrapper) { - _destroy(this.element); - wrapper = this.element; - this.originalElement.css({ - position: wrapper.css("position"), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css("top"), - left: wrapper.css("left") - }).insertAfter( wrapper ); - wrapper.remove(); - } - - this.originalElement.css("resize", this.originalResizeStyle); - _destroy(this.originalElement); - - return this; + _removeHandles: function() { + this._handles.remove(); }, - _mouseCapture: function(event) { + _mouseCapture: function( event ) { var i, handle, capture = false; - for (i in this.handles) { - handle = $(this.handles[i])[0]; - if (handle === event.target || $.contains(handle, event.target)) { + for ( i in this.handles ) { + handle = $( this.handles[ i ] )[ 0 ]; + if ( handle === event.target || $.contains( handle, event.target ) ) { capture = true; } } @@ -7253,7 +11091,7 @@ $.widget("ui.resizable", $.ui.mouse, { return !this.options.disabled && capture; }, - _mouseStart: function(event) { + _mouseStart: function( event ) { var curleft, curtop, cursor, o = this.options, @@ -7263,12 +11101,12 @@ $.widget("ui.resizable", $.ui.mouse, { this._renderProxy(); - curleft = this._num(this.helper.css("left")); - curtop = this._num(this.helper.css("top")); + curleft = this._num( this.helper.css( "left" ) ); + curtop = this._num( this.helper.css( "top" ) ); - if (o.containment) { - curleft += $(o.containment).scrollLeft() || 0; - curtop += $(o.containment).scrollTop() || 0; + if ( o.containment ) { + curleft += $( o.containment ).scrollLeft() || 0; + curtop += $( o.containment ).scrollTop() || 0; } this.offset = this.helper.offset(); @@ -7298,45 +11136,45 @@ $.widget("ui.resizable", $.ui.mouse, { this.originalPosition = { left: curleft, top: curtop }; this.originalMousePosition = { left: event.pageX, top: event.pageY }; - this.aspectRatio = (typeof o.aspectRatio === "number") ? + this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? o.aspectRatio : - ((this.originalSize.width / this.originalSize.height) || 1); + ( ( this.originalSize.width / this.originalSize.height ) || 1 ); - cursor = $(".ui-resizable-" + this.axis).css("cursor"); - $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); + cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); + $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); - el.addClass("ui-resizable-resizing"); - this._propagate("start", event); + this._addClass( "ui-resizable-resizing" ); + this._propagate( "start", event ); return true; }, - _mouseDrag: function(event) { + _mouseDrag: function( event ) { var data, props, smp = this.originalMousePosition, a = this.axis, - dx = (event.pageX - smp.left) || 0, - dy = (event.pageY - smp.top) || 0, - trigger = this._change[a]; + dx = ( event.pageX - smp.left ) || 0, + dy = ( event.pageY - smp.top ) || 0, + trigger = this._change[ a ]; this._updatePrevProperties(); - if (!trigger) { + if ( !trigger ) { return false; } - data = trigger.apply(this, [ event, dx, dy ]); + data = trigger.apply( this, [ event, dx, dy ] ); - this._updateVirtualBoundaries(event.shiftKey); - if (this._aspectRatio || event.shiftKey) { - data = this._updateRatio(data, event); + this._updateVirtualBoundaries( event.shiftKey ); + if ( this._aspectRatio || event.shiftKey ) { + data = this._updateRatio( data, event ); } - data = this._respectSize(data, event); + data = this._respectSize( data, event ); - this._updateCache(data); + this._updateCache( data ); - this._propagate("resize", event); + this._propagate( "resize", event ); props = this._applyChanges(); @@ -7353,47 +11191,47 @@ $.widget("ui.resizable", $.ui.mouse, { return false; }, - _mouseStop: function(event) { + _mouseStop: function( event ) { this.resizing = false; var pr, ista, soffseth, soffsetw, s, left, top, o = this.options, that = this; - if (this._helper) { + if ( this._helper ) { pr = this._proportionallyResizeElements; - ista = pr.length && (/textarea/i).test(pr[0].nodeName); - soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); + soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; soffsetw = ista ? 0 : that.sizeDiff.width; s = { - width: (that.helper.width() - soffsetw), - height: (that.helper.height() - soffseth) + width: ( that.helper.width() - soffsetw ), + height: ( that.helper.height() - soffseth ) }; - left = (parseInt(that.element.css("left"), 10) + - (that.position.left - that.originalPosition.left)) || null; - top = (parseInt(that.element.css("top"), 10) + - (that.position.top - that.originalPosition.top)) || null; + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null; + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; - if (!o.animate) { - this.element.css($.extend(s, { top: top, left: left })); + if ( !o.animate ) { + this.element.css( $.extend( s, { top: top, left: left } ) ); } - that.helper.height(that.size.height); - that.helper.width(that.size.width); + that.helper.height( that.size.height ); + that.helper.width( that.size.width ); - if (this._helper && !o.animate) { + if ( this._helper && !o.animate ) { this._proportionallyResize(); } } - $("body").css("cursor", "auto"); + $( "body" ).css( "cursor", "auto" ); - this.element.removeClass("ui-resizable-resizing"); + this._removeClass( "ui-resizable-resizing" ); - this._propagate("stop", event); + this._propagate( "stop", event ); - if (this._helper) { + if ( this._helper ) { this.helper.remove(); } @@ -7433,51 +11271,51 @@ $.widget("ui.resizable", $.ui.mouse, { return props; }, - _updateVirtualBoundaries: function(forceAspectRatio) { + _updateVirtualBoundaries: function( forceAspectRatio ) { var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, o = this.options; b = { - minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity + minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, + maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, + minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, + maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity }; - if (this._aspectRatio || forceAspectRatio) { + if ( this._aspectRatio || forceAspectRatio ) { pMinWidth = b.minHeight * this.aspectRatio; pMinHeight = b.minWidth / this.aspectRatio; pMaxWidth = b.maxHeight * this.aspectRatio; pMaxHeight = b.maxWidth / this.aspectRatio; - if (pMinWidth > b.minWidth) { + if ( pMinWidth > b.minWidth ) { b.minWidth = pMinWidth; } - if (pMinHeight > b.minHeight) { + if ( pMinHeight > b.minHeight ) { b.minHeight = pMinHeight; } - if (pMaxWidth < b.maxWidth) { + if ( pMaxWidth < b.maxWidth ) { b.maxWidth = pMaxWidth; } - if (pMaxHeight < b.maxHeight) { + if ( pMaxHeight < b.maxHeight ) { b.maxHeight = pMaxHeight; } } this._vBoundaries = b; }, - _updateCache: function(data) { + _updateCache: function( data ) { this.offset = this.helper.offset(); - if (this._isNumber(data.left)) { + if ( this._isNumber( data.left ) ) { this.position.left = data.left; } - if (this._isNumber(data.top)) { + if ( this._isNumber( data.top ) ) { this.position.top = data.top; } - if (this._isNumber(data.height)) { + if ( this._isNumber( data.height ) ) { this.size.height = data.height; } - if (this._isNumber(data.width)) { + if ( this._isNumber( data.width ) ) { this.size.width = data.width; } }, @@ -7488,19 +11326,19 @@ $.widget("ui.resizable", $.ui.mouse, { csize = this.size, a = this.axis; - if (this._isNumber(data.height)) { - data.width = (data.height * this.aspectRatio); - } else if (this._isNumber(data.width)) { - data.height = (data.width / this.aspectRatio); + if ( this._isNumber( data.height ) ) { + data.width = ( data.height * this.aspectRatio ); + } else if ( this._isNumber( data.width ) ) { + data.height = ( data.width / this.aspectRatio ); } - if (a === "sw") { - data.left = cpos.left + (csize.width - data.width); + if ( a === "sw" ) { + data.left = cpos.left + ( csize.width - data.width ); data.top = null; } - if (a === "nw") { - data.top = cpos.top + (csize.height - data.height); - data.left = cpos.left + (csize.width - data.width); + if ( a === "nw" ) { + data.top = cpos.top + ( csize.height - data.height ); + data.left = cpos.left + ( csize.width - data.width ); } return data; @@ -7510,43 +11348,43 @@ $.widget("ui.resizable", $.ui.mouse, { var o = this._vBoundaries, a = this.axis, - ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), - ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), - isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), + ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), + isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), + isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), dw = this.originalPosition.left + this.originalSize.width, - dh = this.position.top + this.size.height, - cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); - if (isminw) { + dh = this.originalPosition.top + this.originalSize.height, + cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); + if ( isminw ) { data.width = o.minWidth; } - if (isminh) { + if ( isminh ) { data.height = o.minHeight; } - if (ismaxw) { + if ( ismaxw ) { data.width = o.maxWidth; } - if (ismaxh) { + if ( ismaxh ) { data.height = o.maxHeight; } - if (isminw && cw) { + if ( isminw && cw ) { data.left = dw - o.minWidth; } - if (ismaxw && cw) { + if ( ismaxw && cw ) { data.left = dw - o.maxWidth; } - if (isminh && ch) { + if ( isminh && ch ) { data.top = dh - o.minHeight; } - if (ismaxh && ch) { + if ( ismaxh && ch ) { data.top = dh - o.maxHeight; } // Fixing jump error on top/left - bug #2330 - if (!data.width && !data.height && !data.left && data.top) { + if ( !data.width && !data.height && !data.left && data.top ) { data.top = null; - } else if (!data.width && !data.height && !data.top && data.left) { + } else if ( !data.width && !data.height && !data.top && data.left ) { data.left = null; } @@ -7570,8 +11408,8 @@ $.widget("ui.resizable", $.ui.mouse, { ]; for ( ; i < 4; i++ ) { - widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); - widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); + widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); + widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); } return { @@ -7582,7 +11420,7 @@ $.widget("ui.resizable", $.ui.mouse, { _proportionallyResize: function() { - if (!this._proportionallyResizeElements.length) { + if ( !this._proportionallyResizeElements.length ) { return; } @@ -7590,20 +11428,20 @@ $.widget("ui.resizable", $.ui.mouse, { i = 0, element = this.helper || this.element; - for ( ; i < this._proportionallyResizeElements.length; i++) { + for ( ; i < this._proportionallyResizeElements.length; i++ ) { - prel = this._proportionallyResizeElements[i]; + prel = this._proportionallyResizeElements[ i ]; // TODO: Seems like a bug to cache this.outerDimensions // considering that we are in a loop. - if (!this.outerDimensions) { + if ( !this.outerDimensions ) { this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); } - prel.css({ - height: (element.height() - this.outerDimensions.height) || 0, - width: (element.width() - this.outerDimensions.width) || 0 - }); + prel.css( { + height: ( element.height() - this.outerDimensions.height ) || 0, + width: ( element.width() - this.outerDimensions.width ) || 0 + } ); } @@ -7614,21 +11452,22 @@ $.widget("ui.resizable", $.ui.mouse, { var el = this.element, o = this.options; this.elementOffset = el.offset(); - if (this._helper) { + if ( this._helper ) { - this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); + this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" ); - this.helper.addClass(this._helper).css({ - width: this.element.outerWidth() - 1, - height: this.element.outerHeight() - 1, + this._addClass( this.helper, this._helper ); + this.helper.css( { + width: this.element.outerWidth(), + height: this.element.outerHeight(), position: "absolute", left: this.elementOffset.left + "px", top: this.elementOffset.top + "px", zIndex: ++o.zIndex //TODO: Don't modify option - }); + } ); this.helper - .appendTo("body") + .appendTo( "body" ) .disableSelection(); } else { @@ -7638,41 +11477,41 @@ $.widget("ui.resizable", $.ui.mouse, { }, _change: { - e: function(event, dx) { + e: function( event, dx ) { return { width: this.originalSize.width + dx }; }, - w: function(event, dx) { + w: function( event, dx ) { var cs = this.originalSize, sp = this.originalPosition; return { left: sp.left + dx, width: cs.width - dx }; }, - n: function(event, dx, dy) { + n: function( event, dx, dy ) { var cs = this.originalSize, sp = this.originalPosition; return { top: sp.top + dy, height: cs.height - dy }; }, - s: function(event, dx, dy) { + s: function( event, dx, dy ) { return { height: this.originalSize.height + dy }; }, - se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), - this._change.e.apply(this, [ event, dx, dy ])); + se: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); }, - sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), - this._change.w.apply(this, [ event, dx, dy ])); + sw: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); }, - ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), - this._change.e.apply(this, [ event, dx, dy ])); + ne: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); }, - nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), - this._change.w.apply(this, [ event, dx, dy ])); + nw: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); } }, - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [ event, this.ui() ]); - (n !== "resize" && this._trigger(n, event, this.ui())); + _propagate: function( n, event ) { + $.ui.plugin.call( this, n, [ event, this.ui() ] ); + ( n !== "resize" && this._trigger( n, event, this.ui() ) ); }, plugins: {}, @@ -7689,54 +11528,57 @@ $.widget("ui.resizable", $.ui.mouse, { }; } -}); +} ); /* * Resizable Extensions */ -$.ui.plugin.add("resizable", "animate", { +$.ui.plugin.add( "resizable", "animate", { stop: function( event ) { - var that = $(this).resizable( "instance" ), + var that = $( this ).resizable( "instance" ), o = that.options, pr = that._proportionallyResizeElements, - ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), + soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, soffsetw = ista ? 0 : that.sizeDiff.width, - style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, - left = (parseInt(that.element.css("left"), 10) + - (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css("top"), 10) + - (that.position.top - that.originalPosition.top)) || null; + style = { + width: ( that.size.width - soffsetw ), + height: ( that.size.height - soffseth ) + }, + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null, + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; that.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { + $.extend( style, top && left ? { top: top, left: left } : {} ), { duration: o.animateDuration, easing: o.animateEasing, step: function() { var data = { - width: parseInt(that.element.css("width"), 10), - height: parseInt(that.element.css("height"), 10), - top: parseInt(that.element.css("top"), 10), - left: parseInt(that.element.css("left"), 10) + width: parseFloat( that.element.css( "width" ) ), + height: parseFloat( that.element.css( "height" ) ), + top: parseFloat( that.element.css( "top" ) ), + left: parseFloat( that.element.css( "left" ) ) }; - if (pr && pr.length) { - $(pr[0]).css({ width: data.width, height: data.height }); + if ( pr && pr.length ) { + $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); } - // propagating resize, and updating values for each animation step - that._updateCache(data); - that._propagate("resize", event); + // Propagating resize, and updating values for each animation step + that._updateCache( data ); + that._propagate( "resize", event ); } } ); } -}); +} ); $.ui.plugin.add( "resizable", "containment", { @@ -7746,7 +11588,9 @@ $.ui.plugin.add( "resizable", "containment", { o = that.options, el = that.element, oc = o.containment, - ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; + ce = ( oc instanceof $ ) ? + oc.get( 0 ) : + ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; if ( !ce ) { return; @@ -7774,9 +11618,9 @@ $.ui.plugin.add( "resizable", "containment", { } else { element = $( ce ); p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { + $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { p[ i ] = that._num( element.css( "padding" + name ) ); - }); + } ); that.containerOffset = element.offset(); that.containerPosition = element.position(); @@ -7857,14 +11701,14 @@ $.ui.plugin.add( "resizable", "containment", { } woset = Math.abs( that.sizeDiff.width + - (that._helper ? + ( that._helper ? that.offset.left - cop.left : - (that.offset.left - co.left)) ); + ( that.offset.left - co.left ) ) ); hoset = Math.abs( that.sizeDiff.height + - (that._helper ? + ( that._helper ? that.offset.top - cop.top : - (that.offset.top - co.top)) ); + ( that.offset.top - co.top ) ) ); if ( woset + that.size.width >= that.parentData.width ) { that.size.width = that.parentData.width - woset; @@ -7902,167 +11746,174 @@ $.ui.plugin.add( "resizable", "containment", { h = helper.outerHeight() - that.sizeDiff.height; if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { - $( this ).css({ + $( this ).css( { left: ho.left - cop.left - co.left, width: w, height: h - }); + } ); } if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { - $( this ).css({ + $( this ).css( { left: ho.left - cop.left - co.left, width: w, height: h - }); + } ); } } -}); +} ); -$.ui.plugin.add("resizable", "alsoResize", { +$.ui.plugin.add( "resizable", "alsoResize", { start: function() { - var that = $(this).resizable( "instance" ), + var that = $( this ).resizable( "instance" ), o = that.options; - $(o.alsoResize).each(function() { - var el = $(this); - el.data("ui-resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) - }); - }); + $( o.alsoResize ).each( function() { + var el = $( this ); + el.data( "ui-resizable-alsoresize", { + width: parseFloat( el.width() ), height: parseFloat( el.height() ), + left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) + } ); + } ); }, - resize: function(event, ui) { - var that = $(this).resizable( "instance" ), + resize: function( event, ui ) { + var that = $( this ).resizable( "instance" ), o = that.options, os = that.originalSize, op = that.originalPosition, delta = { - height: (that.size.height - os.height) || 0, - width: (that.size.width - os.width) || 0, - top: (that.position.top - op.top) || 0, - left: (that.position.left - op.left) || 0 + height: ( that.size.height - os.height ) || 0, + width: ( that.size.width - os.width ) || 0, + top: ( that.position.top - op.top ) || 0, + left: ( that.position.left - op.left ) || 0 }; - $(o.alsoResize).each(function() { - var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, - css = el.parents(ui.originalElement[0]).length ? + $( o.alsoResize ).each( function() { + var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, + css = el.parents( ui.originalElement[ 0 ] ).length ? [ "width", "height" ] : [ "width", "height", "top", "left" ]; - $.each(css, function(i, prop) { - var sum = (start[prop] || 0) + (delta[prop] || 0); - if (sum && sum >= 0) { - style[prop] = sum || null; + $.each( css, function( i, prop ) { + var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); + if ( sum && sum >= 0 ) { + style[ prop ] = sum || null; } - }); + } ); - el.css(style); - }); + el.css( style ); + } ); }, stop: function() { - $(this).removeData("resizable-alsoresize"); + $( this ).removeData( "ui-resizable-alsoresize" ); } -}); +} ); -$.ui.plugin.add("resizable", "ghost", { +$.ui.plugin.add( "resizable", "ghost", { start: function() { - var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; + var that = $( this ).resizable( "instance" ), cs = that.size; that.ghost = that.originalElement.clone(); - that.ghost - .css({ - opacity: 0.25, - display: "block", - position: "relative", - height: cs.height, - width: cs.width, - margin: 0, - left: 0, - top: 0 - }) - .addClass("ui-resizable-ghost") - .addClass(typeof o.ghost === "string" ? o.ghost : ""); + that.ghost.css( { + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 + } ); + + that._addClass( that.ghost, "ui-resizable-ghost" ); - that.ghost.appendTo(that.helper); + // DEPRECATED + // TODO: remove after 1.12 + if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { + + // Ghost option + that.ghost.addClass( this.options.ghost ); + } + + that.ghost.appendTo( that.helper ); }, resize: function() { - var that = $(this).resizable( "instance" ); - if (that.ghost) { - that.ghost.css({ + var that = $( this ).resizable( "instance" ); + if ( that.ghost ) { + that.ghost.css( { position: "relative", height: that.size.height, width: that.size.width - }); + } ); } }, stop: function() { - var that = $(this).resizable( "instance" ); - if (that.ghost && that.helper) { - that.helper.get(0).removeChild(that.ghost.get(0)); + var that = $( this ).resizable( "instance" ); + if ( that.ghost && that.helper ) { + that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); } } -}); +} ); -$.ui.plugin.add("resizable", "grid", { +$.ui.plugin.add( "resizable", "grid", { resize: function() { var outerDimensions, - that = $(this).resizable( "instance" ), + that = $( this ).resizable( "instance" ), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, - gridX = (grid[0] || 1), - gridY = (grid[1] || 1), - ox = Math.round((cs.width - os.width) / gridX) * gridX, - oy = Math.round((cs.height - os.height) / gridY) * gridY, + gridX = ( grid[ 0 ] || 1 ), + gridY = ( grid[ 1 ] || 1 ), + ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, + oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, newWidth = os.width + ox, newHeight = os.height + oy, - isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), - isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), - isMinWidth = o.minWidth && (o.minWidth > newWidth), - isMinHeight = o.minHeight && (o.minHeight > newHeight); + isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), + isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), + isMinWidth = o.minWidth && ( o.minWidth > newWidth ), + isMinHeight = o.minHeight && ( o.minHeight > newHeight ); o.grid = grid; - if (isMinWidth) { + if ( isMinWidth ) { newWidth += gridX; } - if (isMinHeight) { + if ( isMinHeight ) { newHeight += gridY; } - if (isMaxWidth) { + if ( isMaxWidth ) { newWidth -= gridX; } - if (isMaxHeight) { + if ( isMaxHeight ) { newHeight -= gridY; } - if (/^(se|s|e)$/.test(a)) { + if ( /^(se|s|e)$/.test( a ) ) { that.size.width = newWidth; that.size.height = newHeight; - } else if (/^(ne)$/.test(a)) { + } else if ( /^(ne)$/.test( a ) ) { that.size.width = newWidth; that.size.height = newHeight; that.position.top = op.top - oy; - } else if (/^(sw)$/.test(a)) { + } else if ( /^(sw)$/.test( a ) ) { that.size.width = newWidth; that.size.height = newHeight; that.position.left = op.left - ox; } else { - if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { + if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { outerDimensions = that._getPaddingPlusBorderDimensions( this ); } @@ -8085,32 +11936,43 @@ $.ui.plugin.add("resizable", "grid", { } } -}); +} ); -var resizable = $.ui.resizable; +var widgetsResizable = $.ui.resizable; /*! - * jQuery UI Dialog 1.11.4 + * jQuery UI Dialog 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/dialog/ */ +//>>label: Dialog +//>>group: Widgets +//>>description: Displays customizable dialog windows. +//>>docs: http://api.jqueryui.com/dialog/ +//>>demos: http://jqueryui.com/dialog/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/dialog.css +//>>css.theme: ../../themes/base/theme.css + -var dialog = $.widget( "ui.dialog", { - version: "1.11.4", + +$.widget( "ui.dialog", { + version: "1.12.1", options: { appendTo: "body", autoOpen: true, buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, closeOnEscape: true, closeText: "Close", - dialogClass: "", draggable: true, hide: null, height: "auto", @@ -8124,6 +11986,7 @@ var dialog = $.widget( "ui.dialog", { at: "center", of: window, collision: "fit", + // Ensure the titlebar is always visible using: function( pos ) { var topOffset = $( this ).css( pos ).offset().top; @@ -8137,7 +12000,7 @@ var dialog = $.widget( "ui.dialog", { title: null, width: 300, - // callbacks + // Callbacks beforeClose: null, close: null, drag: null, @@ -8180,16 +12043,24 @@ var dialog = $.widget( "ui.dialog", { index: this.element.parent().children().index( this.element ) }; this.originalTitle = this.element.attr( "title" ); - this.options.title = this.options.title || this.originalTitle; + if ( this.options.title == null && this.originalTitle != null ) { + this.options.title = this.originalTitle; + } + + // Dialogs can't be disabled + if ( this.options.disabled ) { + this.options.disabled = false; + } this._createWrapper(); this.element .show() .removeAttr( "title" ) - .addClass( "ui-dialog-content ui-widget-content" ) .appendTo( this.uiDialog ); + this._addClass( "ui-dialog-content", "ui-widget-content" ); + this._createTitlebar(); this._createButtonPane(); @@ -8213,7 +12084,7 @@ var dialog = $.widget( "ui.dialog", { _appendTo: function() { var element = this.options.appendTo; - if ( element && (element.jquery || element.nodeType) ) { + if ( element && ( element.jquery || element.nodeType ) ) { return $( element ); } return this.document.find( element || "body" ).eq( 0 ); @@ -8228,18 +12099,19 @@ var dialog = $.widget( "ui.dialog", { this.element .removeUniqueId() - .removeClass( "ui-dialog-content ui-widget-content" ) .css( this.originalCss ) + // Without detaching first, the following becomes really slow .detach(); - this.uiDialog.stop( true, true ).remove(); + this.uiDialog.remove(); if ( this.originalTitle ) { this.element.attr( "title", this.originalTitle ); } next = originalPosition.parent.children().eq( originalPosition.index ); + // Don't try to place the dialog next to itself (#8613) if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { next.before( this.element ); @@ -8256,8 +12128,7 @@ var dialog = $.widget( "ui.dialog", { enable: $.noop, close: function( event ) { - var activeElement, - that = this; + var that = this; if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { return; @@ -8268,28 +12139,17 @@ var dialog = $.widget( "ui.dialog", { this._destroyOverlay(); this._untrackInstance(); - if ( !this.opener.filter( ":focusable" ).focus().length ) { - - // support: IE9 - // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> - try { - activeElement = this.document[ 0 ].activeElement; - - // Support: IE9, IE10 - // If the <body> is blurred, IE will switch windows, see #4520 - if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { + if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { - // Hiding a focused element doesn't trigger blur in WebKit - // so in case we have nothing to focus on, explicitly blur the active element - // https://bugs.webkit.org/show_bug.cgi?id=47182 - $( activeElement ).blur(); - } - } catch ( error ) {} + // Hiding a focused element doesn't trigger blur in WebKit + // so in case we have nothing to focus on, explicitly blur the active element + // https://bugs.webkit.org/show_bug.cgi?id=47182 + $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); } this._hide( this.uiDialog, this.options.hide, function() { that._trigger( "close", event ); - }); + } ); }, isOpen: function() { @@ -8302,9 +12162,9 @@ var dialog = $.widget( "ui.dialog", { _moveToTop: function( event, silent ) { var moved = false, - zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() { + zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { return +$( this ).css( "z-index" ); - }).get(), + } ).get(), zIndexMax = Math.max.apply( null, zIndices ); if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { @@ -8328,7 +12188,7 @@ var dialog = $.widget( "ui.dialog", { } this._isOpen = true; - this.opener = $( this.document[ 0 ].activeElement ); + this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); this._size(); this._position(); @@ -8345,7 +12205,7 @@ var dialog = $.widget( "ui.dialog", { this._show( this.uiDialog, this.options.show, function() { that._focusTabbable(); that._trigger( "focus" ); - }); + } ); // Track the dialog immediately upon openening in case a focus event // somehow occurs outside of the dialog before an element inside the @@ -8356,6 +12216,7 @@ var dialog = $.widget( "ui.dialog", { }, _focusTabbable: function() { + // Set focus to the first match: // 1. An element that was focused previously // 2. First element inside the dialog matching [autofocus] @@ -8379,20 +12240,21 @@ var dialog = $.widget( "ui.dialog", { if ( !hasFocus.length ) { hasFocus = this.uiDialog; } - hasFocus.eq( 0 ).focus(); + hasFocus.eq( 0 ).trigger( "focus" ); }, _keepFocus: function( event ) { function checkFocus() { - var activeElement = this.document[0].activeElement, - isActive = this.uiDialog[0] === activeElement || - $.contains( this.uiDialog[0], activeElement ); + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + isActive = this.uiDialog[ 0 ] === activeElement || + $.contains( this.uiDialog[ 0 ], activeElement ); if ( !isActive ) { this._focusTabbable(); } } event.preventDefault(); checkFocus.call( this ); + // support: IE // IE <= 8 doesn't prevent moving focus even with event.preventDefault() // so we check again later @@ -8400,17 +12262,17 @@ var dialog = $.widget( "ui.dialog", { }, _createWrapper: function() { - this.uiDialog = $("<div>") - .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + - this.options.dialogClass ) + this.uiDialog = $( "<div>" ) .hide() - .attr({ + .attr( { + // Setting tabIndex makes the div focusable tabIndex: -1, role: "dialog" - }) + } ) .appendTo( this._appendTo() ); + this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); this._on( this.uiDialog, { keydown: function( event ) { if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && @@ -8420,7 +12282,7 @@ var dialog = $.widget( "ui.dialog", { return; } - // prevent tabbing out of dialogs + // Prevent tabbing out of dialogs if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { return; } @@ -8428,15 +12290,17 @@ var dialog = $.widget( "ui.dialog", { first = tabbables.filter( ":first" ), last = tabbables.filter( ":last" ); - if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { - this._delay(function() { - first.focus(); - }); + if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && + !event.shiftKey ) { + this._delay( function() { + first.trigger( "focus" ); + } ); event.preventDefault(); - } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { - this._delay(function() { - last.focus(); - }); + } else if ( ( event.target === first[ 0 ] || + event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { + this._delay( function() { + last.trigger( "focus" ); + } ); event.preventDefault(); } }, @@ -8445,81 +12309,84 @@ var dialog = $.widget( "ui.dialog", { this._focusTabbable(); } } - }); + } ); // We assume that any existing aria-describedby attribute means // that the dialog content is marked up properly // otherwise we brute force the content as the description if ( !this.element.find( "[aria-describedby]" ).length ) { - this.uiDialog.attr({ + this.uiDialog.attr( { "aria-describedby": this.element.uniqueId().attr( "id" ) - }); + } ); } }, _createTitlebar: function() { var uiDialogTitle; - this.uiDialogTitlebar = $( "<div>" ) - .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" ) - .prependTo( this.uiDialog ); + this.uiDialogTitlebar = $( "<div>" ); + this._addClass( this.uiDialogTitlebar, + "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); this._on( this.uiDialogTitlebar, { mousedown: function( event ) { + // Don't prevent click on close button (#8838) // Focusing a dialog that is partially scrolled out of view // causes the browser to scroll it into view, preventing the click event if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { + // Dialog isn't getting focus when dragging (#8063) - this.uiDialog.focus(); + this.uiDialog.trigger( "focus" ); } } - }); + } ); - // support: IE + // Support: IE // Use type="button" to prevent enter keypresses in textboxes from closing the // dialog in IE (#9312) this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) - .button({ - label: this.options.closeText, - icons: { - primary: "ui-icon-closethick" - }, - text: false - }) - .addClass( "ui-dialog-titlebar-close" ) + .button( { + label: $( "<a>" ).text( this.options.closeText ).html(), + icon: "ui-icon-closethick", + showLabel: false + } ) .appendTo( this.uiDialogTitlebar ); + + this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); this._on( this.uiDialogTitlebarClose, { click: function( event ) { event.preventDefault(); this.close( event ); } - }); + } ); - uiDialogTitle = $( "<span>" ) - .uniqueId() - .addClass( "ui-dialog-title" ) - .prependTo( this.uiDialogTitlebar ); + uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); + this._addClass( uiDialogTitle, "ui-dialog-title" ); this._title( uiDialogTitle ); - this.uiDialog.attr({ + this.uiDialogTitlebar.prependTo( this.uiDialog ); + + this.uiDialog.attr( { "aria-labelledby": uiDialogTitle.attr( "id" ) - }); + } ); }, _title: function( title ) { - if ( !this.options.title ) { + if ( this.options.title ) { + title.text( this.options.title ); + } else { title.html( " " ); } - title.text( this.options.title ); }, _createButtonPane: function() { - this.uiDialogButtonPane = $( "<div>" ) - .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ); + this.uiDialogButtonPane = $( "<div>" ); + this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", + "ui-widget-content ui-helper-clearfix" ); this.uiButtonSet = $( "<div>" ) - .addClass( "ui-dialog-buttonset" ) .appendTo( this.uiDialogButtonPane ); + this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); this._createButtons(); }, @@ -8528,12 +12395,12 @@ var dialog = $.widget( "ui.dialog", { var that = this, buttons = this.options.buttons; - // if we already have a button pane, remove it + // If we already have a button pane, remove it this.uiDialogButtonPane.remove(); this.uiButtonSet.empty(); - if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { - this.uiDialog.removeClass( "ui-dialog-buttons" ); + if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) { + this._removeClass( this.uiDialog, "ui-dialog-buttons" ); return; } @@ -8542,24 +12409,41 @@ var dialog = $.widget( "ui.dialog", { props = $.isFunction( props ) ? { click: props, text: name } : props; + // Default to a non-submitting button props = $.extend( { type: "button" }, props ); + // Change the context for the click callback to be the main element click = props.click; - props.click = function() { - click.apply( that.element[ 0 ], arguments ); - }; buttonOptions = { + icon: props.icon, + iconPosition: props.iconPosition, + showLabel: props.showLabel, + + // Deprecated options icons: props.icons, - text: props.showText + text: props.text }; + + delete props.click; + delete props.icon; + delete props.iconPosition; + delete props.showLabel; + + // Deprecated options delete props.icons; - delete props.showText; + if ( typeof props.text === "boolean" ) { + delete props.text; + } + $( "<button></button>", props ) .button( buttonOptions ) - .appendTo( that.uiButtonSet ); - }); - this.uiDialog.addClass( "ui-dialog-buttons" ); + .appendTo( that.uiButtonSet ) + .on( "click", function() { + click.apply( that.element[ 0 ], arguments ); + } ); + } ); + this._addClass( this.uiDialog, "ui-dialog-buttons" ); this.uiDialogButtonPane.appendTo( this.uiDialog ); }, @@ -8574,12 +12458,12 @@ var dialog = $.widget( "ui.dialog", { }; } - this.uiDialog.draggable({ + this.uiDialog.draggable( { cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", handle: ".ui-dialog-titlebar", containment: "document", start: function( event, ui ) { - $( this ).addClass( "ui-dialog-dragging" ); + that._addClass( $( this ), "ui-dialog-dragging" ); that._blockFrames(); that._trigger( "dragStart", event, filteredUi( ui ) ); }, @@ -8592,26 +12476,27 @@ var dialog = $.widget( "ui.dialog", { options.position = { my: "left top", - at: "left" + (left >= 0 ? "+" : "") + left + " " + - "top" + (top >= 0 ? "+" : "") + top, + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, of: that.window }; - $( this ).removeClass( "ui-dialog-dragging" ); + that._removeClass( $( this ), "ui-dialog-dragging" ); that._unblockFrames(); that._trigger( "dragStop", event, filteredUi( ui ) ); } - }); + } ); }, _makeResizable: function() { var that = this, options = this.options, handles = options.resizable, + // .ui-resizable has position: relative defined in the stylesheet // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css("position"), + position = this.uiDialog.css( "position" ), resizeHandles = typeof handles === "string" ? - handles : + handles : "n,e,s,w,se,sw,ne,nw"; function filteredUi( ui ) { @@ -8623,7 +12508,7 @@ var dialog = $.widget( "ui.dialog", { }; } - this.uiDialog.resizable({ + this.uiDialog.resizable( { cancel: ".ui-dialog-content", containment: "document", alsoResize: this.element, @@ -8633,7 +12518,7 @@ var dialog = $.widget( "ui.dialog", { minHeight: this._minHeight(), handles: resizeHandles, start: function( event, ui ) { - $( this ).addClass( "ui-dialog-resizing" ); + that._addClass( $( this ), "ui-dialog-resizing" ); that._blockFrames(); that._trigger( "resizeStart", event, filteredUi( ui ) ); }, @@ -8649,16 +12534,16 @@ var dialog = $.widget( "ui.dialog", { options.width = that.uiDialog.width(); options.position = { my: "left top", - at: "left" + (left >= 0 ? "+" : "") + left + " " + - "top" + (top >= 0 ? "+" : "") + top, + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, of: that.window }; - $( this ).removeClass( "ui-dialog-resizing" ); + that._removeClass( $( this ), "ui-dialog-resizing" ); that._unblockFrames(); that._trigger( "resizeStop", event, filteredUi( ui ) ); } - }) - .css( "position", position ); + } ) + .css( "position", position ); }, _trackFocus: function() { @@ -8667,7 +12552,7 @@ var dialog = $.widget( "ui.dialog", { this._makeFocusTarget(); this._focusedElement = $( event.target ); } - }); + } ); }, _makeFocusTarget: function() { @@ -8701,6 +12586,7 @@ var dialog = $.widget( "ui.dialog", { }, _position: function() { + // Need to show the dialog to get the actual offset in the position plugin var isVisible = this.uiDialog.is( ":visible" ); if ( !isVisible ) { @@ -8726,7 +12612,7 @@ var dialog = $.widget( "ui.dialog", { if ( key in that.resizableRelatedOptions ) { resizableOptions[ key ] = value; } - }); + } ); if ( resize ) { this._size(); @@ -8741,12 +12627,6 @@ var dialog = $.widget( "ui.dialog", { var isDraggable, isResizable, uiDialog = this.uiDialog; - if ( key === "dialogClass" ) { - uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); - } - if ( key === "disabled" ) { return; } @@ -8762,10 +12642,11 @@ var dialog = $.widget( "ui.dialog", { } if ( key === "closeText" ) { - this.uiDialogTitlebarClose.button({ + this.uiDialogTitlebarClose.button( { + // Ensure that we always pass a string - label: "" + value - }); + label: $( "<a>" ).text( "" + this.options.closeText ).html() + } ); } if ( key === "draggable" ) { @@ -8784,18 +12665,19 @@ var dialog = $.widget( "ui.dialog", { } if ( key === "resizable" ) { + // currently resizable, becoming non-resizable isResizable = uiDialog.is( ":data(ui-resizable)" ); if ( isResizable && !value ) { uiDialog.resizable( "destroy" ); } - // currently resizable, changing handles + // Currently resizable, changing handles if ( isResizable && typeof value === "string" ) { uiDialog.resizable( "option", "handles", value ); } - // currently non-resizable, becoming resizable + // Currently non-resizable, becoming resizable if ( !isResizable && value !== false ) { this._makeResizable(); } @@ -8807,29 +12689,30 @@ var dialog = $.widget( "ui.dialog", { }, _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 nonContentHeight, minContentHeight, maxContentHeight, options = this.options; // Reset content sizing - this.element.show().css({ + this.element.show().css( { width: "auto", minHeight: 0, maxHeight: "none", height: 0 - }); + } ); if ( options.minWidth > options.width ) { options.width = options.minWidth; } - // reset wrapper sizing + // Reset wrapper sizing // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css({ - height: "auto", - width: options.width - }) + nonContentHeight = this.uiDialog.css( { + height: "auto", + width: options.width + } ) .outerHeight(); minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); maxContentHeight = typeof options.maxHeight === "number" ? @@ -8837,11 +12720,11 @@ var dialog = $.widget( "ui.dialog", { "none"; if ( options.height === "auto" ) { - this.element.css({ + this.element.css( { minHeight: minContentHeight, maxHeight: maxContentHeight, height: "auto" - }); + } ); } else { this.element.height( Math.max( 0, options.height - nonContentHeight ) ); } @@ -8852,18 +12735,18 @@ var dialog = $.widget( "ui.dialog", { }, _blockFrames: function() { - this.iframeBlocks = this.document.find( "iframe" ).map(function() { + this.iframeBlocks = this.document.find( "iframe" ).map( function() { var iframe = $( this ); return $( "<div>" ) - .css({ + .css( { position: "absolute", width: iframe.outerWidth(), height: iframe.outerHeight() - }) + } ) .appendTo( iframe.parent() ) - .offset( iframe.offset() )[0]; - }); + .offset( iframe.offset() )[ 0 ]; + } ); }, _unblockFrames: function() { @@ -8891,9 +12774,9 @@ var dialog = $.widget( "ui.dialog", { // We use a delay in case the overlay is created from an // event that we're going to be cancelling (#2804) var isOpening = true; - this._delay(function() { + this._delay( function() { isOpening = false; - }); + } ); if ( !this.document.data( "ui-dialog-overlays" ) ) { @@ -8911,17 +12794,18 @@ var dialog = $.widget( "ui.dialog", { this._trackingInstances()[ 0 ]._focusTabbable(); } } - }); + } ); } this.overlay = $( "<div>" ) - .addClass( "ui-widget-overlay ui-front" ) .appendTo( this._appendTo() ); + + this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); this._on( this.overlay, { mousedown: "_keepFocus" - }); + } ); this.document.data( "ui-dialog-overlays", - (this.document.data( "ui-dialog-overlays" ) || 0) + 1 ); + ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); }, _destroyOverlay: function() { @@ -8933,9 +12817,8 @@ var dialog = $.widget( "ui.dialog", { var overlays = this.document.data( "ui-dialog-overlays" ) - 1; if ( !overlays ) { - this.document - .unbind( "focusin" ) - .removeData( "ui-dialog-overlays" ); + this._off( this.document, "focusin" ); + this.document.removeData( "ui-dialog-overlays" ); } else { this.document.data( "ui-dialog-overlays", overlays ); } @@ -8944,34 +12827,63 @@ var dialog = $.widget( "ui.dialog", { this.overlay = null; } } -}); +} ); + +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for dialogClass option + $.widget( "ui.dialog", $.ui.dialog, { + options: { + dialogClass: "" + }, + _createWrapper: function() { + this._super(); + this.uiDialog.addClass( this.options.dialogClass ); + }, + _setOption: function( key, value ) { + if ( key === "dialogClass" ) { + this.uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + this._superApply( arguments ); + } + } ); +} + +var widgetsDialog = $.ui.dialog; /*! - * jQuery UI Droppable 1.11.4 + * jQuery UI Droppable 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/droppable/ */ +//>>label: Droppable +//>>group: Interactions +//>>description: Enables drop targets for draggable elements. +//>>docs: http://api.jqueryui.com/droppable/ +//>>demos: http://jqueryui.com/droppable/ + + $.widget( "ui.droppable", { - version: "1.11.4", + version: "1.12.1", widgetEventPrefix: "drop", options: { accept: "*", - activeClass: false, addClasses: true, greedy: false, - hoverClass: false, scope: "default", tolerance: "intersect", - // callbacks + // Callbacks activate: null, deactivate: null, drop: null, @@ -8993,9 +12905,11 @@ $.widget( "ui.droppable", { this.proportions = function( /* valueToWrite */ ) { if ( arguments.length ) { + // Store the droppable's proportions proportions = arguments[ 0 ]; } else { + // Retrieve or derive the droppable's proportions return proportions ? proportions : @@ -9008,11 +12922,12 @@ $.widget( "ui.droppable", { this._addToManager( o.scope ); - o.addClasses && this.element.addClass( "ui-droppable" ); + o.addClasses && this._addClass( "ui-droppable" ); }, _addToManager: function( scope ) { + // Add the reference and positions to the manager $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; $.ui.ddmanager.droppables[ scope ].push( this ); @@ -9031,8 +12946,6 @@ $.widget( "ui.droppable", { var drop = $.ui.ddmanager.droppables[ this.options.scope ]; this._splice( drop ); - - this.element.removeClass( "ui-droppable ui-droppable-disabled" ); }, _setOption: function( key, value ) { @@ -9053,20 +12966,18 @@ $.widget( "ui.droppable", { _activate: function( event ) { var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.addClass( this.options.activeClass ); - } - if ( draggable ){ + + this._addActiveClass(); + if ( draggable ) { this._trigger( "activate", event, this.ui( draggable ) ); } }, _deactivate: function( event ) { var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - if ( draggable ){ + + this._removeActiveClass(); + if ( draggable ) { this._trigger( "deactivate", event, this.ui( draggable ) ); } }, @@ -9076,14 +12987,14 @@ $.widget( "ui.droppable", { var draggable = $.ui.ddmanager.current; // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { return; } - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.addClass( this.options.hoverClass ); - } + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._addHoverClass(); this._trigger( "over", event, this.ui( draggable ) ); } @@ -9094,14 +13005,14 @@ $.widget( "ui.droppable", { var draggable = $.ui.ddmanager.current; // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { return; } - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._removeHoverClass(); this._trigger( "out", event, this.ui( draggable ) ); } @@ -9113,31 +13024,41 @@ $.widget( "ui.droppable", { childrenIntersection = false; // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { return false; } - this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { - var inst = $( this ).droppable( "instance" ); - 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, event ) - ) { childrenIntersection = true; return false; } - }); + this.element + .find( ":data(ui-droppable)" ) + .not( ".ui-draggable-dragging" ) + .each( function() { + var inst = $( this ).droppable( "instance" ); + if ( + inst.options.greedy && + !inst.options.disabled && + inst.options.scope === draggable.options.scope && + inst.accept.call( + inst.element[ 0 ], ( draggable.currentItem || draggable.element ) + ) && + intersect( + draggable, + $.extend( inst, { offset: inst.element.offset() } ), + inst.options.tolerance, event + ) + ) { + childrenIntersection = true; + return false; } + } ); if ( childrenIntersection ) { return false; } - 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 ); - } + if ( this.accept.call( this.element[ 0 ], + ( draggable.currentItem || draggable.element ) ) ) { + this._removeActiveClass(); + this._removeHoverClass(); + this._trigger( "drop", event, this.ui( draggable ) ); return this.element; } @@ -9153,11 +13074,28 @@ $.widget( "ui.droppable", { position: c.position, offset: c.positionAbs }; - } + }, + + // Extension points just to make backcompat sane and avoid duplicating logic + // TODO: Remove in 1.13 along with call to it below + _addHoverClass: function() { + this._addClass( "ui-droppable-hover" ); + }, -}); + _removeHoverClass: function() { + this._removeClass( "ui-droppable-hover" ); + }, + + _addActiveClass: function() { + this._addClass( "ui-droppable-active" ); + }, + + _removeActiveClass: function() { + this._removeClass( "ui-droppable-active" ); + } +} ); -$.ui.intersect = (function() { +var intersect = $.ui.intersect = ( function() { function isOverAxis( x, reference, size ) { return ( x >= reference ) && ( x < ( reference + size ) ); } @@ -9168,8 +13106,10 @@ $.ui.intersect = (function() { return false; } - var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, - y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, + var x1 = ( draggable.positionAbs || + draggable.position.absolute ).left + draggable.margins.left, + y1 = ( draggable.positionAbs || + draggable.position.absolute ).top + draggable.margins.top, x2 = x1 + draggable.helperProportions.width, y2 = y1 + draggable.helperProportions.height, l = droppable.offset.left, @@ -9186,7 +13126,8 @@ $.ui.intersect = (function() { t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half case "pointer": - return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); + return isOverAxis( event.pageY, t, droppable.proportions().height ) && + isOverAxis( event.pageX, l, droppable.proportions().width ); case "touch": return ( ( y1 >= t && y1 <= b ) || // Top edge touching @@ -9201,7 +13142,7 @@ $.ui.intersect = (function() { return false; } }; -})(); +} )(); /* This manager tracks offsets of draggables and droppables @@ -9219,7 +13160,8 @@ $.ui.ddmanager = { droppablesLoop: for ( i = 0; i < m.length; i++ ) { // No disabled and non-accepted - if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { + if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], + ( t.currentItem || t.element ) ) ) ) { continue; } @@ -9242,7 +13184,10 @@ $.ui.ddmanager = { } m[ i ].offset = m[ i ].element.offset(); - m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); + m[ i ].proportions( { + width: m[ i ].element[ 0 ].offsetWidth, + height: m[ i ].element[ 0 ].offsetHeight + } ); } @@ -9250,37 +13195,43 @@ $.ui.ddmanager = { drop: function( draggable, event ) { var dropped = false; + // Create a copy of the droppables in case the list changes during the drop (#9116) $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { if ( !this.options ) { return; } - if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { + if ( !this.options.disabled && this.visible && + intersect( draggable, this, this.options.tolerance, event ) ) { dropped = this._drop.call( this, event ) || dropped; } - if ( !this.options.disabled && this.visible && this.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 = true; this.isover = false; this._deactivate.call( this, event ); } - }); + } ); return dropped; }, dragStart: function( draggable, event ) { - // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { + + // Listen for scrolling so that if the dragging causes scrolling the position of the + // droppables can be recalculated (see #5003) + draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { if ( !draggable.options.refreshPositions ) { $.ui.ddmanager.prepareOffsets( draggable, event ); } - }); + } ); }, drag: function( draggable, event ) { - // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. + // If you have a highly dynamic page, you might try this option. It renders positions + // every time you move the mouse. if ( draggable.options.refreshPositions ) { $.ui.ddmanager.prepareOffsets( draggable, event ); } @@ -9293,18 +13244,21 @@ $.ui.ddmanager = { } var parentInstance, scope, parent, - intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), - c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); + intersects = intersect( draggable, this, this.options.tolerance, event ), + c = !intersects && this.isover ? + "isout" : + ( intersects && !this.isover ? "isover" : null ); if ( !c ) { return; } if ( this.options.greedy ) { + // find droppable parents with same scope scope = this.options.scope; - parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { + parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { return $( this ).droppable( "instance" ).options.scope === scope; - }); + } ); if ( parent.length ) { parentInstance = $( parent[ 0 ] ).droppable( "instance" ); @@ -9312,7 +13266,7 @@ $.ui.ddmanager = { } } - // we just moved into a greedy child + // We just moved into a greedy child if ( parentInstance && c === "isover" ) { parentInstance.isover = false; parentInstance.isout = true; @@ -9320,2467 +13274,99 @@ $.ui.ddmanager = { } this[ c ] = true; - this[c === "isout" ? "isover" : "isout"] = false; - this[c === "isover" ? "_over" : "_out"].call( this, event ); + this[ c === "isout" ? "isover" : "isout" ] = false; + this[ c === "isover" ? "_over" : "_out" ].call( this, event ); - // we just moved out of a greedy child + // We just moved out of a greedy child if ( parentInstance && c === "isout" ) { parentInstance.isout = false; parentInstance.isover = true; parentInstance._over.call( parentInstance, event ); } - }); + } ); }, dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); - // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) + draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); + + // Call prepareOffsets one final time since IE does not fire return scroll events when + // overflow was caused by drag (see #5003) if ( !draggable.options.refreshPositions ) { $.ui.ddmanager.prepareOffsets( draggable, event ); } } }; -var droppable = $.ui.droppable; - - -/*! - * jQuery UI Effects 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/category/effects-core/ - */ - - -var dataSpace = "ui-effects-", - - // Create a local jQuery because jQuery Color relies on it and the - // global may not exist with AMD and a custom build (#10199) - jQuery = $; - -$.effects = { - effect: {} -}; - -/*! - * jQuery Color Animations v2.1.2 - * https://github.com/jquery/jquery-color - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * Date: Wed Jan 16 08:47:09 2013 -0600 - */ -(function( jQuery, undefined ) { - - var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { - // plusequals test for += 100 -= 100 - rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, - // a set of RE's that can match strings and generate color tuples. - stringParsers = [ { - re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] - ]; - } - }, { - re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ] * 2.55, - execResult[ 2 ] * 2.55, - execResult[ 3 ] * 2.55, - execResult[ 4 ] - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ) - ]; - } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) - ]; - } - }, { - re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - space: "hsla", - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ] / 100, - execResult[ 3 ] / 100, - execResult[ 4 ] - ]; - } - } ], - - // jQuery.Color( ) - color = jQuery.Color = function( color, green, blue, alpha ) { - return new jQuery.Color.fn.parse( color, green, blue, alpha ); - }, - spaces = { - rgba: { - props: { - red: { - idx: 0, - type: "byte" - }, - green: { - idx: 1, - type: "byte" - }, - blue: { - idx: 2, - type: "byte" - } - } + // Backcompat for activeClass and hoverClass options + $.widget( "ui.droppable", $.ui.droppable, { + options: { + hoverClass: false, + activeClass: false }, - - hsla: { - props: { - hue: { - idx: 0, - type: "degrees" - }, - saturation: { - idx: 1, - type: "percent" - }, - lightness: { - idx: 2, - type: "percent" - } + _addActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.addClass( this.options.activeClass ); } - } - }, - propTypes = { - "byte": { - floor: true, - max: 255 - }, - "percent": { - max: 1 }, - "degrees": { - mod: 360, - floor: true - } - }, - support = color.support = {}, - - // element for support tests - supportElem = jQuery( "<p>" )[ 0 ], - - // colors = jQuery.Color.names - colors, - - // local aliases of functions called often - each = jQuery.each; - -// determine rgba support immediately -supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; -support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; - -// define cache name and alpha properties -// for rgba and hsla spaces -each( spaces, function( spaceName, space ) { - space.cache = "_" + spaceName; - space.props.alpha = { - idx: 3, - type: "percent", - def: 1 - }; -}); - -function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; - - if ( value == null ) { - return (allowEmpty || !prop.def) ? null : prop.def; - } - - // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); - - // IE will pass in empty strings as value for alpha, - // which will hit this case - if ( isNaN( value ) ) { - return prop.def; - } - - if ( type.mod ) { - // we add mod before modding to make sure that negatives values - // get converted properly: -10 -> 350 - return (value + type.mod) % type.mod; - } - - // for now all property types without mod have min and max - return 0 > value ? 0 : type.max < value ? type.max : value; -} - -function stringParse( string ) { - var inst = color(), - rgba = inst._rgba = []; - - string = string.toLowerCase(); - - each( stringParsers, function( i, parser ) { - var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), - spaceName = parser.space || "rgba"; - - if ( values ) { - parsed = inst[ spaceName ]( values ); - - // if this was an rgba parse the assignment might happen twice - // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; - rgba = inst._rgba = parsed._rgba; - - // exit each( stringParsers ) here because we matched - return false; - } - }); - - // Found a stringParser that handled it - if ( rgba.length ) { - - // if this came from a parsed string, force "transparent" when alpha is 0 - // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( rgba.join() === "0,0,0,0" ) { - jQuery.extend( rgba, colors.transparent ); - } - return inst; - } - - // named colors - return colors[ string ]; -} - -color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; - return this; - } - if ( red.jquery || red.nodeType ) { - red = jQuery( red ).css( green ); - green = undefined; - } - - var inst = this, - type = jQuery.type( red ), - rgba = this._rgba = []; - - // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; - type = "array"; - } - - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); - } - - if ( type === "array" ) { - each( spaces.rgba.props, function( key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); - }); - return this; - } - - if ( type === "object" ) { - if ( red instanceof color ) { - each( spaces, function( spaceName, space ) { - if ( red[ space.cache ] ) { - inst[ space.cache ] = red[ space.cache ].slice(); - } - }); - } else { - each( spaces, function( spaceName, space ) { - var cache = space.cache; - each( space.props, function( key, prop ) { - - // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { - - // if the value was null, we don't need to copy it - // if the key was alpha, we don't need to copy it either - if ( key === "alpha" || red[ key ] == null ) { - return; - } - inst[ cache ] = space.to( inst._rgba ); - } - - // this is the only case where we allow nulls for ALL properties. - // call clamp with alwaysAllowEmpty - inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); - }); - - // everything defined but alpha? - if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { - // use the default of 1 - inst[ cache ][ 3 ] = 1; - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); - } - } - }); - } - return this; - } - }, - is: function( compare ) { - var is = color( compare ), - same = true, - inst = this; - - each( spaces, function( _, space ) { - var localCache, - isCache = is[ space.cache ]; - if (isCache) { - localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; - each( space.props, function( _, prop ) { - if ( isCache[ prop.idx ] != null ) { - same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); - return same; - } - }); - } - return same; - }); - return same; - }, - _space: function() { - var used = [], - inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); - } - }); - return used.pop(); - }, - transition: function( other, distance ) { - var end = color( other ), - spaceName = end._space(), - space = spaces[ spaceName ], - startColor = this.alpha() === 0 ? color( "transparent" ) : this, - start = startColor[ space.cache ] || space.to( startColor._rgba ), - result = start.slice(); - - end = end[ space.cache ]; - each( space.props, function( key, prop ) { - var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; - - // if null, don't override start value - if ( endValue === null ) { - return; - } - // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; - } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { - startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { - startValue -= type.mod; - } - } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); - } - }); - return this[ spaceName ]( result ); - }, - blend: function( opaque ) { - // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { - return this; - } - - var rgb = this._rgba.slice(), - a = rgb.pop(), - blend = color( opaque )._rgba; - - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; - })); - }, - toRgbaString: function() { - var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - return v == null ? ( i > 2 ? 1 : 0 ) : v; - }); - - if ( rgba[ 3 ] === 1 ) { - rgba.pop(); - prefix = "rgb("; - } - - return prefix + rgba.join() + ")"; - }, - toHslaString: function() { - var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { - v = i > 2 ? 1 : 0; - } - - // catch 1 and 2 - if ( i && i < 3 ) { - v = Math.round( v * 100 ) + "%"; - } - return v; - }); - - if ( hsla[ 3 ] === 1 ) { - hsla.pop(); - prefix = "hsl("; - } - return prefix + hsla.join() + ")"; - }, - toHexString: function( includeAlpha ) { - var rgba = this._rgba.slice(), - alpha = rgba.pop(); - - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); - } - - return "#" + jQuery.map( rgba, function( v ) { - - // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); - return v.length === 1 ? "0" + v : v; - }).join(""); - }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); - } -}); -color.fn.parse.prototype = color.fn; - -// hsla conversions adapted from: -// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - -function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { - return p + ( q - p ) * h * 6; - } - if ( h * 2 < 1) { - return q; - } - if ( h * 3 < 2 ) { - return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; - } - return p; -} - -spaces.hsla.to = function( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; - } - var r = rgba[ 0 ] / 255, - g = rgba[ 1 ] / 255, - b = rgba[ 2 ] / 255, - a = rgba[ 3 ], - max = Math.max( r, g, b ), - min = Math.min( r, g, b ), - diff = max - min, - add = max + min, - l = add * 0.5, - h, s; - - if ( min === max ) { - h = 0; - } else if ( r === max ) { - h = ( 60 * ( g - b ) / diff ) + 360; - } else if ( g === max ) { - h = ( 60 * ( b - r ) / diff ) + 120; - } else { - h = ( 60 * ( r - g ) / diff ) + 240; - } - - // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% - // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) - if ( diff === 0 ) { - s = 0; - } else if ( l <= 0.5 ) { - s = diff / add; - } else { - s = diff / ( 2 - add ); - } - return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; -}; - -spaces.hsla.from = function( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; - } - var h = hsla[ 0 ] / 360, - s = hsla[ 1 ], - l = hsla[ 2 ], - a = hsla[ 3 ], - q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, - p = 2 * l - q; - - return [ - Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), - Math.round( hue2rgb( p, q, h ) * 255 ), - Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), - a - ]; -}; - -each( spaces, function( spaceName, space ) { - var props = space.props, - cache = space.cache, - to = space.to, - from = space.from; - - // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { - - // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); - } - if ( value === undefined ) { - return this[ cache ].slice(); - } - - var ret, - type = jQuery.type( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); - - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; - } - local[ prop.idx ] = clamp( val, prop ); - }); - - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; - return ret; - } else { - return color( local ); - } - }; - - // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { - // alpha is included in more than one space - if ( color.fn[ key ] ) { - return; - } - color.fn[ key ] = function( value ) { - var vtype = jQuery.type( value ), - fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), - local = this[ fn ](), - cur = local[ prop.idx ], - match; - - if ( vtype === "undefined" ) { - return cur; - } - - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = jQuery.type( value ); - } - if ( value == null && prop.empty ) { - return this; - } - if ( vtype === "string" ) { - match = rplusequals.exec( value ); - if ( match ) { - value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); - } - } - local[ prop.idx ] = value; - return this[ fn ]( local ); - }; - }); -}); - -// add cssHook and .fx.step function for each named hook. -// accept a space separated string of properties -color.hook = function( hook ) { - var hooks = hook.split( " " ); - each( hooks, function( i, hook ) { - jQuery.cssHooks[ hook ] = { - set: function( elem, value ) { - var parsed, curElem, - backgroundColor = ""; - - if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { - curElem = hook === "backgroundColor" ? elem.parentNode : elem; - while ( - (backgroundColor === "" || backgroundColor === "transparent") && - curElem && curElem.style - ) { - try { - backgroundColor = jQuery.css( curElem, "backgroundColor" ); - curElem = curElem.parentNode; - } catch ( e ) { - } - } - - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? - backgroundColor : - "_default" ); - } - - value = value.toRgbaString(); - } - try { - elem.style[ hook ] = value; - } catch ( e ) { - // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' - } - } - }; - jQuery.fx.step[ hook ] = function( fx ) { - if ( !fx.colorInit ) { - fx.start = color( fx.elem, hook ); - fx.end = color( fx.end ); - fx.colorInit = true; - } - jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); - }; - }); - -}; - -color.hook( stepHooks ); - -jQuery.cssHooks.borderColor = { - expand: function( value ) { - var expanded = {}; - - each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { - expanded[ "border" + part + "Color" ] = value; - }); - return expanded; - } -}; - -// Basic color names only. -// Usage of any of the other color names requires adding yourself or including -// jquery.color.svg-names.js. -colors = jQuery.Color.names = { - // 4.1. Basic color keywords - aqua: "#00ffff", - black: "#000000", - blue: "#0000ff", - fuchsia: "#ff00ff", - gray: "#808080", - green: "#008000", - lime: "#00ff00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - purple: "#800080", - red: "#ff0000", - silver: "#c0c0c0", - teal: "#008080", - white: "#ffffff", - yellow: "#ffff00", - - // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], - - _default: "#ffffff" -}; - -})( jQuery ); - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -(function() { - -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; - } - }; -}); - -function getElementStyles( elem ) { - var key, len, - style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : - elem.currentStyle, - styles = {}; - - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - styles[ $.camelCase( key ) ] = style[ key ]; - } - } - // support: Opera, IE <9 - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - styles[ key ] = style[ key ]; - } - } - } - - return styles; -} - -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; - - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } - } - } - } - - return diff; -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); - - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; - - // map the animated objects to store the original styles. - allAnimations = allAnimations.map(function() { - var el = $( this ); - return { - el: el, - start: getElementStyles( this ) - }; - }); - - // apply class change - applyClassChange = function() { - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - }); - }; - applyClassChange(); - - // map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map(function() { - this.end = getElementStyles( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - }); - - // apply original class - animated.attr( "class", baseClass ); - - // map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map(function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = $.extend({}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - }); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - }); - - // once all animations have completed: - $.when.apply( $, allAnimations.get() ).done(function() { - - // set the final class - applyClassChange(); - - // for each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function(key) { - el.css( key, "" ); - }); - }); - - // this is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - }); - }); -}; - -$.fn.extend({ - addClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.addClass ), - - removeClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { - return arguments.length > 1 ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - })( $.fn.removeClass ), - - toggleClass: (function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { - // without speed parameter - return orig.apply( this, arguments ); - } else { - return $.effects.animateClass.call( this, - (force ? { add: classNames } : { remove: classNames }), - speed, easing, callback ); - } - } else { - // without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }; - })( $.fn.toggleClass ), - - switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -}); - -})(); - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -(function() { - -$.extend( $.effects, { - version: "1.11.4", - - // 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( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i; - for ( i = 0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - // support: jQuery 1.6.2 - // http://bugs.jquery.com/ticket/9917 - // jQuery 1.6.2 incorrectly returns undefined for any falsy value. - // We can't differentiate between "" and 0 here, so we just assume - // empty string since it's likely to be a more common value... - if ( val === undefined ) { - val = ""; - } - element.css( set[ i ], val ); - } - } - }, - - setMode: function( el, mode ) { - if (mode === "toggle") { - mode = el.is( ":hidden" ) ? "show" : "hide"; - } - return mode; - }, - - // Translates a [top,left] array into a baseline value - // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { - 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 - }), - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; - - // support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - active.id; - } catch ( e ) { - active = document.body; - } - - element.wrap( wrapper ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose 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, - right: "auto", - bottom: "auto" - }); - } - element.css(size); - - return wrapper.css( props ).show(); - }, - - removeWrapper: function( element ) { - var active = document.activeElement; - - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); - } - } - - return element; - }, - - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - }); - return value; - } -}); - -// return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { - - // allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } - - // convert to an object - effect = { effect: effect }; - - // catch (effect, null, ...) - if ( options == null ) { - options = {}; - } - - // catch (effect, callback) - if ( $.isFunction( options ) ) { - callback = options; - speed = null; - options = {}; - } - - // catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } - - // catch (effect, options, callback) - if ( $.isFunction( speed ) ) { - callback = speed; - speed = null; - } - - // add options to effect - if ( options ) { - $.extend( effect, options ); - } - - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; - - effect.complete = callback || options.complete; - - return effect; -} - -function standardAnimationOption( option ) { - // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { - return true; - } - - // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { - return true; - } - - // Complete callback - if ( $.isFunction( option ) ) { - return true; - } - - // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { - return true; - } - - // Didn't match any standard API - return false; -} - -$.fn.extend({ - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - mode = args.mode, - queue = args.queue, - effectMethod = $.effects.effect[ args.effect ]; - - if ( $.fx.off || !effectMethod ) { - // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, args.complete ); - } else { - return this.each( function() { - if ( args.complete ) { - args.complete.call( this ); - } - }); - } - } - - function run( next ) { - var elem = $( this ), - complete = args.complete, - mode = args.mode; - - function done() { - if ( $.isFunction( complete ) ) { - complete.call( elem[0] ); - } - if ( $.isFunction( next ) ) { - next(); - } - } - - // If the element already has the correct final state, delegate to - // the core methods so the internal tracking of "olddisplay" works. - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[0], args, done ); - } - } - - return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); - }, - - show: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }; - })( $.fn.show ), - - hide: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }; - })( $.fn.hide ), - - toggle: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }; - })( $.fn.toggle ), - - // 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 ***********************************/ -/******************************************************************************/ - -(function() { - -// based on easing equations from Robert Penner (http://www.robertpenner.com/easing) - -var baseEasings = {}; - -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -}); - -$.extend( baseEasings, { - Sine: function( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); - }, - Circ: function( p ) { - return 1 - Math.sqrt( 1 - p * p ); - }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); - }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); - }, - Bounce: function( p ) { - var pow2, - bounce = 4; - - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -}); - -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -}); - -})(); - -var effect = $.effects; - - -/*! - * jQuery UI Effects Blind 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/blind-effect/ - */ - - -var effectBlind = $.effects.effect.blind = function( o, done ) { - // Create element - var el = $( this ), - rvertical = /up|down|vertical/, - rpositivemotion = /up|left|vertical|horizontal/, - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - direction = o.direction || "up", - vertical = rvertical.test( direction ), - ref = vertical ? "height" : "width", - ref2 = vertical ? "top" : "left", - motion = rpositivemotion.test( direction ), - animation = {}, - show = mode === "show", - wrapper, distance, margin; - - // if already wrapped, the wrapper's properties are my property. #6245 - if ( el.parent().is( ".ui-effects-wrapper" ) ) { - $.effects.save( el.parent(), props ); - } else { - $.effects.save( el, props ); - } - el.show(); - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - distance = wrapper[ ref ](); - margin = parseFloat( wrapper.css( ref2 ) ) || 0; - - animation[ ref ] = show ? distance : 0; - if ( !motion ) { - el - .css( vertical ? "bottom" : "right", 0 ) - .css( vertical ? "top" : "left", "auto" ) - .css({ position: "absolute" }); - - animation[ ref2 ] = show ? margin : distance + margin; - } - - // start at 0 if we are showing - if ( show ) { - wrapper.css( ref, 0 ); - if ( !motion ) { - wrapper.css( ref2, margin + distance ); - } - } - - // Animate - wrapper.animate( animation, { - duration: o.duration, - easing: o.easing, - queue: false, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - - -/*! - * jQuery UI Effects Bounce 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/bounce-effect/ - */ - - -var effectBounce = $.effects.effect.bounce = function( o, done ) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - - // defaults: - mode = $.effects.setMode( el, o.mode || "effect" ), - hide = mode === "hide", - show = mode === "show", - direction = o.direction || "up", - distance = o.distance, - times = o.times || 5, - - // number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), - speed = o.duration / anims, - easing = o.easing, - - // utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), - i, - upAnim, - downAnim, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - // Avoid touching opacity to prevent clearType and PNG issues in IE - if ( show || hide ) { - props.push( "opacity" ); - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); // Create Wrapper - - // default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; - } - - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = 0; - - // if we are showing, force opacity 0 and set the initial position - // then do the "first" animation - el.css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); - } - - // start at the smallest distance if we are hiding - if ( hide ) { - distance = distance / Math.pow( 2, times - 1 ); - } - - downAnim = {}; - downAnim[ ref ] = 0; - // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( i = 0; i < times; i++ ) { - upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); - - distance = hide ? distance * 2 : distance / 2; - } - - // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - - el.animate( upAnim, speed, easing ); - } - - el.queue(function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - - -/*! - * jQuery UI Effects Clip 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/clip-effect/ - */ - - -var effectClip = $.effects.effect.clip = function( o, done ) { - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "vertical", - vert = direction === "vertical", - size = vert ? "height" : "width", - position = vert ? "top" : "left", - animation = {}, - wrapper, animate, distance; - - // Save & Show - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - animate = ( el[0].tagName === "IMG" ) ? wrapper : el; - distance = animate[ size ](); - - // Shift - if ( show ) { - animate.css( size, 0 ); - animate.css( position, distance / 2 ); - } - - // Create Animation Object: - animation[ size ] = show ? distance : 0; - animation[ position ] = show ? 0 : distance / 2; - - // Animate - animate.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( !show ) { - el.hide(); + _removeActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.removeClass( this.options.activeClass ); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); - -}; - - -/*! - * jQuery UI Effects Drop 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/drop-effect/ - */ - - -var effectDrop = $.effects.effect.drop = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - direction = o.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", - animation = { - opacity: show ? 1 : 0 }, - distance; - - // Adjust - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; - - if ( show ) { - el - .css( "opacity", 0 ) - .css( ref, motion === "pos" ? -distance : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( motion === "pos" ? "+=" : "-=" ) : - ( motion === "pos" ? "-=" : "+=" ) ) + - distance; - - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; - - -/*! - * jQuery UI Effects Explode 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/explode-effect/ - */ - - -var effectExplode = $.effects.effect.explode = function( o, done ) { - - var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, - cells = rows, - el = $( this ), - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - - // show and then visibility:hidden the element before calculating offset - offset = el.show().css( "visibility", "hidden" ).offset(), - - // width and height of a piece - width = Math.ceil( el.outerWidth() / cells ), - height = Math.ceil( el.outerHeight() / rows ), - pieces = [], - - // loop - i, j, left, top, mx, my; - - // children animate complete: - function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { - animComplete(); - } - } - - // clone the element for each row and cell. - for ( i = 0; i < rows ; i++ ) { // ===> - top = offset.top + i * height; - my = i - ( rows - 1 ) / 2 ; - - for ( j = 0; j < cells ; j++ ) { // ||| - left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2 ; - - // Create a clone of the now hidden main element that will be absolute positioned - // within a wrapper div off the -left and -top equal to size of our pieces - el - .clone() - .appendTo( "body" ) - .wrap( "<div></div>" ) - .css({ - position: "absolute", - visibility: "visible", - left: -j * width, - top: -i * height - }) - - // select the wrapper - make it overflow: hidden and absolute positioned based on - // where the original was located +left and +top equal to the size of pieces - .parent() - .addClass( "ui-effects-explode" ) - .css({ - position: "absolute", - overflow: "hidden", - width: width, - height: height, - left: left + ( show ? mx * width : 0 ), - top: top + ( show ? my * height : 0 ), - opacity: show ? 0 : 1 - }).animate({ - left: left + ( show ? 0 : mx * width ), - top: top + ( show ? 0 : my * height ), - opacity: show ? 1 : 0 - }, o.duration || 500, o.easing, childComplete ); - } - } - - function animComplete() { - el.css({ - visibility: "visible" - }); - $( pieces ).remove(); - if ( !show ) { - el.hide(); - } - done(); - } -}; - - -/*! - * jQuery UI Effects Fade 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/fade-effect/ - */ - - -var effectFade = $.effects.effect.fade = function( o, done ) { - var el = $( this ), - mode = $.effects.setMode( el, o.mode || "toggle" ); - - el.animate({ - opacity: mode - }, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: done - }); -}; - - -/*! - * jQuery UI Effects Fold 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/fold-effect/ - */ - - -var effectFold = $.effects.effect.fold = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), - show = mode === "show", - hide = mode === "hide", - size = o.size || 15, - percent = /([0-9]+)%/.exec( size ), - horizFirst = !!o.horizFirst, - widthFirst = show !== horizFirst, - ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], - duration = o.duration / 2, - wrapper, distance, - animation1 = {}, - animation2 = {}; - - $.effects.save( el, props ); - el.show(); - - // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - distance = widthFirst ? - [ wrapper.width(), wrapper.height() ] : - [ wrapper.height(), wrapper.width() ]; - - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; - } - if ( show ) { - wrapper.css( horizFirst ? { - height: 0, - width: size - } : { - height: size, - width: 0 - }); - } - - // Animation - animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; - animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; - - // Animate - wrapper - .animate( animation1, duration, o.easing ) - .animate( animation2, duration, o.easing, function() { - if ( hide ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - -}; - - -/*! - * jQuery UI Effects Highlight 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/highlight-effect/ - */ - - -var effectHighlight = $.effects.effect.highlight = function( o, done ) { - var elem = $( this ), - props = [ "backgroundImage", "backgroundColor", "opacity" ], - mode = $.effects.setMode( elem, o.mode || "show" ), - animation = { - backgroundColor: elem.css( "backgroundColor" ) - }; - - if (mode === "hide") { - animation.opacity = 0; - } - - $.effects.save( elem, props ); - - elem - .show() - .css({ - backgroundImage: "none", - backgroundColor: o.color || "#ffff99" - }) - .animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - elem.hide(); - } - $.effects.restore( elem, props ); - done(); + _addHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.addClass( this.options.hoverClass ); } - }); -}; - - -/*! - * jQuery UI Effects Size 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/size-effect/ - */ - - -var effectSize = $.effects.effect.size = function( o, done ) { - - // Create element - var original, baseline, factor, - el = $( this ), - props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], - - // Always restore - props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], - - // Copy for children - props2 = [ "width", "height", "overflow" ], - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], - - // Set options - mode = $.effects.setMode( el, o.mode || "effect" ), - restore = o.restore || mode !== "effect", - scale = o.scale || "both", - origin = o.origin || [ "middle", "center" ], - position = el.css( "position" ), - props = restore ? props0 : props1, - zero = { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - }; - - if ( mode === "show" ) { - el.show(); - } - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }; - - if ( o.mode === "toggle" && mode === "show" ) { - el.from = o.to || zero; - el.to = o.from || original; - } else { - el.from = o.from || ( mode === "show" ? zero : original ); - el.to = o.to || ( mode === "hide" ? zero : original ); - } - - // Set scaling factor - factor = { - from: { - y: el.from.height / original.height, - x: el.from.width / original.width }, - to: { - y: el.to.height / original.height, - x: el.to.width / original.width - } - }; - - // Scale the css box - if ( scale === "box" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( vProps ); - el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - props = props.concat( hProps ); - el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); - el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); - } - } - - // Scale the content - if ( scale === "content" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( cProps ).concat( props2 ); - el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); - } - } - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - el.css( "overflow", "hidden" ).css( el.from ); - - // Adjust - if (origin) { // Calculate baseline shifts - baseline = $.effects.getBaseline( origin, original ); - el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; - el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; - el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; - el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; - } - el.css( el.from ); // set top & left - - // Animate - if ( scale === "content" || scale === "both" ) { // Scale the children - - // Add margins/font-size - vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); - hProps = hProps.concat([ "marginLeft", "marginRight" ]); - props2 = props0.concat(vProps).concat(hProps); - - el.find( "*[width]" ).each( function() { - var child = $( this ), - c_original = { - height: child.height(), - width: child.width(), - outerHeight: child.outerHeight(), - outerWidth: child.outerWidth() - }; - if (restore) { - $.effects.save(child, props2); - } - - child.from = { - height: c_original.height * factor.from.y, - width: c_original.width * factor.from.x, - outerHeight: c_original.outerHeight * factor.from.y, - outerWidth: c_original.outerWidth * factor.from.x - }; - child.to = { - height: c_original.height * factor.to.y, - width: c_original.width * factor.to.x, - outerHeight: c_original.height * factor.to.y, - outerWidth: c_original.width * factor.to.x - }; - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); - child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); - child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); - } - - // Animate children - child.css( child.from ); - child.animate( child.to, o.duration, o.easing, function() { - - // Restore children - if ( restore ) { - $.effects.restore( child, props2 ); - } - }); - }); - } - - // Animate - el.animate( el.to, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( el.to.opacity === 0 ) { - el.css( "opacity", el.from.opacity ); - } - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - if ( !restore ) { - - // we need to calculate our new positioning based on the scaling - if ( position === "static" ) { - el.css({ - position: "relative", - top: el.to.top, - left: el.to.left - }); - } else { - $.each([ "top", "left" ], function( idx, pos ) { - el.css( pos, function( _, str ) { - var val = parseInt( str, 10 ), - toRef = idx ? el.to.left : el.to.top; - - // if original was "auto", recalculate the new value from wrapper - if ( str === "auto" ) { - return toRef + "px"; - } - - return val + toRef + "px"; - }); - }); - } + _removeHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.removeClass( this.options.hoverClass ); } - - $.effects.removeWrapper( el ); - done(); } - }); - -}; - - -/*! - * jQuery UI Effects Scale 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/scale-effect/ - */ - - -var effectScale = $.effects.effect.scale = function( o, done ) { - - // Create element - var el = $( this ), - options = $.extend( true, {}, o ), - mode = $.effects.setMode( el, o.mode || "effect" ), - percent = parseInt( o.percent, 10 ) || - ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), - direction = o.direction || "both", - origin = o.origin, - original = { - height: el.height(), - width: el.width(), - outerHeight: el.outerHeight(), - outerWidth: el.outerWidth() - }, - factor = { - y: direction !== "horizontal" ? (percent / 100) : 1, - x: direction !== "vertical" ? (percent / 100) : 1 - }; - - // We are going to pass this effect to the size effect: - options.effect = "size"; - options.queue = false; - options.complete = done; - - // Set default origin and restore for show/hide - if ( mode !== "effect" ) { - options.origin = origin || [ "middle", "center" ]; - options.restore = true; - } - - options.from = o.from || ( mode === "show" ? { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - } : original ); - options.to = { - height: original.height * factor.y, - width: original.width * factor.x, - outerHeight: original.outerHeight * factor.y, - outerWidth: original.outerWidth * factor.x - }; - - // Fade option to support puff - if ( options.fade ) { - if ( mode === "show" ) { - options.from.opacity = 0; - options.to.opacity = 1; - } - if ( mode === "hide" ) { - options.from.opacity = 1; - options.to.opacity = 0; - } - } - - // Animate - el.effect( options ); - -}; - - -/*! - * jQuery UI Effects Puff 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/puff-effect/ - */ - - -var effectPuff = $.effects.effect.puff = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "hide" ), - hide = mode === "hide", - percent = parseInt( o.percent, 10 ) || 150, - factor = percent / 100, - original = { - height: elem.height(), - width: elem.width(), - outerHeight: elem.outerHeight(), - outerWidth: elem.outerWidth() - }; - - $.extend( o, { - effect: "scale", - queue: false, - fade: true, - mode: mode, - complete: done, - percent: hide ? percent : 100, - from: hide ? - original : - { - height: original.height * factor, - width: original.width * factor, - outerHeight: original.outerHeight * factor, - outerWidth: original.outerWidth * factor - } - }); - - elem.effect( o ); -}; - - -/*! - * jQuery UI Effects Pulsate 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/pulsate-effect/ - */ - - -var effectPulsate = $.effects.effect.pulsate = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "show" ), - show = mode === "show", - hide = mode === "hide", - showhide = ( show || mode === "hide" ), - - // showing or hiding leaves of the "last" animation - anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), - duration = o.duration / anims, - animateTo = 0, - queue = elem.queue(), - queuelen = queue.length, - i; - - if ( show || !elem.is(":visible")) { - elem.css( "opacity", 0 ).show(); - animateTo = 1; - } - - // anims - 1 opacity "toggles" - for ( i = 1; i < anims; i++ ) { - elem.animate({ - opacity: animateTo - }, duration, o.easing ); - animateTo = 1 - animateTo; - } - - elem.animate({ - opacity: animateTo - }, duration, o.easing); - - elem.queue(function() { - if ( hide ) { - elem.hide(); - } - done(); - }); - - // We just queued up "anims" animations, we need to put them next in the queue - if ( queuelen > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - elem.dequeue(); -}; - - -/*! - * jQuery UI Effects Shake 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/shake-effect/ - */ - - -var effectShake = $.effects.effect.shake = function( o, done ) { - - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "effect" ), - direction = o.direction || "left", - distance = o.distance || 20, - times = o.times || 3, - anims = times * 2 + 1, - speed = Math.round( o.duration / anims ), - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - animation = {}, - animation1 = {}, - animation2 = {}, - i, - - // we will need to re-assemble the queue to stack our animations in place - queue = el.queue(), - queuelen = queue.length; - - $.effects.save( el, props ); - el.show(); - $.effects.createWrapper( el ); - - // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; - - // Animate - el.animate( animation, speed, o.easing ); - - // Shakes - for ( i = 1; i < times; i++ ) { - el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); - } - el - .animate( animation1, speed, o.easing ) - .animate( animation, speed / 2, o.easing ) - .queue(function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - }); - - // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); - } - el.dequeue(); - -}; - - -/*! - * jQuery UI Effects Slide 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/slide-effect/ - */ - - -var effectSlide = $.effects.effect.slide = function( o, done ) { - - // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "width", "height" ], - mode = $.effects.setMode( el, o.mode || "show" ), - show = mode === "show", - direction = o.direction || "left", - ref = (direction === "up" || direction === "down") ? "top" : "left", - positiveMotion = (direction === "up" || direction === "left"), - distance, - animation = {}; - - // Adjust - $.effects.save( el, props ); - el.show(); - distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); - - $.effects.createWrapper( el ).css({ - overflow: "hidden" - }); - - if ( show ) { - el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); - } - - // Animation - animation[ ref ] = ( show ? - ( positiveMotion ? "+=" : "-=") : - ( positiveMotion ? "-=" : "+=")) + - distance; + } ); +} - // Animate - el.animate( animation, { - queue: false, - duration: o.duration, - easing: o.easing, - complete: function() { - if ( mode === "hide" ) { - el.hide(); - } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); - done(); - } - }); -}; +var widgetsDroppable = $.ui.droppable; /*! - * jQuery UI Effects Transfer 1.11.4 + * jQuery UI Progressbar 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/transfer-effect/ */ +//>>label: Progressbar +//>>group: Widgets +// jscs:disable maximumLineLength +//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. +// jscs:enable maximumLineLength +//>>docs: http://api.jqueryui.com/progressbar/ +//>>demos: http://jqueryui.com/progressbar/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/progressbar.css +//>>css.theme: ../../themes/base/theme.css -var effectTransfer = $.effects.effect.transfer = function( o, done ) { - var elem = $( this ), - target = $( o.to ), - targetFixed = target.css( "position" ) === "fixed", - body = $("body"), - fixTop = targetFixed ? body.scrollTop() : 0, - fixLeft = targetFixed ? body.scrollLeft() : 0, - endPosition = target.offset(), - animation = { - top: endPosition.top - fixTop, - left: endPosition.left - fixLeft, - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = elem.offset(), - transfer = $( "<div class='ui-effects-transfer'></div>" ) - .appendTo( document.body ) - .addClass( o.className ) - .css({ - top: startPosition.top - fixTop, - left: startPosition.left - fixLeft, - height: elem.innerHeight(), - width: elem.innerWidth(), - position: targetFixed ? "fixed" : "absolute" - }) - .animate( animation, o.duration, o.easing, function() { - transfer.remove(); - done(); - }); -}; -/*! - * jQuery UI Progressbar 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/progressbar/ - */ - - -var progressbar = $.widget( "ui.progressbar", { - version: "1.11.4", +var widgetsProgressbar = $.widget( "ui.progressbar", { + version: "1.12.1", options: { + classes: { + "ui-progressbar": "ui-corner-all", + "ui-progressbar-value": "ui-corner-left", + "ui-progressbar-complete": "ui-corner-right" + }, max: 100, value: 0, @@ -11791,31 +13377,26 @@ var progressbar = $.widget( "ui.progressbar", { min: 0, _create: function() { + // Constrain initial value this.oldValue = this.options.value = this._constrainedValue(); - this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .attr({ - // Only set static values, aria-valuenow and aria-valuemax are - // set inside _refreshValue() - role: "progressbar", - "aria-valuemin": this.min - }); + this.element.attr( { - this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) - .appendTo( this.element ); + // Only set static values; aria-valuenow and aria-valuemax are + // set inside _refreshValue() + role: "progressbar", + "aria-valuemin": this.min + } ); + this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); + this.valueDiv = $( "<div>" ).appendTo( this.element ); + this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 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" ); + this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); this.valueDiv.remove(); }, @@ -11836,7 +13417,7 @@ var progressbar = $.widget( "ui.progressbar", { this.indeterminate = newValue === false; - // sanitize value + // Sanitize value if ( typeof newValue !== "number" ) { newValue = 0; } @@ -11846,6 +13427,7 @@ var progressbar = $.widget( "ui.progressbar", { }, _setOptions: function( options ) { + // Ensure "value" option is set after other values (like max) var value = options.value; delete options.value; @@ -11858,19 +13440,24 @@ var progressbar = $.widget( "ui.progressbar", { _setOption: function( key, value ) { if ( key === "max" ) { + // Don't allow a max less than min value = Math.max( this.min, value ); } - if ( key === "disabled" ) { - this.element - .toggleClass( "ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - } this._super( key, value ); }, + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", value ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + _percentage: function() { - return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); + return this.indeterminate ? + 100 : + 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); }, _refreshValue: function() { @@ -11879,21 +13466,24 @@ var progressbar = $.widget( "ui.progressbar", { this.valueDiv .toggle( this.indeterminate || value > this.min ) - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); + .width( percentage.toFixed( 0 ) + "%" ); - this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); + this + ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, + value === this.options.max ) + ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); if ( this.indeterminate ) { this.element.removeAttr( "aria-valuenow" ); if ( !this.overlayDiv ) { - this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); + this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); + this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); } } else { - this.element.attr({ + this.element.attr( { "aria-valuemax": this.options.max, "aria-valuenow": value - }); + } ); if ( this.overlayDiv ) { this.overlayDiv.remove(); this.overlayDiv = null; @@ -11908,23 +13498,29 @@ var progressbar = $.widget( "ui.progressbar", { this._trigger( "complete" ); } } -}); +} ); /*! - * jQuery UI Selectable 1.11.4 + * jQuery UI Selectable 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/selectable/ */ +//>>label: Selectable +//>>group: Interactions +//>>description: Allows groups of elements to be selected with the mouse. +//>>docs: http://api.jqueryui.com/selectable/ +//>>demos: http://jqueryui.com/selectable/ +//>>css.structure: ../../themes/base/selectable.css + -var selectable = $.widget("ui.selectable", $.ui.mouse, { - version: "1.11.4", + +var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { + version: "1.12.1", options: { appendTo: "body", autoRefresh: true, @@ -11932,7 +13528,7 @@ var selectable = $.widget("ui.selectable", $.ui.mouse, { filter: "*", tolerance: "touch", - // callbacks + // Callbacks selected: null, selecting: null, start: null, @@ -11941,21 +13537,25 @@ var selectable = $.widget("ui.selectable", $.ui.mouse, { unselecting: null }, _create: function() { - var selectees, - that = this; + var that = this; - this.element.addClass("ui-selectable"); + this._addClass( "ui-selectable" ); this.dragged = false; - // cache selectee children based on filter + // Cache selectee children based on filter this.refresh = function() { - selectees = $(that.options.filter, that.element[0]); - selectees.addClass("ui-selectee"); - selectees.each(function() { - var $this = $(this), - pos = $this.offset(); - $.data(this, "selectable-item", { + that.elementPos = $( that.element[ 0 ] ).offset(); + that.selectees = $( that.options.filter, that.element[ 0 ] ); + that._addClass( that.selectees, "ui-selectee" ); + that.selectees.each( function() { + var $this = $( this ), + selecteeOffset = $this.offset(), + pos = { + left: selecteeOffset.left - that.elementPos.left, + top: selecteeOffset.top - that.elementPos.top + }; + $.data( this, "selectable-item", { element: this, $element: $this, left: pos.left, @@ -11963,243 +13563,270 @@ var selectable = $.widget("ui.selectable", $.ui.mouse, { right: pos.left + $this.outerWidth(), bottom: pos.top + $this.outerHeight(), startselected: false, - selected: $this.hasClass("ui-selected"), - selecting: $this.hasClass("ui-selecting"), - unselecting: $this.hasClass("ui-unselecting") - }); - }); + selected: $this.hasClass( "ui-selected" ), + selecting: $this.hasClass( "ui-selecting" ), + unselecting: $this.hasClass( "ui-unselecting" ) + } ); + } ); }; this.refresh(); - this.selectees = selectees.addClass("ui-selectee"); - this._mouseInit(); - this.helper = $("<div class='ui-selectable-helper'></div>"); + this.helper = $( "<div>" ); + this._addClass( this.helper, "ui-selectable-helper" ); }, _destroy: function() { - this.selectees - .removeClass("ui-selectee") - .removeData("selectable-item"); - this.element - .removeClass("ui-selectable ui-selectable-disabled"); + this.selectees.removeData( "selectable-item" ); this._mouseDestroy(); }, - _mouseStart: function(event) { + _mouseStart: function( event ) { var that = this, options = this.options; this.opos = [ event.pageX, event.pageY ]; + this.elementPos = $( this.element[ 0 ] ).offset(); - if (this.options.disabled) { + if ( this.options.disabled ) { return; } - this.selectees = $(options.filter, this.element[0]); + this.selectees = $( options.filter, this.element[ 0 ] ); + + this._trigger( "start", event ); - this._trigger("start", event); + $( options.appendTo ).append( this.helper ); - $(options.appendTo).append(this.helper); // position helper (lasso) - this.helper.css({ + this.helper.css( { "left": event.pageX, "top": event.pageY, "width": 0, "height": 0 - }); + } ); - if (options.autoRefresh) { + if ( options.autoRefresh ) { this.refresh(); } - this.selectees.filter(".ui-selected").each(function() { - var selectee = $.data(this, "selectable-item"); + this.selectees.filter( ".ui-selected" ).each( function() { + var selectee = $.data( this, "selectable-item" ); selectee.startselected = true; - if (!event.metaKey && !event.ctrlKey) { - selectee.$element.removeClass("ui-selected"); + if ( !event.metaKey && !event.ctrlKey ) { + that._removeClass( selectee.$element, "ui-selected" ); selectee.selected = false; - selectee.$element.addClass("ui-unselecting"); + that._addClass( selectee.$element, "ui-unselecting" ); selectee.unselecting = true; + // selectable UNSELECTING callback - that._trigger("unselecting", event, { + that._trigger( "unselecting", event, { unselecting: selectee.element - }); + } ); } - }); + } ); - $(event.target).parents().addBack().each(function() { + $( event.target ).parents().addBack().each( function() { var doSelect, - selectee = $.data(this, "selectable-item"); - if (selectee) { - doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); - selectee.$element - .removeClass(doSelect ? "ui-unselecting" : "ui-selected") - .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee = $.data( this, "selectable-item" ); + if ( selectee ) { + doSelect = ( !event.metaKey && !event.ctrlKey ) || + !selectee.$element.hasClass( "ui-selected" ); + that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) + ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); selectee.unselecting = !doSelect; selectee.selecting = doSelect; selectee.selected = doSelect; + // selectable (UN)SELECTING callback - if (doSelect) { - that._trigger("selecting", event, { + if ( doSelect ) { + that._trigger( "selecting", event, { selecting: selectee.element - }); + } ); } else { - that._trigger("unselecting", event, { + that._trigger( "unselecting", event, { unselecting: selectee.element - }); + } ); } return false; } - }); + } ); }, - _mouseDrag: function(event) { + _mouseDrag: function( event ) { this.dragged = true; - if (this.options.disabled) { + if ( this.options.disabled ) { return; } var tmp, that = this, options = this.options, - x1 = this.opos[0], - y1 = this.opos[1], + x1 = this.opos[ 0 ], + y1 = this.opos[ 1 ], x2 = event.pageX, y2 = event.pageY; - if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } - if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } - this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); + if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; } + if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; } + this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); - this.selectees.each(function() { - var selectee = $.data(this, "selectable-item"), - hit = false; + this.selectees.each( function() { + var selectee = $.data( this, "selectable-item" ), + hit = false, + offset = {}; //prevent helper from being selected if appendTo: selectable - if (!selectee || selectee.element === that.element[0]) { + if ( !selectee || selectee.element === that.element[ 0 ] ) { return; } - if (options.tolerance === "touch") { - hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); - } else if (options.tolerance === "fit") { - hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); + offset.left = selectee.left + that.elementPos.left; + offset.right = selectee.right + that.elementPos.left; + offset.top = selectee.top + that.elementPos.top; + offset.bottom = selectee.bottom + that.elementPos.top; + + if ( options.tolerance === "touch" ) { + hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || + offset.bottom < y1 ) ); + } else if ( options.tolerance === "fit" ) { + hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && + offset.bottom < y2 ); } - if (hit) { + if ( hit ) { + // SELECT - if (selectee.selected) { - selectee.$element.removeClass("ui-selected"); + if ( selectee.selected ) { + that._removeClass( selectee.$element, "ui-selected" ); selectee.selected = false; } - if (selectee.unselecting) { - selectee.$element.removeClass("ui-unselecting"); + if ( selectee.unselecting ) { + that._removeClass( selectee.$element, "ui-unselecting" ); selectee.unselecting = false; } - if (!selectee.selecting) { - selectee.$element.addClass("ui-selecting"); + if ( !selectee.selecting ) { + that._addClass( selectee.$element, "ui-selecting" ); selectee.selecting = true; + // selectable SELECTING callback - that._trigger("selecting", event, { + that._trigger( "selecting", event, { selecting: selectee.element - }); + } ); } } else { + // UNSELECT - if (selectee.selecting) { - if ((event.metaKey || event.ctrlKey) && selectee.startselected) { - selectee.$element.removeClass("ui-selecting"); + if ( selectee.selecting ) { + if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selecting" ); selectee.selecting = false; - selectee.$element.addClass("ui-selected"); + that._addClass( selectee.$element, "ui-selected" ); selectee.selected = true; } else { - selectee.$element.removeClass("ui-selecting"); + that._removeClass( selectee.$element, "ui-selecting" ); selectee.selecting = false; - if (selectee.startselected) { - selectee.$element.addClass("ui-unselecting"); + if ( selectee.startselected ) { + that._addClass( selectee.$element, "ui-unselecting" ); selectee.unselecting = true; } + // selectable UNSELECTING callback - that._trigger("unselecting", event, { + that._trigger( "unselecting", event, { unselecting: selectee.element - }); + } ); } } - if (selectee.selected) { - if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { - selectee.$element.removeClass("ui-selected"); + if ( selectee.selected ) { + if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selected" ); selectee.selected = false; - selectee.$element.addClass("ui-unselecting"); + that._addClass( selectee.$element, "ui-unselecting" ); selectee.unselecting = true; + // selectable UNSELECTING callback - that._trigger("unselecting", event, { + that._trigger( "unselecting", event, { unselecting: selectee.element - }); + } ); } } } - }); + } ); return false; }, - _mouseStop: function(event) { + _mouseStop: function( event ) { var that = this; this.dragged = false; - $(".ui-unselecting", this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass("ui-unselecting"); + $( ".ui-unselecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-unselecting" ); selectee.unselecting = false; selectee.startselected = false; - that._trigger("unselected", event, { + that._trigger( "unselected", event, { unselected: selectee.element - }); - }); - $(".ui-selecting", this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); + } ); + } ); + $( ".ui-selecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-selecting" ) + ._addClass( selectee.$element, "ui-selected" ); selectee.selecting = false; selectee.selected = true; selectee.startselected = true; - that._trigger("selected", event, { + that._trigger( "selected", event, { selected: selectee.element - }); - }); - this._trigger("stop", event); + } ); + } ); + this._trigger( "stop", event ); this.helper.remove(); return false; } -}); +} ); /*! - * jQuery UI Selectmenu 1.11.4 + * jQuery UI Selectmenu 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/selectmenu */ +//>>label: Selectmenu +//>>group: Widgets +// jscs:disable maximumLineLength +//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. +// jscs:enable maximumLineLength +//>>docs: http://api.jqueryui.com/selectmenu/ +//>>demos: http://jqueryui.com/selectmenu/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css +//>>css.theme: ../../themes/base/theme.css -var selectmenu = $.widget( "ui.selectmenu", { - version: "1.11.4", + + +var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { + version: "1.12.1", defaultElement: "<select>", options: { appendTo: null, + classes: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + }, disabled: null, icons: { button: "ui-icon-triangle-1-s" @@ -12209,9 +13836,9 @@ var selectmenu = $.widget( "ui.selectmenu", { at: "left bottom", collision: "none" }, - width: null, + width: false, - // callbacks + // Callbacks change: null, close: null, focus: null, @@ -12229,64 +13856,66 @@ var selectmenu = $.widget( "ui.selectmenu", { this._drawButton(); this._drawMenu(); + this._bindFormResetHandler(); - if ( this.options.disabled ) { - this.disable(); - } + this._rendered = false; + this.menuItems = $(); }, _drawButton: function() { - var that = this; + var icon, + that = this, + item = this._parseOption( + this.element.find( "option:selected" ), + this.element[ 0 ].selectedIndex + ); // Associate existing label with the new button - this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button ); - this._on( this.label, { + this.labels = this.element.labels().attr( "for", this.ids.button ); + this._on( this.labels, { click: function( event ) { this.button.focus(); event.preventDefault(); } - }); + } ); // Hide original select element this.element.hide(); // Create button this.button = $( "<span>", { - "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all", tabindex: this.options.disabled ? -1 : 0, id: this.ids.button, role: "combobox", "aria-expanded": "false", "aria-autocomplete": "list", "aria-owns": this.ids.menu, - "aria-haspopup": "true" - }) + "aria-haspopup": "true", + title: this.element.attr( "title" ) + } ) .insertAfter( this.element ); - $( "<span>", { - "class": "ui-icon " + this.options.icons.button - }) - .prependTo( this.button ); + this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", + "ui-button ui-widget" ); - this.buttonText = $( "<span>", { - "class": "ui-selectmenu-text" - }) + icon = $( "<span>" ).appendTo( this.button ); + this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); + this.buttonItem = this._renderButtonItem( item ) .appendTo( this.button ); - this._setText( this.buttonText, this.element.find( "option:selected" ).text() ); - this._resizeButton(); + if ( this.options.width !== false ) { + this._resizeButton(); + } this._on( this.button, this._buttonEvents ); this.button.one( "focusin", function() { // Delay rendering the menu items until the button receives focus. // The menu may have already been rendered via a programmatic open. - if ( !that.menuItems ) { + if ( !that._rendered ) { that._refreshMenu(); } - }); - this._hoverable( this.button ); - this._focusable( this.button ); + } ); }, _drawMenu: function() { @@ -12297,23 +13926,24 @@ var selectmenu = $.widget( "ui.selectmenu", { "aria-hidden": "true", "aria-labelledby": this.ids.button, id: this.ids.menu - }); + } ); // Wrap menu - this.menuWrap = $( "<div>", { - "class": "ui-selectmenu-menu ui-front" - }) - .append( this.menu ) - .appendTo( this._appendTo() ); + this.menuWrap = $( "<div>" ).append( this.menu ); + this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); + this.menuWrap.appendTo( this._appendTo() ); // Initialize menu widget this.menuInstance = this.menu - .menu({ + .menu( { + classes: { + "ui-menu": "ui-corner-bottom" + }, role: "listbox", select: function( event, ui ) { event.preventDefault(); - // support: IE8 + // Support: IE8 // If the item was selected via a click, the text selection // will be destroyed in IE that._setSelection(); @@ -12335,14 +13965,9 @@ var selectmenu = $.widget( "ui.selectmenu", { that.button.attr( "aria-activedescendant", that.menuItems.eq( item.index ).attr( "id" ) ); } - }) + } ) .menu( "instance" ); - // Adjust menu styles to dropdown - this.menu - .addClass( "ui-corner-bottom" ) - .removeClass( "ui-corner-all" ); - // Don't close the menu on mouseleave this.menuInstance._off( this.menu, "mouseleave" ); @@ -12359,27 +13984,37 @@ var selectmenu = $.widget( "ui.selectmenu", { refresh: function() { this._refreshMenu(); - this._setText( this.buttonText, this._getSelectedItem().text() ); - if ( !this.options.width ) { + this.buttonItem.replaceWith( + this.buttonItem = this._renderButtonItem( + + // Fall back to an empty object in case there are no options + this._getSelectedItem().data( "ui-selectmenu-item" ) || {} + ) + ); + if ( this.options.width === null ) { this._resizeButton(); } }, _refreshMenu: function() { - this.menu.empty(); - var item, options = this.element.find( "option" ); - if ( !options.length ) { - return; - } + this.menu.empty(); this._parseOptions( options ); this._renderMenu( this.menu, this.items ); this.menuInstance.refresh(); - this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" ); + this.menuItems = this.menu.find( "li" ) + .not( ".ui-selectmenu-optgroup" ) + .find( ".ui-menu-item-wrapper" ); + + this._rendered = true; + + if ( !options.length ) { + return; + } item = this._getSelectedItem(); @@ -12397,15 +14032,20 @@ var selectmenu = $.widget( "ui.selectmenu", { } // If this is the first time the menu is being opened, render the items - if ( !this.menuItems ) { + if ( !this._rendered ) { this._refreshMenu(); } else { // Menu clears focus on close, reset focus to selected item - this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" ); + this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); this.menuInstance.focus( null, this._getSelectedItem() ); } + // If there are no options, don't open the menu + if ( !this.menuItems.length ) { + return; + } + this.isOpen = true; this._toggleAttr(); this._resizeMenu(); @@ -12442,26 +14082,38 @@ var selectmenu = $.widget( "ui.selectmenu", { return this.menu; }, + _renderButtonItem: function( item ) { + var buttonItem = $( "<span>" ); + + this._setText( buttonItem, item.label ); + this._addClass( buttonItem, "ui-selectmenu-text" ); + + return buttonItem; + }, + _renderMenu: function( ul, items ) { var that = this, currentOptgroup = ""; $.each( items, function( index, item ) { + var li; + if ( item.optgroup !== currentOptgroup ) { - $( "<li>", { - "class": "ui-selectmenu-optgroup ui-menu-divider" + - ( item.element.parent( "optgroup" ).prop( "disabled" ) ? - " ui-state-disabled" : - "" ), + li = $( "<li>", { text: item.optgroup - }) - .appendTo( ul ); + } ); + that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + + ( item.element.parent( "optgroup" ).prop( "disabled" ) ? + " ui-state-disabled" : + "" ) ); + + li.appendTo( ul ); currentOptgroup = item.optgroup; } that._renderItemData( ul, item ); - }); + } ); }, _renderItemData: function( ul, item ) { @@ -12469,14 +14121,17 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _renderItem: function( ul, item ) { - var li = $( "<li>" ); + var li = $( "<li>" ), + wrapper = $( "<div>", { + title: item.element.attr( "title" ) + } ); if ( item.disabled ) { - li.addClass( "ui-state-disabled" ); + this._addClass( li, null, "ui-state-disabled" ); } - this._setText( li, item.label ); + this._setText( wrapper, item.label ); - return li.appendTo( ul ); + return li.append( wrapper ).appendTo( ul ); }, _setText: function( element, value ) { @@ -12492,9 +14147,9 @@ var selectmenu = $.widget( "ui.selectmenu", { filter = ".ui-menu-item"; if ( this.isOpen ) { - item = this.menuItems.eq( this.focusIndex ); + item = this.menuItems.eq( this.focusIndex ).parent( "li" ); } else { - item = this.menuItems.eq( this.element[ 0 ].selectedIndex ); + item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); filter += ":not(.ui-state-disabled)"; } @@ -12510,7 +14165,7 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _getSelectedItem: function() { - return this.menuItems.eq( this.element[ 0 ].selectedIndex ); + return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); }, _toggle: function( event ) { @@ -12529,12 +14184,12 @@ var selectmenu = $.widget( "ui.selectmenu", { selection.removeAllRanges(); selection.addRange( this.range ); - // support: IE8 + // Support: IE8 } else { this.range.select(); } - // support: IE + // Support: IE // Setting the text selection kills the button focus in IE, but // restoring the focus doesn't kill the selection. this.button.focus(); @@ -12546,7 +14201,8 @@ var selectmenu = $.widget( "ui.selectmenu", { return; } - if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) { + if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + + $.ui.escapeSelector( this.ids.button ) ).length ) { this.close( event ); } } @@ -12564,7 +14220,7 @@ var selectmenu = $.widget( "ui.selectmenu", { this.range = selection.getRangeAt( 0 ); } - // support: IE8 + // Support: IE8 } else { this.range = document.selection.createRange(); } @@ -12578,54 +14234,54 @@ var selectmenu = $.widget( "ui.selectmenu", { keydown: function( event ) { var preventDefault = true; switch ( event.keyCode ) { - case $.ui.keyCode.TAB: - case $.ui.keyCode.ESCAPE: - this.close( event ); - preventDefault = false; - break; - case $.ui.keyCode.ENTER: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } - break; - case $.ui.keyCode.UP: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "prev", event ); - } - break; - case $.ui.keyCode.DOWN: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "next", event ); - } - break; - case $.ui.keyCode.SPACE: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } else { - this._toggle( event ); - } - break; - case $.ui.keyCode.LEFT: + case $.ui.keyCode.TAB: + case $.ui.keyCode.ESCAPE: + this.close( event ); + preventDefault = false; + break; + case $.ui.keyCode.ENTER: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } + break; + case $.ui.keyCode.UP: + if ( event.altKey ) { + this._toggle( event ); + } else { this._move( "prev", event ); - break; - case $.ui.keyCode.RIGHT: + } + break; + case $.ui.keyCode.DOWN: + if ( event.altKey ) { + this._toggle( event ); + } else { this._move( "next", event ); - break; - case $.ui.keyCode.HOME: - case $.ui.keyCode.PAGE_UP: - this._move( "first", event ); - break; - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_DOWN: - this._move( "last", event ); - break; - default: - this.menu.trigger( event ); - preventDefault = false; + } + break; + case $.ui.keyCode.SPACE: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } else { + this._toggle( event ); + } + break; + case $.ui.keyCode.LEFT: + this._move( "prev", event ); + break; + case $.ui.keyCode.RIGHT: + this._move( "next", event ); + break; + case $.ui.keyCode.HOME: + case $.ui.keyCode.PAGE_UP: + this._move( "first", event ); + break; + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_DOWN: + this._move( "last", event ); + break; + default: + this.menu.trigger( event ); + preventDefault = false; } if ( preventDefault ) { @@ -12635,7 +14291,7 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _selectFocusedItem: function( event ) { - var item = this.menuItems.eq( this.focusIndex ); + var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); if ( !item.hasClass( "ui-state-disabled" ) ) { this._select( item.data( "ui-selectmenu-item" ), event ); } @@ -12646,7 +14302,7 @@ var selectmenu = $.widget( "ui.selectmenu", { // Change native select element this.element[ 0 ].selectedIndex = item.index; - this._setText( this.buttonText, item.label ); + this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); this._setAria( item ); this._trigger( "select", event, { item: item } ); @@ -12660,18 +14316,18 @@ var selectmenu = $.widget( "ui.selectmenu", { _setAria: function( item ) { var id = this.menuItems.eq( item.index ).attr( "id" ); - this.button.attr({ + this.button.attr( { "aria-labelledby": id, "aria-activedescendant": id - }); + } ); this.menu.attr( "aria-activedescendant", id ); }, _setOption: function( key, value ) { if ( key === "icons" ) { - this.button.find( "span.ui-icon" ) - .removeClass( this.options.icons.button ) - .addClass( value.button ); + var icon = this.button.find( "span.ui-icon" ); + this._removeClass( icon, null, this.options.icons.button ) + ._addClass( icon, null, value.button ); } this._super( key, value ); @@ -12680,26 +14336,27 @@ var selectmenu = $.widget( "ui.selectmenu", { this.menuWrap.appendTo( this._appendTo() ); } - if ( key === "disabled" ) { - this.menuInstance.option( "disabled", value ); - this.button - .toggleClass( "ui-state-disabled", value ) - .attr( "aria-disabled", value ); - - this.element.prop( "disabled", value ); - if ( value ) { - this.button.attr( "tabindex", -1 ); - this.close(); - } else { - this.button.attr( "tabindex", 0 ); - } - } - if ( key === "width" ) { this._resizeButton(); } }, + _setOptionDisabled: function( value ) { + this._super( value ); + + this.menuInstance.option( "disabled", value ); + this.button.attr( "aria-disabled", value ); + this._toggleClass( this.button, null, "ui-state-disabled", value ); + + this.element.prop( "disabled", value ); + if ( value ) { + this.button.attr( "tabindex", -1 ); + this.close(); + } else { + this.button.attr( "tabindex", 0 ); + } + }, + _appendTo: function() { var element = this.options.appendTo; @@ -12710,7 +14367,7 @@ var selectmenu = $.widget( "ui.selectmenu", { } if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front" ); + element = this.element.closest( ".ui-front, dialog" ); } if ( !element.length ) { @@ -12721,18 +14378,31 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _toggleAttr: function() { - this.button - .toggleClass( "ui-corner-top", this.isOpen ) - .toggleClass( "ui-corner-all", !this.isOpen ) - .attr( "aria-expanded", this.isOpen ); - this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen ); + this.button.attr( "aria-expanded", this.isOpen ); + + // We can't use two _toggleClass() calls here, because we need to make sure + // we always remove classes first and add them second, otherwise if both classes have the + // same theme class, it will be removed after we add it. + this._removeClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "closed" : "open" ) ) + ._addClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "open" : "closed" ) ) + ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); + this.menu.attr( "aria-hidden", !this.isOpen ); }, _resizeButton: function() { var width = this.options.width; - if ( !width ) { + // For `width: false`, just remove inline style and stop + if ( width === false ) { + this.button.css( "width", "" ); + return; + } + + // For `width: null`, match the width of the original element + if ( width === null ) { width = this.element.show().outerWidth(); this.element.hide(); } @@ -12744,7 +14414,7 @@ var selectmenu = $.widget( "ui.selectmenu", { this.menu.outerWidth( Math.max( this.button.outerWidth(), - // support: IE10 + // Support: IE10 // IE10 wraps long text (possibly a rounding bug) // so we add 1px to avoid the wrapping this.menu.width( "" ).outerWidth() + 1 @@ -12752,54 +14422,80 @@ var selectmenu = $.widget( "ui.selectmenu", { }, _getCreateOptions: function() { - return { disabled: this.element.prop( "disabled" ) }; + var options = this._super(); + + options.disabled = this.element.prop( "disabled" ); + + return options; }, _parseOptions: function( options ) { - var data = []; - options.each(function( index, item ) { - var option = $( item ), - optgroup = option.parent( "optgroup" ); - data.push({ - element: option, - index: index, - value: option.val(), - label: option.text(), - optgroup: optgroup.attr( "label" ) || "", - disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) - }); - }); + var that = this, + data = []; + options.each( function( index, item ) { + data.push( that._parseOption( $( item ), index ) ); + } ); this.items = data; }, + _parseOption: function( option, index ) { + var optgroup = option.parent( "optgroup" ); + + return { + element: option, + index: index, + value: option.val(), + label: option.text(), + optgroup: optgroup.attr( "label" ) || "", + disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) + }; + }, + _destroy: function() { + this._unbindFormResetHandler(); this.menuWrap.remove(); this.button.remove(); this.element.show(); this.element.removeUniqueId(); - this.label.attr( "for", this.ids.element ); + this.labels.attr( "for", this.ids.element ); } -}); +} ] ); /*! - * jQuery UI Slider 1.11.4 + * jQuery UI Slider 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/slider/ */ +//>>label: Slider +//>>group: Widgets +//>>description: Displays a flexible slider with ranges and accessibility via keyboard. +//>>docs: http://api.jqueryui.com/slider/ +//>>demos: http://jqueryui.com/slider/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/slider.css +//>>css.theme: ../../themes/base/theme.css -var slider = $.widget( "ui.slider", $.ui.mouse, { - version: "1.11.4", + + +var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { + version: "1.12.1", widgetEventPrefix: "slide", options: { animate: false, + classes: { + "ui-slider": "ui-corner-all", + "ui-slider-handle": "ui-corner-all", + + // Note: ui-widget-header isn't the most fittingly semantic framework class for this + // element, but worked best visually with a variety of themes + "ui-slider-range": "ui-corner-all ui-widget-header" + }, distance: 0, max: 100, min: 0, @@ -12809,14 +14505,14 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { value: 0, values: null, - // callbacks + // Callbacks change: null, slide: null, start: null, stop: null }, - // number of pages in a slider + // Number of pages in a slider // (how many times can you page up/down to go through the whole range) numPages: 5, @@ -12829,15 +14525,10 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this._mouseInit(); this._calculateNewMax(); - this.element - .addClass( "ui-slider" + - " ui-slider-" + this.orientation + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all"); + this._addClass( "ui-slider ui-slider-" + this.orientation, + "ui-widget ui-widget-content" ); this._refresh(); - this._setOption( "disabled", this.options.disabled ); this._animateOff = false; }, @@ -12852,8 +14543,8 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { _createHandles: function() { var i, handleCount, options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), - handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", + existingHandles = this.element.find( ".ui-slider-handle" ), + handle = "<span tabindex='0'></span>", handles = []; handleCount = ( options.values && options.values.length ) || 1; @@ -12869,47 +14560,48 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); + this.handle = this.handles.eq( 0 ); - this.handles.each(function( i ) { - $( this ).data( "ui-slider-handle-index", i ); - }); + this.handles.each( function( i ) { + $( this ) + .data( "ui-slider-handle-index", i ) + .attr( "tabIndex", 0 ); + } ); }, _createRange: function() { - var options = this.options, - classes = ""; + var options = this.options; if ( options.range ) { if ( options.range === true ) { if ( !options.values ) { options.values = [ this._valueMin(), this._valueMin() ]; } else if ( options.values.length && options.values.length !== 2 ) { - options.values = [ options.values[0], options.values[0] ]; + options.values = [ options.values[ 0 ], options.values[ 0 ] ]; } else if ( $.isArray( options.values ) ) { - options.values = options.values.slice(0); + options.values = options.values.slice( 0 ); } } if ( !this.range || !this.range.length ) { - this.range = $( "<div></div>" ) + this.range = $( "<div>" ) .appendTo( this.element ); - classes = "ui-slider-range" + - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - " ui-widget-header ui-corner-all"; + this._addClass( this.range, "ui-slider-range" ); } else { - this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) - // Handle range switching from true to min/max - .css({ - "left": "", - "bottom": "" - }); - } + this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); - this.range.addClass( classes + - ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); + // Handle range switching from true to min/max + this.range.css( { + "left": "", + "bottom": "" + } ); + } + if ( options.range === "min" || options.range === "max" ) { + this._addClass( this.range, "ui-slider-range-" + options.range ); + } } else { if ( this.range ) { this.range.remove(); @@ -12931,14 +14623,6 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this.range.remove(); } - this.element - .removeClass( "ui-slider" + - " ui-slider-horizontal" + - " ui-slider-vertical" + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" ); - this._mouseDestroy(); }, @@ -12960,16 +14644,16 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { position = { x: event.pageX, y: event.pageY }; normValue = this._normValueFromMouse( position ); distance = this._valueMax() - this._valueMin() + 1; - this.handles.each(function( i ) { - var thisDistance = Math.abs( normValue - that.values(i) ); - if (( distance > thisDistance ) || + this.handles.each( function( i ) { + var thisDistance = Math.abs( normValue - that.values( i ) ); + if ( ( distance > thisDistance ) || ( distance === thisDistance && - (i === that._lastChangedValue || that.values(i) === o.min ))) { + ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { distance = thisDistance; closestHandle = $( this ); index = i; } - }); + } ); allowed = this._start( event, index ); if ( allowed === false ) { @@ -12979,9 +14663,8 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this._handleIndex = index; - closestHandle - .addClass( "ui-state-active" ) - .focus(); + this._addClass( closestHandle, null, "ui-state-active" ); + closestHandle.trigger( "focus" ); offset = closestHandle.offset(); mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); @@ -12989,9 +14672,9 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { 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) + ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + + ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) }; if ( !this.handles.hasClass( "ui-state-hover" ) ) { @@ -13015,7 +14698,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { }, _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); + this._removeClass( this.handles, null, "ui-state-active" ); this._mouseSliding = false; this._stop( event, this._handleIndex ); @@ -13041,10 +14724,12 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { 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 ); } percentMouse = ( pixelMouse / pixelTotal ); @@ -13064,88 +14749,73 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { return this._trimAlignValue( valueMouse ); }, - _start: function( event, index ) { + _uiHash: function( index, value, values ) { var uiHash = { handle: this.handles[ index ], - value: this.value() + handleIndex: index, + value: value !== undefined ? value : this.value() }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); + + if ( this._hasMultipleValues() ) { + uiHash.value = value !== undefined ? value : this.values( index ); + uiHash.values = values || this.values(); } - return this._trigger( "start", event, uiHash ); + + return uiHash; + }, + + _hasMultipleValues: function() { + return this.options.values && this.options.values.length; + }, + + _start: function( event, index ) { + return this._trigger( "start", event, this._uiHash( index ) ); }, _slide: function( event, index, newVal ) { - var otherVal, - newValues, - allowed; + var allowed, otherVal, + currentValue = this.value(), + newValues = this.values(); - if ( this.options.values && this.options.values.length ) { + if ( this._hasMultipleValues() ) { otherVal = this.values( index ? 0 : 1 ); + currentValue = this.values( index ); - 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 ) { + newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); } - if ( newVal !== this.values( index ) ) { - newValues = this.values(); - newValues[ index ] = newVal; - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal, - values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal ); - } - } + newValues[ index ] = newVal; + } + + if ( newVal === currentValue ) { + return; + } + + allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); + + // A slide can be canceled by returning false from the slide callback + if ( allowed === false ) { + return; + } + + if ( this._hasMultipleValues() ) { + this.values( index, newVal ); } else { - if ( newVal !== this.value() ) { - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); - } - } + this.value( newVal ); } }, _stop: 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(); - } - - this._trigger( "stop", event, uiHash ); + this._trigger( "stop", event, this._uiHash( index ) ); }, _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(); - } //store the last changed value index for reference when handles overlap this._lastChangedValue = index; - - this._trigger( "change", event, uiHash ); + this._trigger( "change", event, this._uiHash( index ) ); } }, @@ -13182,7 +14852,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { } this._refreshValue(); } else { - if ( this.options.values && this.options.values.length ) { + if ( this._hasMultipleValues() ) { return this._values( index ); } else { return this.value(); @@ -13211,19 +14881,17 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { valsLength = this.options.values.length; } - if ( key === "disabled" ) { - this.element.toggleClass( "ui-state-disabled", !!value ); - } - this._super( key, value ); switch ( key ) { case "orientation": this._detectOrientation(); - this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); + this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) + ._addClass( "ui-slider-" + this.orientation ); this._refreshValue(); + if ( this.options.range ) { + this._refreshRange( value ); + } // Reset positioning from previous orientation this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); @@ -13237,7 +14905,9 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { case "values": this._animateOff = true; this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { + + // Start from the last handle to prevent unreachable handles (#9046) + for ( i = valsLength - 1; i >= 0; i-- ) { this._change( null, i ); } this._animateOff = false; @@ -13258,6 +14928,12 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { } }, + _setOptionDisabled: function( value ) { + this._super( value ); + + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + //internal value getter // _value() returns value trimmed by min and max, aligned by step _value: function() { @@ -13280,11 +14956,12 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { val = this._trimAlignValue( val ); return val; - } else if ( this.options.values && this.options.values.length ) { + } else if ( this._hasMultipleValues() ) { + // .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) { + for ( i = 0; i < vals.length; i += 1 ) { vals[ i ] = this._trimAlignValue( vals[ i ] ); } @@ -13294,7 +14971,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { } }, - // returns the step-aligned value that val is closest to, between (inclusive) min and max + // 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(); @@ -13303,24 +14980,29 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { return this._valueMax(); } var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = (val - this._valueMin()) % step, + valModStep = ( val - this._valueMin() ) % step, alignValue = val - valModStep; - if ( Math.abs(valModStep) * 2 >= step ) { + 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) ); + return parseFloat( alignValue.toFixed( 5 ) ); }, _calculateNewMax: function() { var max = this.options.max, min = this._valueMin(), step = this.options.step, - aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step; + aboveMin = Math.round( ( max - min ) / step ) * step; max = aboveMin + min; + if ( max > this.options.max ) { + + //If max is not divisible by step, rounding off may increase its value + max -= step; + } this.max = parseFloat( max.toFixed( this._precision() ) ); }, @@ -13346,6 +15028,15 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { return this.max; }, + _refreshRange: function( orientation ) { + if ( orientation === "vertical" ) { + this.range.css( { "width": "", "left": "" } ); + } + if ( orientation === "horizontal" ) { + this.range.css( { "height": "", "bottom": "" } ); + } + }, + _refreshValue: function() { var lastValPercent, valPercent, value, valueMin, valueMax, oRange = this.options.range, @@ -13354,30 +15045,45 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { animate = ( !this._animateOff ) ? o.animate : false, _set = {}; - if ( this.options.values && this.options.values.length ) { - this.handles.each(function( i ) { - valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; + if ( this._hasMultipleValues() ) { + this.handles.each( function( i ) { + valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - + that._valueMin() ) * 100; _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( that.options.range === true ) { if ( that.orientation === "horizontal" ) { if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + left: valPercent + "%" + }, o.animate ); } if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + that.range[ animate ? "animate" : "css" ]( { + width: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); } } else { if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + bottom: ( valPercent ) + "%" + }, o.animate ); } if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + that.range[ animate ? "animate" : "css" ]( { + height: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); } } } lastValPercent = valPercent; - }); + } ); } else { value = this.value(); valueMin = this._valueMin(); @@ -13389,16 +15095,24 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { 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 ); + 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 } ); + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + width: ( 100 - valPercent ) + "%" + }, o.animate ); } if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); + 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 } ); + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + height: ( 100 - valPercent ) + "%" + }, o.animate ); } } }, @@ -13420,7 +15134,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { event.preventDefault(); if ( !this._keySliding ) { this._keySliding = true; - $( event.target ).addClass( "ui-state-active" ); + this._addClass( $( event.target ), null, "ui-state-active" ); allowed = this._start( event, index ); if ( allowed === false ) { return; @@ -13430,7 +15144,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { } step = this.options.step; - if ( this.options.values && this.options.values.length ) { + if ( this._hasMultipleValues() ) { curVal = newVal = this.values( index ); } else { curVal = newVal = this.value(); @@ -13450,7 +15164,7 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { break; case $.ui.keyCode.PAGE_DOWN: newVal = this._trimAlignValue( - curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); + curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: @@ -13477,27 +15191,33 @@ var slider = $.widget( "ui.slider", $.ui.mouse, { this._keySliding = false; this._stop( event, index ); this._change( event, index ); - $( event.target ).removeClass( "ui-state-active" ); + this._removeClass( $( event.target ), null, "ui-state-active" ); } } } -}); +} ); /*! - * jQuery UI Sortable 1.11.4 + * jQuery UI Sortable 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/sortable/ */ +//>>label: Sortable +//>>group: Interactions +//>>description: Enables items in a list to be sorted using the mouse. +//>>docs: http://api.jqueryui.com/sortable/ +//>>demos: http://jqueryui.com/sortable/ +//>>css.structure: ../../themes/base/sortable.css + -var sortable = $.widget("ui.sortable", $.ui.mouse, { - version: "1.11.4", + +var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { + version: "1.12.1", widgetEventPrefix: "sort", ready: false, options: { @@ -13524,7 +15244,7 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { tolerance: "intersect", zIndex: 1000, - // callbacks + // Callbacks activate: null, beforeStop: null, change: null, @@ -13544,12 +15264,13 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }, _isFloating: function( item ) { - return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); + return ( /left|right/ ).test( item.css( "float" ) ) || + ( /inline|table-cell/ ).test( item.css( "display" ) ); }, _create: function() { this.containerCache = {}; - this.element.addClass("ui-sortable"); + this._addClass( "ui-sortable" ); //Get the items this.refresh(); @@ -13576,65 +15297,65 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }, _setHandleClassName: function() { - this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" ); + var that = this; + this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); $.each( this.items, function() { - ( this.instance.options.handle ? - this.item.find( this.instance.options.handle ) : this.item ) - .addClass( "ui-sortable-handle" ); - }); + that._addClass( + this.instance.options.handle ? + this.item.find( this.instance.options.handle ) : + this.item, + "ui-sortable-handle" + ); + } ); }, _destroy: function() { - this.element - .removeClass( "ui-sortable ui-sortable-disabled" ) - .find( ".ui-sortable-handle" ) - .removeClass( "ui-sortable-handle" ); this._mouseDestroy(); for ( var i = this.items.length - 1; i >= 0; i-- ) { - this.items[i].item.removeData(this.widgetName + "-item"); + this.items[ i ].item.removeData( this.widgetName + "-item" ); } return this; }, - _mouseCapture: function(event, overrideHandle) { + _mouseCapture: function( event, overrideHandle ) { var currentItem = null, validHandle = false, that = this; - if (this.reverting) { + if ( this.reverting ) { return false; } - if(this.options.disabled || this.options.type === "static") { + if ( this.options.disabled || this.options.type === "static" ) { return false; } //We have to refresh the items data once first - this._refreshItems(event); + this._refreshItems( event ); //Find out if the clicked node (or one of its parents) is a actual item in this.items - $(event.target).parents().each(function() { - if($.data(this, that.widgetName + "-item") === that) { - currentItem = $(this); + $( event.target ).parents().each( function() { + if ( $.data( this, that.widgetName + "-item" ) === that ) { + currentItem = $( this ); return false; } - }); - if($.data(event.target, that.widgetName + "-item") === that) { - currentItem = $(event.target); + } ); + if ( $.data( event.target, that.widgetName + "-item" ) === that ) { + currentItem = $( event.target ); } - if(!currentItem) { + if ( !currentItem ) { return false; } - if(this.options.handle && !overrideHandle) { - $(this.options.handle, currentItem).find("*").addBack().each(function() { - if(this === event.target) { + if ( this.options.handle && !overrideHandle ) { + $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { + if ( this === event.target ) { validHandle = true; } - }); - if(!validHandle) { + } ); + if ( !validHandle ) { return false; } } @@ -13645,18 +15366,19 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }, - _mouseStart: function(event, overrideHandle, noActivation) { + _mouseStart: function( event, overrideHandle, noActivation ) { var i, body, o = this.options; this.currentContainer = this; - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + //We only need to call refreshPositions, because the refreshItems call has been moved to + // mouseCapture this.refreshPositions(); //Create and append the visible helper - this.helper = this._createHelper(event); + this.helper = this._createHelper( event ); //Cache the helper size this._cacheHelperProportions(); @@ -13679,33 +15401,40 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { left: this.offset.left - this.margins.left }; - $.extend(this.offset, { + $.extend( this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); + + // This is a relative to absolute position minus the actual position calculation - + // only used for relative positioned helper + relative: this._getRelativeOffset() + } ); // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); + this.helper.css( "position", "absolute" ); + this.cssPosition = this.helper.css( "position" ); //Generate the original position - this.originalPosition = this._generatePosition(event); + this.originalPosition = this._generatePosition( event ); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (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] }; + this.domPosition = { + prev: this.currentItem.prev()[ 0 ], + parent: this.currentItem.parent()[ 0 ] + }; - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way - if(this.helper[0] !== this.currentItem[0]) { + // If the helper is not the original, hide the original so it's not playing any role during + // the drag, won't cause anything bad this way + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { this.currentItem.hide(); } @@ -13713,141 +15442,158 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { this._createPlaceholder(); //Set a containment if given in the options - if(o.containment) { + if ( o.containment ) { this._setContainment(); } - if( o.cursor && o.cursor !== "auto" ) { // cursor option + if ( o.cursor && o.cursor !== "auto" ) { // cursor option body = this.document.find( "body" ); - // support: IE + // Support: IE this.storedCursor = body.css( "cursor" ); body.css( "cursor", o.cursor ); - this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); + this.storedStylesheet = + $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); } - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) { - this._storedOpacity = this.helper.css("opacity"); + if ( o.opacity ) { // opacity option + if ( this.helper.css( "opacity" ) ) { + this._storedOpacity = this.helper.css( "opacity" ); } - this.helper.css("opacity", o.opacity); + this.helper.css( "opacity", o.opacity ); } - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) { - this._storedZIndex = this.helper.css("zIndex"); + if ( o.zIndex ) { // zIndex option + if ( this.helper.css( "zIndex" ) ) { + this._storedZIndex = this.helper.css( "zIndex" ); } - this.helper.css("zIndex", o.zIndex); + this.helper.css( "zIndex", o.zIndex ); } //Prepare scrolling - if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { this.overflowOffset = this.scrollParent.offset(); } //Call callbacks - this._trigger("start", event, this._uiHash()); + this._trigger( "start", event, this._uiHash() ); //Recache the helper size - if(!this._preserveHelperProportions) { + if ( !this._preserveHelperProportions ) { this._cacheHelperProportions(); } - //Post "activate" events to possible containers - if( !noActivation ) { + if ( !noActivation ) { for ( i = this.containers.length - 1; i >= 0; i-- ) { this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); } } //Prepare possible droppables - if($.ui.ddmanager) { + if ( $.ui.ddmanager ) { $.ui.ddmanager.current = this; } - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); } this.dragging = true; - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + this._addClass( this.helper, "ui-sortable-helper" ); + + // Execute the drag once - this causes the helper not to be visiblebefore getting its + // correct position + this._mouseDrag( event ); return true; }, - _mouseDrag: function(event) { + _mouseDrag: function( event ) { var i, item, itemElement, intersection, o = this.options, scrolled = false; //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); + this.position = this._generatePosition( event ); + this.positionAbs = this._convertPositionTo( "absolute" ); - if (!this.lastPositionAbs) { + if ( !this.lastPositionAbs ) { this.lastPositionAbs = this.positionAbs; } //Do scrolling - if(this.options.scroll) { - if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; + if ( this.options.scroll ) { + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + + if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - + event.pageY < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; + } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; } - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; + if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - + event.pageX < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; + } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; } } else { - if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) { - scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); - } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) { - scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); + if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); + } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); } - if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { - scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed); - } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) { - scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed); + if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() - o.scrollSpeed + ); + } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() + o.scrollSpeed + ); } } - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); + if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); } } //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); + this.positionAbs = this._convertPositionTo( "absolute" ); //Set the helper position - if(!this.options.axis || this.options.axis !== "y") { - this.helper[0].style.left = this.position.left+"px"; + if ( !this.options.axis || this.options.axis !== "y" ) { + this.helper[ 0 ].style.left = this.position.left + "px"; } - if(!this.options.axis || this.options.axis !== "x") { - this.helper[0].style.top = this.position.top+"px"; + if ( !this.options.axis || this.options.axis !== "x" ) { + this.helper[ 0 ].style.top = this.position.top + "px"; } //Rearrange - for (i = this.items.length - 1; i >= 0; i--) { + for ( i = this.items.length - 1; i >= 0; i-- ) { //Cache variables and intersection, continue if no intersection - item = this.items[i]; - itemElement = item.item[0]; - intersection = this._intersectsWithPointer(item); - if (!intersection) { + item = this.items[ i ]; + itemElement = item.item[ 0 ]; + intersection = this._intersectsWithPointer( item ); + if ( !intersection ) { continue; } @@ -13858,77 +15604,92 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { // // Without this, moving items in "sub-sortables" can cause // the placeholder to jitter between the outer and inner container. - if (item.instance !== this.currentContainer) { + if ( item.instance !== this.currentContainer ) { continue; } - // cannot intersect with itself + // Cannot intersect with itself // no useless actions that have been done before // no action if the item moved is the parent of the item checked - if (itemElement !== this.currentItem[0] && - this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && - !$.contains(this.placeholder[0], itemElement) && - (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) + if ( itemElement !== this.currentItem[ 0 ] && + this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement && + !$.contains( this.placeholder[ 0 ], itemElement ) && + ( this.options.type === "semi-dynamic" ? + !$.contains( this.element[ 0 ], itemElement ) : + true + ) ) { this.direction = intersection === 1 ? "down" : "up"; - if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); + if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) { + this._rearrange( event, item ); } else { break; } - this._trigger("change", event, this._uiHash()); + this._trigger( "change", event, this._uiHash() ); break; } } //Post events to containers - this._contactContainers(event); + this._contactContainers( event ); //Interconnect with droppables - if($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); } //Call callbacks - this._trigger("sort", event, this._uiHash()); + this._trigger( "sort", event, this._uiHash() ); this.lastPositionAbs = this.positionAbs; return false; }, - _mouseStop: function(event, noPropagation) { + _mouseStop: function( event, noPropagation ) { - if(!event) { + if ( !event ) { return; } //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) { - $.ui.ddmanager.drop(this, event); + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + $.ui.ddmanager.drop( this, event ); } - if(this.options.revert) { + if ( this.options.revert ) { var that = this, cur = this.placeholder.offset(), axis = this.options.axis, animation = {}; if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft); + animation.left = cur.left - this.offset.parent.left - this.margins.left + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollLeft + ); } if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop); + animation.top = cur.top - this.offset.parent.top - this.margins.top + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollTop + ); } this.reverting = true; - $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { - that._clear(event); - }); + $( this.helper ).animate( + animation, + parseInt( this.options.revert, 10 ) || 500, + function() { + that._clear( event ); + } + ); } else { - this._clear(event, noPropagation); + this._clear( event, noPropagation ); } return false; @@ -13937,47 +15698,51 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { cancel: function() { - if(this.dragging) { + if ( this.dragging ) { - this._mouseUp({ target: null }); + this._mouseUp( new $.Event( "mouseup", { target: null } ) ); - if(this.options.helper === "original") { - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + if ( this.options.helper === "original" ) { + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); } else { this.currentItem.show(); } //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, this._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, this._uiHash(this)); - this.containers[i].containerCache.over = 0; + for ( var i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); + if ( this.containers[ i ].containerCache.over ) { + this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); + this.containers[ i ].containerCache.over = 0; } } } - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) { - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + if ( this.placeholder ) { + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + if ( this.placeholder[ 0 ].parentNode ) { + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); } - if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { + if ( this.options.helper !== "original" && this.helper && + this.helper[ 0 ].parentNode ) { this.helper.remove(); } - $.extend(this, { + $.extend( this, { helper: null, dragging: false, reverting: false, _noFinalSort: null - }); + } ); - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); + if ( this.domPosition.prev ) { + $( this.domPosition.prev ).after( this.currentItem ); } else { - $(this.domPosition.parent).prepend(this.currentItem); + $( this.domPosition.parent ).prepend( this.currentItem ); } } @@ -13985,41 +15750,46 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }, - serialize: function(o) { + serialize: function( o ) { - var items = this._getItemsAsjQuery(o && o.connected), + var items = this._getItemsAsjQuery( o && o.connected ), str = []; o = o || {}; - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); - if (res) { - str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); + $( items ).each( function() { + var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) + .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); + if ( res ) { + str.push( + ( o.key || res[ 1 ] + "[]" ) + + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); } - }); + } ); - if(!str.length && o.key) { - str.push(o.key + "="); + if ( !str.length && o.key ) { + str.push( o.key + "=" ); } - return str.join("&"); + return str.join( "&" ); }, - toArray: function(o) { + toArray: function( o ) { - var items = this._getItemsAsjQuery(o && o.connected), + var items = this._getItemsAsjQuery( o && o.connected ), ret = []; o = o || {}; - items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); + items.each( function() { + ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); + } ); return ret; }, /* Be careful with the following core functions */ - _intersectsWith: function(item) { + _intersectsWith: function( item ) { var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width, @@ -14031,70 +15801,83 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { b = t + item.height, dyClick = this.offset.click.top, dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), + isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && + ( y1 + dyClick ) < b ), + isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && + ( x1 + dxClick ) < r ), isOverElement = isOverElementHeight && isOverElementWidth; if ( this.options.tolerance === "pointer" || this.options.forcePointerForContainers || - (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) + ( this.options.tolerance !== "pointer" && + this.helperProportions[ this.floating ? "width" : "height" ] > + item[ this.floating ? "width" : "height" ] ) ) { return isOverElement; } else { - return (l < x1 + (this.helperProportions.width / 2) && // Right Half - x2 - (this.helperProportions.width / 2) < r && // Left Half - t < y1 + (this.helperProportions.height / 2) && // Bottom Half - y2 - (this.helperProportions.height / 2) < b ); // Top Half + return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half + x2 - ( this.helperProportions.width / 2 ) < r && // Left Half + t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half + y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half } }, - _intersectsWithPointer: function(item) { - - var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); + _intersectsWithPointer: function( item ) { + var verticalDirection, horizontalDirection, + isOverElementHeight = ( this.options.axis === "x" ) || + this._isOverAxis( + this.positionAbs.top + this.offset.click.top, item.top, item.height ), + isOverElementWidth = ( this.options.axis === "y" ) || + this._isOverAxis( + this.positionAbs.left + this.offset.click.left, item.left, item.width ), + isOverElement = isOverElementHeight && isOverElementWidth; - if (!isOverElement) { + if ( !isOverElement ) { return false; } + verticalDirection = this._getDragVerticalDirection(); + horizontalDirection = this._getDragHorizontalDirection(); + return this.floating ? - ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); + ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) + : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); }, - _intersectsWithSides: function(item) { + _intersectsWithSides: function( item ) { - var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), + isOverRightHalf = this._isOverAxis( this.positionAbs.left + + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); - if (this.floating && horizontalDirection) { - return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); + if ( this.floating && horizontalDirection ) { + return ( ( horizontalDirection === "right" && isOverRightHalf ) || + ( horizontalDirection === "left" && !isOverRightHalf ) ); } else { - return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); + return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || + ( verticalDirection === "up" && !isOverBottomHalf ) ); } }, _getDragVerticalDirection: function() { var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && (delta > 0 ? "down" : "up"); + return delta !== 0 && ( delta > 0 ? "down" : "up" ); }, _getDragHorizontalDirection: function() { var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && (delta > 0 ? "right" : "left"); + return delta !== 0 && ( delta > 0 ? "right" : "left" ); }, - refresh: function(event) { - this._refreshItems(event); + refresh: function( event ) { + this._refreshItems( event ); this._setHandleClassName(); this.refreshPositions(); return this; @@ -14102,124 +15885,146 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { _connectWith: function() { var options = this.options; - return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; + return options.connectWith.constructor === String ? + [ options.connectWith ] : + options.connectWith; }, - _getItemsAsjQuery: function(connected) { + _getItemsAsjQuery: function( connected ) { var i, j, cur, inst, items = [], queries = [], connectWith = this._connectWith(); - if(connectWith && connected) { - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i], this.document[0]); - for ( j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - 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").not(".ui-sortable-placeholder"), inst]); + if ( connectWith && connected ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + 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" ) + .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").not(".ui-sortable-placeholder"), 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 ] ); function addItems() { items.push( this ); } - for (i = queries.length - 1; i >= 0; i--){ - queries[i][0].each( addItems ); + for ( i = queries.length - 1; i >= 0; i-- ) { + queries[ i ][ 0 ].each( addItems ); } - return $(items); + return $( items ); }, _removeCurrentsFromItems: function() { - var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); + var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); - this.items = $.grep(this.items, function (item) { - for (var j=0; j < list.length; j++) { - if(list[j] === item.item[0]) { + this.items = $.grep( this.items, function( item ) { + for ( var j = 0; j < list.length; j++ ) { + if ( list[ j ] === item.item[ 0 ] ) { return false; } } return true; - }); + } ); }, - _refreshItems: function(event) { + _refreshItems: function( event ) { this.items = []; - this.containers = [this]; + this.containers = [ this ]; var i, j, cur, inst, targetData, _queries, item, queriesLength, items = this.items, - queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], + queries = [ [ $.isFunction( this.options.items ) ? + this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : + $( this.options.items, this.element ), this ] ], connectWith = this._connectWith(); - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (i = connectWith.length - 1; i >= 0; i--){ - cur = $(connectWith[i], this.document[0]); - for (j = cur.length - 1; j >= 0; j--){ - inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); + //Shouldn't be run the first time through due to massive slow-down + if ( connectWith && this.ready ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + if ( inst && inst !== this && !inst.options.disabled ) { + queries.push( [ $.isFunction( inst.options.items ) ? + inst.options.items + .call( inst.element[ 0 ], event, { item: this.currentItem } ) : + $( inst.options.items, inst.element ), inst ] ); + this.containers.push( inst ); } } } } - for (i = queries.length - 1; i >= 0; i--) { - targetData = queries[i][1]; - _queries = queries[i][0]; + for ( i = queries.length - 1; i >= 0; i-- ) { + targetData = queries[ i ][ 1 ]; + _queries = queries[ i ][ 0 ]; - for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { - item = $(_queries[j]); + for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { + item = $( _queries[ j ] ); - item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) + // Data for target checking (mouse manager) + item.data( this.widgetName + "-item", targetData ); - items.push({ + items.push( { item: item, instance: targetData, width: 0, height: 0, left: 0, top: 0 - }); + } ); } } }, - refreshPositions: function(fast) { + refreshPositions: function( fast ) { // Determine whether items are being displayed horizontally this.floating = this.items.length ? this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : false; - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { + //This has to be redone because due to the item being moved out/into the offsetParent, + // the offsetParent's position will change + if ( this.offsetParent && this.helper ) { this.offset.parent = this._getParentOffset(); } var i, item, t, p; - for (i = this.items.length - 1; i >= 0; i--){ - item = this.items[i]; + for ( i = this.items.length - 1; i >= 0; i-- ) { + 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]) { + if ( item.instance !== this.currentContainer && this.currentContainer && + item.item[ 0 ] !== this.currentItem[ 0 ] ) { continue; } - t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; + t = this.options.toleranceElement ? + $( this.options.toleranceElement, item.item ) : + item.item; - if (!fast) { + if ( !fast ) { item.width = t.outerWidth(); item.height = t.outerHeight(); } @@ -14229,35 +16034,39 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { item.top = p.top; } - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); + if ( this.options.custom && this.options.custom.refreshContainers ) { + this.options.custom.refreshContainers.call( this ); } else { - for (i = this.containers.length - 1; i >= 0; i--){ - p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); + for ( i = this.containers.length - 1; i >= 0; i-- ) { + p = this.containers[ i ].element.offset(); + this.containers[ i ].containerCache.left = p.left; + this.containers[ i ].containerCache.top = p.top; + this.containers[ i ].containerCache.width = + this.containers[ i ].element.outerWidth(); + this.containers[ i ].containerCache.height = + this.containers[ i ].element.outerHeight(); } } return this; }, - _createPlaceholder: function(that) { + _createPlaceholder: function( that ) { that = that || this; var className, o = that.options; - if(!o.placeholder || o.placeholder.constructor === String) { + if ( !o.placeholder || o.placeholder.constructor === String ) { className = o.placeholder; o.placeholder = { element: function() { - var nodeName = that.currentItem[0].nodeName.toLowerCase(), - element = $( "<" + nodeName + ">", that.document[0] ) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper"); + var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(), + element = $( "<" + nodeName + ">", that.document[ 0 ] ); + + that._addClass( element, "ui-sortable-placeholder", + className || that.currentItem[ 0 ].className ) + ._removeClass( element, "ui-sortable-helper" ); if ( nodeName === "tbody" ) { that._createTrPlaceholder( @@ -14276,105 +16085,126 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { return element; }, - update: function(container, p) { + update: function( container, p ) { - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) { + // 1. If a className is set as 'placeholder option, we don't force sizes - + // the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a + // class name is specified + if ( className && !o.forcePlaceholderSize ) { return; } - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } - if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } + //If the element doesn't have a actual height by itself (without styles coming + // from a stylesheet), it receives the inline height from the dragged item + if ( !p.height() ) { + p.height( + that.currentItem.innerHeight() - + parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); + } + if ( !p.width() ) { + p.width( + that.currentItem.innerWidth() - + parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); + } } }; } //Create the placeholder - that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); + that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); //Append it after the actual current item - that.currentItem.after(that.placeholder); + that.currentItem.after( that.placeholder ); //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(that, that.placeholder); + o.placeholder.update( that, that.placeholder ); }, _createTrPlaceholder: function( sourceTr, targetTr ) { var that = this; - sourceTr.children().each(function() { + sourceTr.children().each( function() { $( "<td> </td>", that.document[ 0 ] ) .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) .appendTo( targetTr ); - }); + } ); }, - _contactContainers: function(event) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, + _contactContainers: function( event ) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, + floating, axis, innermostContainer = null, innermostIndex = null; - // get innermost container that intersects with item - for (i = this.containers.length - 1; i >= 0; i--) { + // Get innermost container that intersects with item + for ( i = this.containers.length - 1; i >= 0; i-- ) { - // never consider a container that's located within the item itself - if($.contains(this.currentItem[0], this.containers[i].element[0])) { + // Never consider a container that's located within the item itself + if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { continue; } - if(this._intersectsWith(this.containers[i].containerCache)) { + 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 && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { + // If we've already found a container and it's more "inner" than this, then continue + if ( innermostContainer && + $.contains( + this.containers[ i ].element[ 0 ], + innermostContainer.element[ 0 ] ) ) { continue; } - innermostContainer = this.containers[i]; + 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 ( 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) { + // 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) { - if (!this.containers[innermostIndex].containerCache.over) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; + // Move the item into the container if it's not there already + if ( this.containers.length === 1 ) { + if ( !this.containers[ innermostIndex ].containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; } } else { - //When entering a new container, we will find the item with the least distance and append our item near it + // When entering a new container, we will find the item with the least distance and + // append our item near it dist = 10000; itemWithLeastDistance = null; - floating = innermostContainer.floating || this._isFloating(this.currentItem); + floating = innermostContainer.floating || this._isFloating( this.currentItem ); posProperty = floating ? "left" : "top"; sizeProperty = floating ? "width" : "height"; - axis = floating ? "clientX" : "clientY"; + axis = floating ? "pageX" : "pageY"; - for (j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { + for ( j = this.items.length - 1; j >= 0; j-- ) { + if ( !$.contains( + this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) + ) { continue; } - if(this.items[j].item[0] === this.currentItem[0]) { + if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { continue; } - cur = this.items[j].item.offset()[posProperty]; + cur = this.items[ j ].item.offset()[ posProperty ]; nearBottom = false; if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { nearBottom = true; @@ -14383,16 +16213,16 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { if ( Math.abs( event[ axis ] - cur ) < dist ) { dist = Math.abs( event[ axis ] - cur ); itemWithLeastDistance = this.items[ j ]; - this.direction = nearBottom ? "up": "down"; + this.direction = nearBottom ? "up" : "down"; } } //Check if dropOnEmpty is enabled - if(!itemWithLeastDistance && !this.options.dropOnEmpty) { + if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { return; } - if(this.currentContainer === this.containers[innermostIndex]) { + if ( this.currentContainer === this.containers[ innermostIndex ] ) { if ( !this.currentContainer.containerCache.over ) { this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); this.currentContainer.containerCache.over = 1; @@ -14400,103 +16230,121 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { return; } - 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)); - 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 ) ); + this.currentContainer = this.containers[ innermostIndex ]; //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); + this.options.placeholder.update( this.currentContainer, this.placeholder ); - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; } - }, - _createHelper: function(event) { + _createHelper: function( event ) { var o = this.options, - helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); + helper = $.isFunction( o.helper ) ? + $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : + ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); //Add the helper to the DOM if that didn't happen already - if(!helper.parents("body").length) { - $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - } - - if(helper[0] === this.currentItem[0]) { - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; + if ( !helper.parents( "body" ).length ) { + $( o.appendTo !== "parent" ? + o.appendTo : + this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); + } + + if ( helper[ 0 ] === this.currentItem[ 0 ] ) { + this._storedCSS = { + width: this.currentItem[ 0 ].style.width, + height: this.currentItem[ 0 ].style.height, + position: this.currentItem.css( "position" ), + top: this.currentItem.css( "top" ), + left: this.currentItem.css( "left" ) + }; } - if(!helper[0].style.width || o.forceHelperSize) { - helper.width(this.currentItem.width()); + if ( !helper[ 0 ].style.width || o.forceHelperSize ) { + helper.width( this.currentItem.width() ); } - if(!helper[0].style.height || o.forceHelperSize) { - helper.height(this.currentItem.height()); + if ( !helper[ 0 ].style.height || o.forceHelperSize ) { + helper.height( this.currentItem.height() ); } return helper; }, - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; + if ( $.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; } - if ("left" in obj) { + if ( "left" in obj ) { this.offset.click.left = obj.left + this.margins.left; } - if ("right" in obj) { + if ( "right" in obj ) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } - if ("top" in obj) { + if ( "top" in obj ) { this.offset.click.top = obj.top + this.margins.top; } - if ("bottom" in obj) { + if ( "bottom" in obj ) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, _getParentOffset: function() { - //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) { + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } - // This needs to be actually done for all browsers, since pageX/pageY includes this information - // with an ugly IE fix - if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { + // This needs to be actually done for all browsers, since pageX/pageY includes this + // information with an ugly IE fix + if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || + ( this.offsetParent[ 0 ].tagName && + this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { po = { top: 0, left: 0 }; } return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) }; }, _getRelativeOffset: function() { - if(this.cssPosition === "relative") { + if ( this.cssPosition === "relative" ) { var p = this.currentItem.position(); return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + this.scrollParent.scrollTop(), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; @@ -14506,8 +16354,8 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { _cacheMargins: function() { this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) + left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) }; }, @@ -14522,72 +16370,111 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { var ce, co, over, o = this.options; - if(o.containment === "parent") { - o.containment = this.helper[0].parentNode; + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; } - if(o.containment === "document" || o.containment === "window") { + if ( o.containment === "document" || o.containment === "window" ) { this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, - o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, - (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + o.containment === "document" ? + this.document.width() : + this.window.width() - this.helperProportions.width - this.margins.left, + ( o.containment === "document" ? + ( this.document.height() || document.body.parentNode.scrollHeight ) : + this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight + ) - this.helperProportions.height - this.margins.top ]; } - if(!(/^(document|window|parent)$/).test(o.containment)) { - ce = $(o.containment)[0]; - co = $(o.containment).offset(); - over = ($(ce).css("overflow") !== "hidden"); + if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { + ce = $( o.containment )[ 0 ]; + co = $( o.containment ).offset(); + over = ( $( ce ).css( "overflow" ) !== "hidden" ); this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top + co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, + co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, + co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - this.margins.left, + co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - this.margins.top ]; } }, - _convertPositionTo: function(d, pos) { + _convertPositionTo: function( d, pos ) { - if(!pos) { + if ( !pos ) { pos = this.position; } var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, - scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); return { top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + + // The absolute mouse position + pos.top + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) ), left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + + // The absolute mouse position + pos.left + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : + scroll.scrollLeft() ) * mod ) ) }; }, - _generatePosition: function(event) { + _generatePosition: function( event ) { var top, left, o = this.options, pageX = event.pageX, pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.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] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) { + if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { this.offset.relative = this._getRelativeOffset(); } @@ -14596,129 +16483,189 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { * Constrain the position to a mix of grid, containment. */ - if(this.originalPosition) { //If we are not dragging yet, we won't check for options + if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) { - pageX = this.containment[0] + this.offset.click.left; + if ( this.containment ) { + if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { + pageX = this.containment[ 0 ] + this.offset.click.left; } - if(event.pageY - this.offset.click.top < this.containment[1]) { - pageY = this.containment[1] + this.offset.click.top; + if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { + pageY = this.containment[ 1 ] + this.offset.click.top; } - if(event.pageX - this.offset.click.left > this.containment[2]) { - pageX = this.containment[2] + this.offset.click.left; + if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { + pageX = this.containment[ 2 ] + this.offset.click.left; } - if(event.pageY - this.offset.click.top > this.containment[3]) { - pageY = this.containment[3] + this.offset.click.top; + if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { + pageY = this.containment[ 3 ] + this.offset.click.top; } } - if(o.grid) { - top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + if ( o.grid ) { + top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / + o.grid[ 1 ] ) * o.grid[ 1 ]; + pageY = this.containment ? + ( ( top - this.offset.click.top >= this.containment[ 1 ] && + top - this.offset.click.top <= this.containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : + top; - left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / + o.grid[ 0 ] ) * o.grid[ 0 ]; + pageX = this.containment ? + ( ( left - this.offset.click.left >= this.containment[ 0 ] && + left - this.offset.click.left <= this.containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : + left; } } return { top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + + // The absolute mouse position + pageY - + + // Click offset (relative to the element) + this.offset.click.top - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) ), left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + + // The absolute mouse position + pageX - + + // Click offset (relative to the element) + this.offset.click.left - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : + scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) ) }; }, - _rearrange: function(event, i, a, hardRefresh) { + _rearrange: function( event, i, a, hardRefresh ) { - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); + a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : + i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], + ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); //Various things done here to improve the performance: // 1. we create a setTimeout, that calls refreshPositions // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same + // 3. on the local scope, we copy the counter variable, and check in the timeout, + // if it's still the same // 4. this lets only the last addition to the timeout stack through this.counter = this.counter ? ++this.counter : 1; var counter = this.counter; - this._delay(function() { - if(counter === this.counter) { - this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + this._delay( function() { + if ( counter === this.counter ) { + + //Precompute after each DOM insertion, NOT on mousemove + this.refreshPositions( !hardRefresh ); } - }); + } ); }, - _clear: function(event, noPropagation) { + _clear: function( event, noPropagation ) { this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again + + // We delay all events that have to be triggered to after the point where the placeholder + // has been removed and everything else normalized again var i, delayedTriggers = []; // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) { - this.placeholder.before(this.currentItem); + // Note: don't do it if the current item is already removed (by a user), or it gets + // reappended (see #4088) + if ( !this._noFinalSort && this.currentItem.parent().length ) { + this.placeholder.before( this.currentItem ); } this._noFinalSort = null; - if(this.helper[0] === this.currentItem[0]) { - for(i in this._storedCSS) { - if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { - this._storedCSS[i] = ""; + if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { + for ( i in this._storedCSS ) { + if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { + this._storedCSS[ i ] = ""; } } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); } else { this.currentItem.show(); } - if(this.fromOutside && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); + if ( this.fromOutside && !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); + } ); } - if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + if ( ( this.fromOutside || + this.domPosition.prev !== + this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || + this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { + + // Trigger update callback if the DOM position has changed + delayedTriggers.push( function( event ) { + this._trigger( "update", event, this._uiHash() ); + } ); } // Check if the items Container has Changed and trigger appropriate // events. - if (this !== this.currentContainer) { - if(!noPropagation) { - delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + if ( this !== this.currentContainer ) { + if ( !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "remove", event, this._uiHash() ); + } ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "receive", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "update", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); } } - //Post events to containers function delayEvent( type, instance, container ) { return function( event ) { container._trigger( type, event, instance._uiHash( instance ) ); }; } - for (i = this.containers.length - 1; i >= 0; i--){ - if (!noPropagation) { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + if ( !noPropagation ) { delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); } - if(this.containers[i].containerCache.over) { + if ( this.containers[ i ].containerCache.over ) { delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); - this.containers[i].containerCache.over = 0; + this.containers[ i ].containerCache.over = 0; } } @@ -14727,21 +16674,22 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { this.document.find( "body" ).css( "cursor", this.storedCursor ); this.storedStylesheet.remove(); } - if(this._storedOpacity) { - this.helper.css("opacity", this._storedOpacity); + if ( this._storedOpacity ) { + this.helper.css( "opacity", this._storedOpacity ); } - if(this._storedZIndex) { - this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); + if ( this._storedZIndex ) { + this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); } this.dragging = false; - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); + if ( !noPropagation ) { + this._trigger( "beforeStop", event, this._uiHash() ); } - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); if ( !this.cancelHelperRemoval ) { if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { @@ -14750,11 +16698,13 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { this.helper = null; } - if(!noPropagation) { - for (i=0; i < delayedTriggers.length; i++) { - delayedTriggers[i].call(this, event); - } //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); + if ( !noPropagation ) { + for ( i = 0; i < delayedTriggers.length; i++ ) { + + // Trigger all delayed events + delayedTriggers[ i ].call( this, event ); + } + this._trigger( "stop", event, this._uiHash() ); } this.fromOutside = false; @@ -14763,16 +16713,16 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }, _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { + if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { this.cancel(); } }, - _uiHash: function(_inst) { + _uiHash: function( _inst ) { var inst = _inst || this; return { helper: inst.helper, - placeholder: inst.placeholder || $([]), + placeholder: inst.placeholder || $( [] ), position: inst.position, originalPosition: inst.originalPosition, offset: inst.positionAbs, @@ -14781,22 +16731,30 @@ var sortable = $.widget("ui.sortable", $.ui.mouse, { }; } -}); +} ); /*! - * jQuery UI Spinner 1.11.4 + * jQuery UI Spinner 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/spinner/ */ +//>>label: Spinner +//>>group: Widgets +//>>description: Displays buttons to easily input numbers via the keyboard or mouse. +//>>docs: http://api.jqueryui.com/spinner/ +//>>demos: http://jqueryui.com/spinner/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/spinner.css +//>>css.theme: ../../themes/base/theme.css + -function spinner_modifier( fn ) { + +function spinnerModifer( fn ) { return function() { var previous = this.element.val(); fn.apply( this, arguments ); @@ -14807,11 +16765,16 @@ function spinner_modifier( fn ) { }; } -var spinner = $.widget( "ui.spinner", { - version: "1.11.4", +$.widget( "ui.spinner", { + version: "1.12.1", defaultElement: "<input>", widgetEventPrefix: "spin", options: { + classes: { + "ui-spinner": "ui-corner-all", + "ui-spinner-down": "ui-corner-br", + "ui-spinner-up": "ui-corner-tr" + }, culture: null, icons: { down: "ui-icon-triangle-1-s", @@ -14831,6 +16794,7 @@ var spinner = $.widget( "ui.spinner", { }, _create: function() { + // handle string values that need to be parsed this._setOption( "max", this.options.max ); this._setOption( "min", this.options.min ); @@ -14839,6 +16803,7 @@ var spinner = $.widget( "ui.spinner", { // Only format if there is a value, prevents the field from being marked // as invalid in Firefox, see #9573. if ( this.value() !== "" ) { + // Format the value, but don't constrain. this._value( this.element.val(), true ); } @@ -14847,26 +16812,26 @@ var spinner = $.widget( "ui.spinner", { this._on( this._events ); this._refresh(); - // turning off autocomplete prevents the browser from remembering the + // Turning off autocomplete prevents the browser from remembering the // value when navigating through history, so we re-enable autocomplete // if the page is unloaded before the widget is destroyed. #7790 this._on( this.window, { beforeunload: function() { this.element.removeAttr( "autocomplete" ); } - }); + } ); }, _getCreateOptions: function() { - var options = {}, - element = this.element; + var options = this._super(); + var element = this.element; $.each( [ "min", "max", "step" ], function( i, option ) { var value = element.attr( option ); - if ( value !== undefined && value.length ) { + if ( value != null && value.length ) { options[ option ] = value; } - }); + } ); return options; }, @@ -14901,9 +16866,9 @@ var spinner = $.widget( "ui.spinner", { return false; } - this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); + this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay(function() { + this.mousewheelTimer = this._delay( function() { if ( this.spinning ) { this._stop( event ); } @@ -14918,44 +16883,47 @@ var spinner = $.widget( "ui.spinner", { // If the input is focused then this.previous is properly set from // when the input first received focus. If the input is not focused // then we need to set this.previous based on the value before spinning. - previous = this.element[0] === this.document[0].activeElement ? + previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? this.previous : this.element.val(); function checkFocus() { - var isActive = this.element[0] === this.document[0].activeElement; + var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); if ( !isActive ) { - this.element.focus(); + this.element.trigger( "focus" ); this.previous = previous; + // support: IE // IE sets focus asynchronously, so we need to check if focus // moved off of the input because the user clicked on the button. - this._delay(function() { + this._delay( function() { this.previous = previous; - }); + } ); } } - // ensure focus is on (or stays on) the text field + // Ensure focus is on (or stays on) the text field event.preventDefault(); checkFocus.call( this ); - // support: IE + // Support: IE // IE doesn't prevent moving focus even with event.preventDefault() // so we set a flag to know when we should ignore the blur event // and check (again) if focus moved off of the input. this.cancelBlur = true; - this._delay(function() { + this._delay( function() { delete this.cancelBlur; checkFocus.call( this ); - }); + } ); if ( this._start( event ) === false ) { return; } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }, "mouseup .ui-spinner-button": "_stop", "mouseenter .ui-spinner-button": function( event ) { + // button will add ui-state-active if mouse was down while mouseleave and kept down if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { return; @@ -14964,41 +16932,66 @@ var spinner = $.widget( "ui.spinner", { if ( this._start( event ) === false ) { return false; } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }, + // TODO: do we really want to consider this a stop? // shouldn't we just stop the repeater and wait until mouseup before // we trigger the stop event? "mouseleave .ui-spinner-button": "_stop" }, - _draw: function() { - var uiSpinner = this.uiSpinner = this.element - .addClass( "ui-spinner-input" ) + // Support mobile enhanced option and make backcompat more sane + _enhance: function() { + this.uiSpinner = this.element .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) + .wrap( "<span>" ) .parent() - // add buttons - .append( this._buttonHtml() ); + + // Add buttons + .append( + "<a></a><a></a>" + ); + }, + + _draw: function() { + this._enhance(); + + this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); + this._addClass( "ui-spinner-input" ); this.element.attr( "role", "spinbutton" ); - // button bindings - this.buttons = uiSpinner.find( ".ui-spinner-button" ) + // Button bindings + this.buttons = this.uiSpinner.children( "a" ) .attr( "tabIndex", -1 ) - .button() - .removeClass( "ui-corner-all" ); + .attr( "aria-hidden", true ) + .button( { + classes: { + "ui-button": "" + } + } ); + + // TODO: Right now button does not support classes this is already updated in button PR + this._removeClass( this.buttons, "ui-corner-all" ); + + this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); + this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); + this.buttons.first().button( { + "icon": this.options.icons.up, + "showLabel": false + } ); + this.buttons.last().button( { + "icon": this.options.icons.down, + "showLabel": false + } ); // IE 6 doesn't understand height: 50% for the buttons // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && - uiSpinner.height() > 0 ) { - uiSpinner.height( uiSpinner.height() ); - } - - // disable spinner if element was already disabled - if ( this.options.disabled ) { - this.disable(); + if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && + this.uiSpinner.height() > 0 ) { + this.uiSpinner.height( this.uiSpinner.height() ); } }, @@ -15024,20 +17017,6 @@ var spinner = $.widget( "ui.spinner", { return false; }, - _uiSpinnerHtml: function() { - return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; - }, - - _buttonHtml: function() { - return "" + - "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + - "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + - "</a>" + - "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + - "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + - "</a>"; - }, - _start: function( event ) { if ( !this.spinning && this._trigger( "start", event ) === false ) { return false; @@ -15054,7 +17033,7 @@ var spinner = $.widget( "ui.spinner", { i = i || 500; clearTimeout( this.timer ); - this.timer = this._delay(function() { + this.timer = this._delay( function() { this._repeat( 40, steps, event ); }, i ); @@ -15070,7 +17049,7 @@ var spinner = $.widget( "ui.spinner", { value = this._adjustValue( value + step * this._increment( this.counter ) ); - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { + if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { this._value( value ); this.counter++; } @@ -15106,20 +17085,22 @@ var spinner = $.widget( "ui.spinner", { var base, aboveMin, options = this.options; - // make sure we're at a valid step + // Make sure we're at a valid step // - find out where we are relative to the base (min or 0) base = options.min !== null ? options.min : 0; aboveMin = value - base; + // - round to the nearest step - aboveMin = Math.round(aboveMin / options.step) * options.step; + aboveMin = Math.round( aboveMin / options.step ) * options.step; + // - rounding is based on 0, so adjust back to our base value = base + aboveMin; - // fix precision from bad JS floating point math + // Fix precision from bad JS floating point math value = parseFloat( value.toFixed( this._precision() ) ); - // clamp the value - if ( options.max !== null && value > options.max) { + // Clamp the value + if ( options.max !== null && value > options.max ) { return options.max; } if ( options.min !== null && value < options.min ) { @@ -15142,8 +17123,10 @@ var spinner = $.widget( "ui.spinner", { }, _setOption: function( key, value ) { + var prevValue, first, last; + if ( key === "culture" || key === "numberFormat" ) { - var prevValue = this._parse( this.element.val() ); + prevValue = this._parse( this.element.val() ); this.options[ key ] = value; this.element.val( this._format( prevValue ) ); return; @@ -15155,26 +17138,28 @@ var spinner = $.widget( "ui.spinner", { } } if ( key === "icons" ) { - this.buttons.first().find( ".ui-icon" ) - .removeClass( this.options.icons.up ) - .addClass( value.up ); - this.buttons.last().find( ".ui-icon" ) - .removeClass( this.options.icons.down ) - .addClass( value.down ); + first = this.buttons.first().find( ".ui-icon" ); + this._removeClass( first, null, this.options.icons.up ); + this._addClass( first, null, value.up ); + last = this.buttons.last().find( ".ui-icon" ); + this._removeClass( last, null, this.options.icons.down ); + this._addClass( last, null, value.down ); } this._super( key, value ); + }, - if ( key === "disabled" ) { - this.widget().toggleClass( "ui-state-disabled", !!value ); - this.element.prop( "disabled", !!value ); - this.buttons.button( value ? "disable" : "enable" ); - } + _setOptionDisabled: function( value ) { + this._super( value ); + + this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); + this.element.prop( "disabled", !!value ); + this.buttons.button( value ? "disable" : "enable" ); }, - _setOptions: spinner_modifier(function( options ) { + _setOptions: spinnerModifer( function( options ) { this._super( options ); - }), + } ), _parse: function( val ) { if ( typeof val === "string" && val !== "" ) { @@ -15194,27 +17179,28 @@ var spinner = $.widget( "ui.spinner", { }, _refresh: function() { - this.element.attr({ + this.element.attr( { "aria-valuemin": this.options.min, "aria-valuemax": this.options.max, + // TODO: what should we do with values that can't be parsed? "aria-valuenow": this._parse( this.element.val() ) - }); + } ); }, isValid: function() { var value = this.value(); - // null is invalid + // Null is invalid if ( value === null ) { return false; } - // if value gets adjusted, it's invalid + // If value gets adjusted, it's invalid return value === this._adjustValue( value ); }, - // update the value without triggering change + // Update the value without triggering change _value: function( value, allowAny ) { var parsed; if ( value !== "" ) { @@ -15232,101 +17218,134 @@ var spinner = $.widget( "ui.spinner", { _destroy: function() { this.element - .removeClass( "ui-spinner-input" ) .prop( "disabled", false ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); + .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); + this.uiSpinner.replaceWith( this.element ); }, - stepUp: spinner_modifier(function( steps ) { + stepUp: spinnerModifer( function( steps ) { this._stepUp( steps ); - }), + } ), _stepUp: function( steps ) { if ( this._start() ) { - this._spin( (steps || 1) * this.options.step ); + this._spin( ( steps || 1 ) * this.options.step ); this._stop(); } }, - stepDown: spinner_modifier(function( steps ) { + stepDown: spinnerModifer( function( steps ) { this._stepDown( steps ); - }), + } ), _stepDown: function( steps ) { if ( this._start() ) { - this._spin( (steps || 1) * -this.options.step ); + this._spin( ( steps || 1 ) * -this.options.step ); this._stop(); } }, - pageUp: spinner_modifier(function( pages ) { - this._stepUp( (pages || 1) * this.options.page ); - }), + pageUp: spinnerModifer( function( pages ) { + this._stepUp( ( pages || 1 ) * this.options.page ); + } ), - pageDown: spinner_modifier(function( pages ) { - this._stepDown( (pages || 1) * this.options.page ); - }), + pageDown: spinnerModifer( function( pages ) { + this._stepDown( ( pages || 1 ) * this.options.page ); + } ), value: function( newVal ) { if ( !arguments.length ) { return this._parse( this.element.val() ); } - spinner_modifier( this._value ).call( this, newVal ); + spinnerModifer( this._value ).call( this, newVal ); }, widget: function() { return this.uiSpinner; } -}); +} ); + +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for spinner html extension points + $.widget( "ui.spinner", $.ui.spinner, { + _enhance: function() { + this.uiSpinner = this.element + .attr( "autocomplete", "off" ) + .wrap( this._uiSpinnerHtml() ) + .parent() + + // Add buttons + .append( this._buttonHtml() ); + }, + _uiSpinnerHtml: function() { + return "<span>"; + }, + + _buttonHtml: function() { + return "<a></a><a></a>"; + } + } ); +} + +var widgetsSpinner = $.ui.spinner; /*! - * jQuery UI Tabs 1.11.4 + * jQuery UI Tabs 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/tabs/ */ +//>>label: Tabs +//>>group: Widgets +//>>description: Transforms a set of container elements into a tab structure. +//>>docs: http://api.jqueryui.com/tabs/ +//>>demos: http://jqueryui.com/tabs/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/tabs.css +//>>css.theme: ../../themes/base/theme.css + -var tabs = $.widget( "ui.tabs", { - version: "1.11.4", + +$.widget( "ui.tabs", { + version: "1.12.1", delay: 300, options: { active: null, + classes: { + "ui-tabs": "ui-corner-all", + "ui-tabs-nav": "ui-corner-all", + "ui-tabs-panel": "ui-corner-bottom", + "ui-tabs-tab": "ui-corner-top" + }, collapsible: false, event: "click", heightStyle: "content", hide: null, show: null, - // callbacks + // Callbacks activate: null, beforeActivate: null, beforeLoad: null, load: null }, - _isLocal: (function() { + _isLocal: ( function() { var rhash = /#.*$/; return function( anchor ) { var anchorUrl, locationUrl; - // support: IE7 - // IE7 doesn't normalize the href property when set via script (#9317) - anchor = anchor.cloneNode( false ); - anchorUrl = anchor.href.replace( rhash, "" ); locationUrl = location.href.replace( rhash, "" ); - // decoding may throw an error if the URL isn't UTF-8 (#9518) + // Decoding may throw an error if the URL isn't UTF-8 (#9518) try { anchorUrl = decodeURIComponent( anchorUrl ); } catch ( error ) {} @@ -15336,7 +17355,7 @@ var tabs = $.widget( "ui.tabs", { return anchor.hash.length > 1 && anchorUrl === locationUrl; }; - })(), + } )(), _create: function() { var that = this, @@ -15344,9 +17363,8 @@ var tabs = $.widget( "ui.tabs", { this.running = false; - this.element - .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ); + this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); + this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); this._processTabs(); options.active = this._initialActive(); @@ -15357,11 +17375,11 @@ var tabs = $.widget( "ui.tabs", { options.disabled = $.unique( options.disabled.concat( $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { return that.tabs.index( li ); - }) + } ) ) ).sort(); } - // check for length avoids error when initializing empty list + // Check for length avoids error when initializing empty list if ( this.options.active !== false && this.anchors.length ) { this.active = this._findActive( options.active ); } else { @@ -15381,28 +17399,29 @@ var tabs = $.widget( "ui.tabs", { locationHash = location.hash.substring( 1 ); if ( active === null ) { + // check the fragment identifier in the URL if ( locationHash ) { - this.tabs.each(function( i, tab ) { + this.tabs.each( function( i, tab ) { if ( $( tab ).attr( "aria-controls" ) === locationHash ) { active = i; return false; } - }); + } ); } - // check for a tab marked active via a class + // Check for a tab marked active via a class if ( active === null ) { active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); } - // no active tab, set to false + // No active tab, set to false if ( active === null || active === -1 ) { active = this.tabs.length ? 0 : false; } } - // handle numbers: negative, out of range + // Handle numbers: negative, out of range if ( active !== false ) { active = this.tabs.index( this.tabs.eq( active ) ); if ( active === -1 ) { @@ -15410,7 +17429,7 @@ var tabs = $.widget( "ui.tabs", { } } - // don't allow collapsible: false and active: false + // Don't allow collapsible: false and active: false if ( !collapsible && active === false && this.anchors.length ) { active = 0; } @@ -15426,7 +17445,7 @@ var tabs = $.widget( "ui.tabs", { }, _tabKeydown: function( event ) { - var focusedTab = $( this.document[0].activeElement ).closest( "li" ), + var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), selectedIndex = this.tabs.index( focusedTab ), goingForward = true; @@ -15435,36 +17454,39 @@ var tabs = $.widget( "ui.tabs", { } switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + selectedIndex++; + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.LEFT: + goingForward = false; + selectedIndex--; + break; + case $.ui.keyCode.END: + selectedIndex = this.anchors.length - 1; + break; + case $.ui.keyCode.HOME: + selectedIndex = 0; + break; + case $.ui.keyCode.SPACE: + + // Activate only, no collapsing + event.preventDefault(); + clearTimeout( this.activating ); + this._activate( selectedIndex ); + return; + case $.ui.keyCode.ENTER: + + // Toggle (cancel delayed activation, allow collapsing) + event.preventDefault(); + clearTimeout( this.activating ); + + // Determine if we should collapse or activate + this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + return; + default: + return; } // Focus the appropriate tab, based on which key was pressed @@ -15481,7 +17503,7 @@ var tabs = $.widget( "ui.tabs", { focusedTab.attr( "aria-selected", "false" ); this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); - this.activating = this._delay(function() { + this.activating = this._delay( function() { this.option( "active", selectedIndex ); }, this.delay ); } @@ -15495,7 +17517,7 @@ var tabs = $.widget( "ui.tabs", { // Ctrl+up moves focus to the current tab if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { event.preventDefault(); - this.active.focus(); + this.active.trigger( "focus" ); } }, @@ -15533,27 +17555,23 @@ var tabs = $.widget( "ui.tabs", { _focusNextTab: function( index, goingForward ) { index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).focus(); + this.tabs.eq( index ).trigger( "focus" ); return index; }, _setOption: function( key, value ) { if ( key === "active" ) { + // _activate() will handle invalid values and update this.options this._activate( value ); return; } - if ( key === "disabled" ) { - // don't use the widget factory's disabled handling - this._setupDisabled( value ); - return; - } - - this._super( key, value); + this._super( key, value ); if ( key === "collapsible" ) { - this.element.toggleClass( "ui-tabs-collapsible", value ); + this._toggleClass( "ui-tabs-collapsible", null, value ); + // Setting collapsible: false while collapsed; open first panel if ( !value && this.options.active === false ) { this._activate( 0 ); @@ -15577,30 +17595,35 @@ var tabs = $.widget( "ui.tabs", { var options = this.options, lis = this.tablist.children( ":has(a[href])" ); - // get disabled tabs from class attribute from HTML + // Get disabled tabs from class attribute from HTML // this will get converted to a boolean if needed in _refresh() options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { return lis.index( tab ); - }); + } ); this._processTabs(); - // was collapsed or no tabs + // Was collapsed or no tabs if ( options.active === false || !this.anchors.length ) { options.active = false; this.active = $(); + // was active, but active tab is gone } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { + // all remaining tabs are disabled if ( this.tabs.length === options.disabled.length ) { options.active = false; this.active = $(); + // activate previous tab } else { this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); } + // was active, active tab still exists } else { + // make sure active index is correct options.active = this.tabs.index( this.active ); } @@ -15609,37 +17632,37 @@ var tabs = $.widget( "ui.tabs", { }, _refresh: function() { - this._setupDisabled( this.options.disabled ); + this._setOptionDisabled( this.options.disabled ); this._setupEvents( this.options.event ); this._setupHeightStyle( this.options.heightStyle ); - this.tabs.not( this.active ).attr({ + this.tabs.not( this.active ).attr( { "aria-selected": "false", "aria-expanded": "false", tabIndex: -1 - }); + } ); this.panels.not( this._getPanelForTab( this.active ) ) .hide() - .attr({ + .attr( { "aria-hidden": "true" - }); + } ); // Make sure one tab is in the tab order if ( !this.active.length ) { this.tabs.eq( 0 ).attr( "tabIndex", 0 ); } else { this.active - .addClass( "ui-tabs-active ui-state-active" ) - .attr({ + .attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 - }); + } ); + this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); this._getPanelForTab( this.active ) .show() - .attr({ + .attr( { "aria-hidden": "false" - }); + } ); } }, @@ -15649,60 +17672,63 @@ var tabs = $.widget( "ui.tabs", { prevAnchors = this.anchors, prevPanels = this.panels; - this.tablist = this._getList() - .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ) + this.tablist = this._getList().attr( "role", "tablist" ); + this._addClass( this.tablist, "ui-tabs-nav", + "ui-helper-reset ui-helper-clearfix ui-widget-header" ); - // Prevent users from focusing disabled tabs via click - .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) { + // Prevent users from focusing disabled tabs via click + this.tablist + .on( "mousedown" + this.eventNamespace, "> li", function( event ) { if ( $( this ).is( ".ui-state-disabled" ) ) { event.preventDefault(); } - }) + } ) - // support: IE <9 + // Support: IE <9 // Preventing the default action in mousedown doesn't prevent IE // from focusing the element, so if the anchor gets focused, blur. // We don't have to worry about focusing the previously focused // element since clicking on a non-focusable element should focus // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { + .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { this.blur(); } - }); + } ); this.tabs = this.tablist.find( "> li:has(a[href])" ) - .addClass( "ui-state-default ui-corner-top" ) - .attr({ + .attr( { role: "tab", tabIndex: -1 - }); + } ); + this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); - this.anchors = this.tabs.map(function() { - return $( "a", this )[ 0 ]; - }) - .addClass( "ui-tabs-anchor" ) - .attr({ + this.anchors = this.tabs.map( function() { + return $( "a", this )[ 0 ]; + } ) + .attr( { role: "presentation", tabIndex: -1 - }); + } ); + this._addClass( this.anchors, "ui-tabs-anchor" ); this.panels = $(); - this.anchors.each(function( i, anchor ) { + this.anchors.each( function( i, anchor ) { var selector, panel, panelId, anchorId = $( anchor ).uniqueId().attr( "id" ), tab = $( anchor ).closest( "li" ), originalAriaControls = tab.attr( "aria-controls" ); - // inline tab + // Inline tab if ( that._isLocal( anchor ) ) { selector = anchor.hash; panelId = selector.substring( 1 ); panel = that.element.find( that._sanitizeSelector( selector ) ); + // remote tab } else { + // If the tab doesn't already have aria-controls, // generate an id by using a throw-away element panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; @@ -15715,22 +17741,21 @@ var tabs = $.widget( "ui.tabs", { panel.attr( "aria-live", "polite" ); } - if ( panel.length) { + if ( panel.length ) { that.panels = that.panels.add( panel ); } if ( originalAriaControls ) { tab.data( "ui-tabs-aria-controls", originalAriaControls ); } - tab.attr({ + tab.attr( { "aria-controls": panelId, "aria-labelledby": anchorId - }); + } ); panel.attr( "aria-labelledby", anchorId ); - }); + } ); - this.panels - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .attr( "role", "tabpanel" ); + this.panels.attr( "role", "tabpanel" ); + this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); // Avoid memory leaks (#10056) if ( prevTabs ) { @@ -15740,19 +17765,20 @@ var tabs = $.widget( "ui.tabs", { } }, - // allow overriding how to find the list for rare usage scenarios (#7715) + // Allow overriding how to find the list for rare usage scenarios (#7715) _getList: function() { - return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); + return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); }, _createPanel: function( id ) { return $( "<div>" ) .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) .data( "ui-tabs-destroy", true ); }, - _setupDisabled: function( disabled ) { + _setOptionDisabled: function( disabled ) { + var currentItem, li, i; + if ( $.isArray( disabled ) ) { if ( !disabled.length ) { disabled = false; @@ -15761,37 +17787,40 @@ var tabs = $.widget( "ui.tabs", { } } - // disable tabs - for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { + // Disable tabs + for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { + currentItem = $( li ); if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - $( li ) - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); + currentItem.attr( "aria-disabled", "true" ); + this._addClass( currentItem, null, "ui-state-disabled" ); } else { - $( li ) - .removeClass( "ui-state-disabled" ) - .removeAttr( "aria-disabled" ); + currentItem.removeAttr( "aria-disabled" ); + this._removeClass( currentItem, null, "ui-state-disabled" ); } } this.options.disabled = disabled; + + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, + disabled === true ); }, _setupEvents: function( event ) { var events = {}; if ( event ) { - $.each( event.split(" "), function( index, eventName ) { + $.each( event.split( " " ), function( index, eventName ) { events[ eventName ] = "_eventHandler"; - }); + } ); } this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + // Always prevent the default action, even when disabled this._on( true, this.anchors, { click: function( event ) { event.preventDefault(); } - }); + } ); this._on( this.anchors, events ); this._on( this.tabs, { keydown: "_tabKeydown" } ); this._on( this.panels, { keydown: "_panelKeydown" } ); @@ -15808,7 +17837,7 @@ var tabs = $.widget( "ui.tabs", { maxHeight = parent.height(); maxHeight -= this.element.outerHeight() - this.element.height(); - this.element.siblings( ":visible" ).each(function() { + this.element.siblings( ":visible" ).each( function() { var elem = $( this ), position = elem.css( "position" ); @@ -15816,22 +17845,22 @@ var tabs = $.widget( "ui.tabs", { return; } maxHeight -= elem.outerHeight( true ); - }); + } ); - this.element.children().not( this.panels ).each(function() { + this.element.children().not( this.panels ).each( function() { maxHeight -= $( this ).outerHeight( true ); - }); + } ); - this.panels.each(function() { + this.panels.each( function() { $( this ).height( Math.max( 0, maxHeight - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); + } ) + .css( "overflow", "auto" ); } else if ( heightStyle === "auto" ) { maxHeight = 0; - this.panels.each(function() { + this.panels.each( function() { maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }).height( maxHeight ); + } ).height( maxHeight ); } }, @@ -15854,12 +17883,16 @@ var tabs = $.widget( "ui.tabs", { event.preventDefault(); if ( tab.hasClass( "ui-state-disabled" ) || + // tab is already loading tab.hasClass( "ui-tabs-loading" ) || + // can't switch durning an animation this.running || + // click on active header, but not collapsible ( clickedIsActive && !options.collapsible ) || + // allow canceling activation ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { return; @@ -15882,7 +17915,7 @@ var tabs = $.widget( "ui.tabs", { this._toggle( event, eventData ); }, - // handles show/hide for selecting tabs + // Handles show/hide for selecting tabs _toggle: function( event, eventData ) { var that = this, toShow = eventData.newPanel, @@ -15896,7 +17929,7 @@ var tabs = $.widget( "ui.tabs", { } function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); + that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); if ( toShow.length && that.options.show ) { that._show( toShow, that.options.show, complete ); @@ -15906,63 +17939,66 @@ var tabs = $.widget( "ui.tabs", { } } - // start out by hiding, then showing, then completing + // Start out by hiding, then showing, then completing if ( toHide.length && this.options.hide ) { this._hide( toHide, this.options.hide, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + that._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); show(); - }); + } ); } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + this._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); toHide.hide(); show(); } toHide.attr( "aria-hidden", "true" ); - eventData.oldTab.attr({ + eventData.oldTab.attr( { "aria-selected": "false", "aria-expanded": "false" - }); + } ); + // If we're switching tabs, remove the old tab from the tab order. // If we're opening from collapsed state, remove the previous tab from the tab order. // If we're collapsing, then keep the collapsing tab in the tab order. if ( toShow.length && toHide.length ) { eventData.oldTab.attr( "tabIndex", -1 ); } else if ( toShow.length ) { - this.tabs.filter(function() { + this.tabs.filter( function() { return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); + } ) + .attr( "tabIndex", -1 ); } toShow.attr( "aria-hidden", "false" ); - eventData.newTab.attr({ + eventData.newTab.attr( { "aria-selected": "true", "aria-expanded": "true", tabIndex: 0 - }); + } ); }, _activate: function( index ) { var anchor, active = this._findActive( index ); - // trying to activate the already active panel + // Trying to activate the already active panel if ( active[ 0 ] === this.active[ 0 ] ) { return; } - // trying to collapse, simulate a click on the current active header + // Trying to collapse, simulate a click on the current active header if ( !active.length ) { active = this.active; } anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler({ + this._eventHandler( { target: anchor, currentTarget: anchor, preventDefault: $.noop - }); + } ); }, _findActive: function( index ) { @@ -15970,9 +18006,11 @@ var tabs = $.widget( "ui.tabs", { }, _getIndex: function( index ) { + // meta-function to give users option to provide a href string instead of a numerical index. if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); + index = this.anchors.index( this.anchors.filter( "[href$='" + + $.ui.escapeSelector( index ) + "']" ) ); } return index; @@ -15983,39 +18021,24 @@ var tabs = $.widget( "ui.tabs", { this.xhr.abort(); } - this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); - this.tablist - .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .removeAttr( "role" ); + .removeAttr( "role" ) + .off( this.eventNamespace ); this.anchors - .removeClass( "ui-tabs-anchor" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) + .removeAttr( "role tabIndex" ) .removeUniqueId(); - this.tablist.unbind( this.eventNamespace ); - - this.tabs.add( this.panels ).each(function() { + this.tabs.add( this.panels ).each( function() { if ( $.data( this, "ui-tabs-destroy" ) ) { $( this ).remove(); } else { - $( this ) - .removeClass( "ui-state-default ui-state-active ui-state-disabled " + - "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-live" ) - .removeAttr( "aria-busy" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "role" ); - } - }); - - this.tabs.each(function() { + $( this ).removeAttr( "role tabIndex " + + "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); + } + } ); + + this.tabs.each( function() { var li = $( this ), prev = li.data( "ui-tabs-aria-controls" ); if ( prev ) { @@ -16025,7 +18048,7 @@ var tabs = $.widget( "ui.tabs", { } else { li.removeAttr( "aria-controls" ); } - }); + } ); this.panels.show(); @@ -16047,14 +18070,14 @@ var tabs = $.widget( "ui.tabs", { if ( $.isArray( disabled ) ) { disabled = $.map( disabled, function( num ) { return num !== index ? num : null; - }); + } ); } else { disabled = $.map( this.tabs, function( li, num ) { return num !== index ? num : null; - }); + } ); } } - this._setupDisabled( disabled ); + this._setOptionDisabled( disabled ); }, disable: function( index ) { @@ -16076,7 +18099,7 @@ var tabs = $.widget( "ui.tabs", { disabled = [ index ]; } } - this._setupDisabled( disabled ); + this._setOptionDisabled( disabled ); }, load: function( index, event ) { @@ -16094,7 +18117,7 @@ var tabs = $.widget( "ui.tabs", { that.panels.stop( false, true ); } - tab.removeClass( "ui-tabs-loading" ); + that._removeClass( tab, "ui-tabs-loading" ); panel.removeAttr( "aria-busy" ); if ( jqXHR === that.xhr ) { @@ -16102,45 +18125,50 @@ var tabs = $.widget( "ui.tabs", { } }; - // not remote + // Not remote if ( this._isLocal( anchor[ 0 ] ) ) { return; } this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - // support: jQuery <1.8 + // Support: jQuery <1.8 // jQuery <1.8 returns false if the request is canceled in beforeSend, // but as of 1.8, $.ajax() always returns a jqXHR object. if ( this.xhr && this.xhr.statusText !== "canceled" ) { - tab.addClass( "ui-tabs-loading" ); + this._addClass( tab, "ui-tabs-loading" ); panel.attr( "aria-busy", "true" ); this.xhr - .done(function( response, status, jqXHR ) { + .done( function( response, status, jqXHR ) { + // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { + setTimeout( function() { panel.html( response ); that._trigger( "load", event, eventData ); complete( jqXHR, status ); }, 1 ); - }) - .fail(function( jqXHR, status ) { + } ) + .fail( function( jqXHR, status ) { + // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { + setTimeout( function() { complete( jqXHR, status ); }, 1 ); - }); + } ); } }, _ajaxSettings: function( anchor, event, eventData ) { var that = this; return { - url: anchor.attr( "href" ), + + // Support: IE <11 only + // Strip any hash that exists to prevent errors with the Ajax request + url: anchor.attr( "href" ).replace( /#.*$/, "" ), beforeSend: function( jqXHR, settings ) { return that._trigger( "beforeLoad", event, $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); @@ -16152,32 +18180,61 @@ var tabs = $.widget( "ui.tabs", { var id = $( tab ).attr( "aria-controls" ); return this.element.find( this._sanitizeSelector( "#" + id ) ); } -}); +} ); + +// DEPRECATED +// TODO: Switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for ui-tab class (now ui-tabs-tab) + $.widget( "ui.tabs", $.ui.tabs, { + _processTabs: function() { + this._superApply( arguments ); + this._addClass( this.tabs, "ui-tab" ); + } + } ); +} + +var widgetsTabs = $.ui.tabs; /*! - * jQuery UI Tooltip 1.11.4 + * jQuery UI Tooltip 1.12.1 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license - * - * http://api.jqueryui.com/tooltip/ */ +//>>label: Tooltip +//>>group: Widgets +//>>description: Shows additional information for any element on hover or focus. +//>>docs: http://api.jqueryui.com/tooltip/ +//>>demos: http://jqueryui.com/tooltip/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/tooltip.css +//>>css.theme: ../../themes/base/theme.css -var tooltip = $.widget( "ui.tooltip", { - version: "1.11.4", + + +$.widget( "ui.tooltip", { + version: "1.12.1", options: { + classes: { + "ui-tooltip": "ui-corner-all ui-widget-shadow" + }, content: function() { + // support: IE<9, Opera in jQuery <1.7 // .text() can't accept undefined, so coerce to a string var title = $( this ).attr( "title" ) || ""; + // Escape title, since we're going from an attribute to raw HTML return $( "<a>" ).text( title ).html(); }, hide: true, + // Disabled elements have inconsistent behavior across browsers (#8661) items: "[title]:not([disabled])", position: { @@ -16186,16 +18243,15 @@ var tooltip = $.widget( "ui.tooltip", { collision: "flipfit flip" }, show: true, - tooltipClass: null, track: false, - // callbacks + // Callbacks close: null, open: null }, _addDescribedBy: function( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); + var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); describedby.push( id ); elem .data( "ui-tooltip-id", id ) @@ -16204,7 +18260,7 @@ var tooltip = $.widget( "ui.tooltip", { _removeDescribedBy: function( elem ) { var id = elem.data( "ui-tooltip-id" ), - describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), + describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), index = $.inArray( id, describedby ); if ( index !== -1 ) { @@ -16221,10 +18277,10 @@ var tooltip = $.widget( "ui.tooltip", { }, _create: function() { - this._on({ + this._on( { mouseover: "open", focusin: "open" - }); + } ); // IDs of generated tooltips, needed for destroy this.tooltips = {}; @@ -16232,74 +18288,75 @@ var tooltip = $.widget( "ui.tooltip", { // IDs of parent tooltips where we removed the title attribute this.parents = {}; - if ( this.options.disabled ) { - this._disable(); - } - // Append the aria-live region so tooltips announce correctly this.liveRegion = $( "<div>" ) - .attr({ + .attr( { role: "log", "aria-live": "assertive", "aria-relevant": "additions" - }) - .addClass( "ui-helper-hidden-accessible" ) + } ) .appendTo( this.document[ 0 ].body ); + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); + + this.disabledTitles = $( [] ); }, _setOption: function( key, value ) { var that = this; - if ( key === "disabled" ) { - this[ value ? "_disable" : "_enable" ](); - this.options[ key ] = value; - // disable element style changes - return; - } - this._super( key, value ); if ( key === "content" ) { $.each( this.tooltips, function( id, tooltipData ) { that._updateContent( tooltipData.element ); - }); + } ); } }, + _setOptionDisabled: function( value ) { + this[ value ? "_disable" : "_enable" ](); + }, + _disable: function() { var that = this; - // close open tooltips + // Close open tooltips $.each( this.tooltips, function( id, tooltipData ) { var event = $.Event( "blur" ); event.target = event.currentTarget = tooltipData.element[ 0 ]; that.close( event, true ); - }); - - // remove title attributes to prevent native tooltips - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .removeAttr( "title" ); - } - }); + } ); + + // Remove title attributes to prevent native tooltips + this.disabledTitles = this.disabledTitles.add( + this.element.find( this.options.items ).addBack() + .filter( function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + return element + .data( "ui-tooltip-title", element.attr( "title" ) ) + .removeAttr( "title" ); + } + } ) + ); }, _enable: function() { + // restore title attributes - this.element.find( this.options.items ).addBack().each(function() { + this.disabledTitles.each( function() { var element = $( this ); if ( element.data( "ui-tooltip-title" ) ) { element.attr( "title", element.data( "ui-tooltip-title" ) ); } - }); + } ); + this.disabledTitles = $( [] ); }, open: function( event ) { var that = this, target = $( event ? event.target : this.element ) + // we need closest here due to mouseover bubbling, // but always pointing at the same event target .closest( this.options.items ); @@ -16315,9 +18372,9 @@ var tooltip = $.widget( "ui.tooltip", { target.data( "ui-tooltip-open", true ); - // kill parent tooltips, custom or native, for hover + // Kill parent tooltips, custom or native, for hover if ( event && event.type === "mouseover" ) { - target.parents().each(function() { + target.parents().each( function() { var parent = $( this ), blurEvent; if ( parent.data( "ui-tooltip-open" ) ) { @@ -16333,7 +18390,7 @@ var tooltip = $.widget( "ui.tooltip", { }; parent.attr( "title", "" ); } - }); + } ); } this._registerCloseHandlers( event, target ); @@ -16346,22 +18403,23 @@ var tooltip = $.widget( "ui.tooltip", { that = this, eventType = event ? event.type : null; - if ( typeof contentOption === "string" ) { + if ( typeof contentOption === "string" || contentOption.nodeType || + contentOption.jquery ) { return this._open( event, target, contentOption ); } - content = contentOption.call( target[0], function( response ) { + content = contentOption.call( target[ 0 ], function( response ) { // IE may instantly serve a cached response for ajax requests // delay this call to _open so the other call to _open runs first - that._delay(function() { + that._delay( function() { // Ignore async response if tooltip was closed already if ( !target.data( "ui-tooltip-open" ) ) { return; } - // jQuery creates a special event for focusin when it doesn't + // JQuery creates a special event for focusin when it doesn't // exist natively. To improve performance, the native event // object is reused and the type is changed. Therefore, we can't // rely on the type being correct after the event finished @@ -16370,8 +18428,8 @@ var tooltip = $.widget( "ui.tooltip", { event.type = eventType; } this._open( event, target, response ); - }); - }); + } ); + } ); if ( content ) { this._open( event, target, content ); } @@ -16393,7 +18451,7 @@ var tooltip = $.widget( "ui.tooltip", { return; } - // if we have a title, clear it to prevent the native tooltip + // If we have a title, clear it to prevent the native tooltip // we have to check first to avoid defining a title if none exists // (we don't want to cause an element to start matching [title]) // @@ -16417,13 +18475,10 @@ var tooltip = $.widget( "ui.tooltip", { // JAWS announces deletions even when aria-relevant="additions" // Voiceover will sometimes re-read the entire log region's contents from the beginning this.liveRegion.children().hide(); - if ( content.clone ) { - a11yContent = content.clone(); - a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); - } else { - a11yContent = content; - } - $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion ); + a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); + a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); + a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); + a11yContent.appendTo( this.liveRegion ); function position( event ) { positionOption.of = event; @@ -16435,11 +18490,12 @@ var tooltip = $.widget( "ui.tooltip", { if ( this.options.track && event && /^mouse/.test( event.type ) ) { this._on( this.document, { mousemove: position - }); + } ); + // trigger once to override element-relative positioning position( event ); } else { - tooltip.position( $.extend({ + tooltip.position( $.extend( { of: target }, this.options.position ) ); } @@ -16447,11 +18503,13 @@ var tooltip = $.widget( "ui.tooltip", { tooltip.hide(); this._show( tooltip, this.options.show ); + // Handle tracking tooltips that are shown with a delay (#8644). As soon // as the tooltip is visible, position the tooltip using the most recent // event. - if ( this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval(function() { + // Adds the check to add the timers only when both delay and track options are set (#14682) + if ( this.options.track && this.options.show && this.options.show.delay ) { + delayedShow = this.delayedShow = setInterval( function() { if ( tooltip.is( ":visible" ) ) { position( positionOption.of ); clearInterval( delayedShow ); @@ -16466,8 +18524,8 @@ var tooltip = $.widget( "ui.tooltip", { var events = { keyup: function( event ) { if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event(event); - fakeEvent.currentTarget = target[0]; + var fakeEvent = $.Event( event ); + fakeEvent.currentTarget = target[ 0 ]; this.close( fakeEvent, true ); } } @@ -16509,7 +18567,7 @@ var tooltip = $.widget( "ui.tooltip", { tooltip = tooltipData.tooltip; - // disabling closes the tooltip, so we need to track when we're closing + // Disabling closes the tooltip, so we need to track when we're closing // to avoid an infinite loop in case the tooltip becomes disabled on close if ( tooltipData.closing ) { return; @@ -16518,7 +18576,7 @@ var tooltip = $.widget( "ui.tooltip", { // Clear the interval for delayed tracking tooltips clearInterval( this.delayedShow ); - // only set title if we had one before (see comment in _open()) + // Only set title if we had one before (see comment in _open()) // If the title attribute has changed since open(), don't restore if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { target.attr( "title", target.data( "ui-tooltip-title" ) ); @@ -16530,7 +18588,7 @@ var tooltip = $.widget( "ui.tooltip", { tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { that._removeTooltip( $( this ) ); - }); + } ); target.removeData( "ui-tooltip-open" ); this._off( target, "mouseleave focusout keyup" ); @@ -16545,7 +18603,7 @@ var tooltip = $.widget( "ui.tooltip", { $.each( this.parents, function( id, parent ) { $( parent.element ).attr( "title", parent.title ); delete that.parents[ id ]; - }); + } ); } tooltipData.closing = true; @@ -16556,17 +18614,14 @@ var tooltip = $.widget( "ui.tooltip", { }, _tooltip: function( element ) { - var tooltip = $( "<div>" ) - .attr( "role", "tooltip" ) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ), + var tooltip = $( "<div>" ).attr( "role", "tooltip" ), + content = $( "<div>" ).appendTo( tooltip ), id = tooltip.uniqueId().attr( "id" ); - $( "<div>" ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); + this._addClass( content, "ui-tooltip-content" ); + this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); - tooltip.appendTo( this.document[0].body ); + tooltip.appendTo( this._appendTo( element ) ); return this.tooltips[ id ] = { element: element, @@ -16584,11 +18639,22 @@ var tooltip = $.widget( "ui.tooltip", { delete this.tooltips[ tooltip.attr( "id" ) ]; }, + _appendTo: function( target ) { + var element = target.closest( ".ui-front, dialog" ); + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + _destroy: function() { var that = this; - // close open tooltips + // Close open tooltips $.each( this.tooltips, function( id, tooltipData ) { + // Delegate to close method to handle common cleanup var event = $.Event( "blur" ), element = tooltipData.element; @@ -16601,16 +18667,39 @@ var tooltip = $.widget( "ui.tooltip", { // Restore the title if ( element.data( "ui-tooltip-title" ) ) { + // If the title attribute has changed since open(), don't restore if ( !element.attr( "title" ) ) { element.attr( "title", element.data( "ui-tooltip-title" ) ); } element.removeData( "ui-tooltip-title" ); } - }); + } ); this.liveRegion.remove(); } -}); +} ); + +// DEPRECATED +// TODO: Switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for tooltipClass option + $.widget( "ui.tooltip", $.ui.tooltip, { + options: { + tooltipClass: null + }, + _tooltip: function() { + var tooltipData = this._superApply( arguments ); + if ( this.options.tooltipClass ) { + tooltipData.tooltip.addClass( this.options.tooltipClass ); + } + return tooltipData; + } + } ); +} + +var widgetsTooltip = $.ui.tooltip; + |