You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2723 lines
71 KiB
2723 lines
71 KiB
/*! jQuery UI - v1.12.1 - 2017-07-27
|
|
* http://jqueryui.com
|
|
* Includes: widget.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/mouse.js, widgets/spinner.js
|
|
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
|
|
|
(function( factory ) {
|
|
if ( typeof define === "function" && define.amd ) {
|
|
|
|
// AMD. Register as an anonymous module.
|
|
define([ "jquery" ], factory );
|
|
} else {
|
|
|
|
// Browser globals
|
|
factory( jQuery );
|
|
}
|
|
}(function( $ ) {
|
|
|
|
$.ui = $.ui || {};
|
|
|
|
var version = $.ui.version = "1.12.1";
|
|
|
|
|
|
/*!
|
|
* jQuery UI Widget 1.12.1
|
|
* http://jqueryui.com
|
|
*
|
|
* Copyright jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*/
|
|
|
|
//>>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 widgetUuid = 0;
|
|
var widgetSlice = Array.prototype.slice;
|
|
|
|
$.cleanData = ( function( orig ) {
|
|
return function( elems ) {
|
|
var events, elem, i;
|
|
for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
|
|
try {
|
|
|
|
// Only trigger remove when necessary to save time
|
|
events = $._data( elem, "events" );
|
|
if ( events && events.remove ) {
|
|
$( elem ).triggerHandler( "remove" );
|
|
}
|
|
|
|
// Http://bugs.jquery.com/ticket/8235
|
|
} catch ( e ) {}
|
|
}
|
|
orig( elems );
|
|
};
|
|
} )( $.cleanData );
|
|
|
|
$.widget = function( name, base, prototype ) {
|
|
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 ];
|
|
var fullName = namespace + "-" + name;
|
|
|
|
if ( !prototype ) {
|
|
prototype = base;
|
|
base = $.Widget;
|
|
}
|
|
|
|
if ( $.isArray( prototype ) ) {
|
|
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
|
|
}
|
|
|
|
// Create selector for plugin
|
|
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
|
|
return !!$.data( elem, fullName );
|
|
};
|
|
|
|
$[ namespace ] = $[ namespace ] || {};
|
|
existingConstructor = $[ namespace ][ name ];
|
|
constructor = $[ namespace ][ name ] = function( options, element ) {
|
|
|
|
// Allow instantiation without "new" keyword
|
|
if ( !this._createWidget ) {
|
|
return new constructor( options, element );
|
|
}
|
|
|
|
// 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( constructor, existingConstructor, {
|
|
version: prototype.version,
|
|
|
|
// 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
|
|
// 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
|
|
// otherwise we'll modify the options hash on the prototype that we're
|
|
// inheriting from
|
|
basePrototype.options = $.widget.extend( {}, basePrototype.options );
|
|
$.each( prototype, function( prop, value ) {
|
|
if ( !$.isFunction( value ) ) {
|
|
proxiedPrototype[ prop ] = value;
|
|
return;
|
|
}
|
|
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;
|
|
var __superApply = this._superApply;
|
|
var returnValue;
|
|
|
|
this._super = _super;
|
|
this._superApply = _superApply;
|
|
|
|
returnValue = value.apply( this, arguments );
|
|
|
|
this._super = __super;
|
|
this._superApply = __superApply;
|
|
|
|
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
|
|
}, 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
|
|
// the new version of this widget. We're essentially trying to replace one
|
|
// level in the prototype chain.
|
|
if ( existingConstructor ) {
|
|
$.each( existingConstructor._childConstructors, function( i, child ) {
|
|
var childPrototype = child.prototype;
|
|
|
|
// 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
|
|
// so the old child constructors can be garbage collected
|
|
delete existingConstructor._childConstructors;
|
|
} else {
|
|
base._childConstructors.push( constructor );
|
|
}
|
|
|
|
$.widget.bridge( name, constructor );
|
|
|
|
return constructor;
|
|
};
|
|
|
|
$.widget.extend = function( target ) {
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
};
|
|
|
|
$.widget.bridge = function( name, object ) {
|
|
var fullName = object.prototype.widgetFullName || name;
|
|
$.fn[ name ] = function( options ) {
|
|
var isMethodCall = typeof options === "string";
|
|
var args = widgetSlice.call( arguments, 1 );
|
|
var returnValue = this;
|
|
|
|
if ( isMethodCall ) {
|
|
|
|
// 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 ) );
|
|
}
|
|
|
|
this.each( function() {
|
|
var instance = $.data( this, fullName );
|
|
if ( instance ) {
|
|
instance.option( options || {} );
|
|
if ( instance._init ) {
|
|
instance._init();
|
|
}
|
|
} else {
|
|
$.data( this, fullName, new object( options, this ) );
|
|
}
|
|
} );
|
|
}
|
|
|
|
return returnValue;
|
|
};
|
|
};
|
|
|
|
$.Widget = function( /* options, element */ ) {};
|
|
$.Widget._childConstructors = [];
|
|
|
|
$.Widget.prototype = {
|
|
widgetName: "widget",
|
|
widgetEventPrefix: "",
|
|
defaultElement: "<div>",
|
|
|
|
options: {
|
|
classes: {},
|
|
disabled: false,
|
|
|
|
// Callbacks
|
|
create: null
|
|
},
|
|
|
|
_createWidget: function( options, element ) {
|
|
element = $( element || this.defaultElement || this )[ 0 ];
|
|
this.element = $( element );
|
|
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 );
|
|
this._on( true, this.element, {
|
|
remove: function( event ) {
|
|
if ( event.target === element ) {
|
|
this.destroy();
|
|
}
|
|
}
|
|
} );
|
|
this.document = $( element.style ?
|
|
|
|
// Element within the document
|
|
element.ownerDocument :
|
|
|
|
// Element is window or document
|
|
element.document || element );
|
|
this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
|
|
}
|
|
|
|
this.options = $.widget.extend( {},
|
|
this.options,
|
|
this._getCreateOptions(),
|
|
options );
|
|
|
|
this._create();
|
|
|
|
if ( this.options.disabled ) {
|
|
this._setOptionDisabled( this.options.disabled );
|
|
}
|
|
|
|
this._trigger( "create", null, this._getCreateEventData() );
|
|
this._init();
|
|
},
|
|
|
|
_getCreateOptions: function() {
|
|
return {};
|
|
},
|
|
|
|
_getCreateEventData: $.noop,
|
|
|
|
_create: $.noop,
|
|
|
|
_init: $.noop,
|
|
|
|
destroy: function() {
|
|
var that = this;
|
|
|
|
this._destroy();
|
|
$.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
|
|
.off( this.eventNamespace )
|
|
.removeData( this.widgetFullName );
|
|
this.widget()
|
|
.off( this.eventNamespace )
|
|
.removeAttr( "aria-disabled" );
|
|
|
|
// Clean up events and states
|
|
this.bindings.off( this.eventNamespace );
|
|
},
|
|
|
|
_destroy: $.noop,
|
|
|
|
widget: function() {
|
|
return this.element;
|
|
},
|
|
|
|
option: function( key, value ) {
|
|
var options = key;
|
|
var parts;
|
|
var curOption;
|
|
var i;
|
|
|
|
if ( arguments.length === 0 ) {
|
|
|
|
// 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: ___ } }
|
|
options = {};
|
|
parts = key.split( "." );
|
|
key = parts.shift();
|
|
if ( parts.length ) {
|
|
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
|
|
for ( i = 0; i < parts.length - 1; i++ ) {
|
|
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
|
|
curOption = curOption[ parts[ i ] ];
|
|
}
|
|
key = parts.pop();
|
|
if ( arguments.length === 1 ) {
|
|
return curOption[ key ] === undefined ? null : curOption[ key ];
|
|
}
|
|
curOption[ key ] = value;
|
|
} else {
|
|
if ( arguments.length === 1 ) {
|
|
return this.options[ key ] === undefined ? null : this.options[ key ];
|
|
}
|
|
options[ key ] = value;
|
|
}
|
|
}
|
|
|
|
this._setOptions( options );
|
|
|
|
return this;
|
|
},
|
|
|
|
_setOptions: function( options ) {
|
|
var key;
|
|
|
|
for ( key in options ) {
|
|
this._setOption( key, options[ key ] );
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
_setOption: function( key, value ) {
|
|
if ( key === "classes" ) {
|
|
this._setOptionClasses( value );
|
|
}
|
|
|
|
this.options[ key ] = value;
|
|
|
|
if ( key === "disabled" ) {
|
|
this._setOptionDisabled( value );
|
|
}
|
|
|
|
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
|
|
} ) );
|
|
}
|
|
},
|
|
|
|
_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 } );
|
|
},
|
|
|
|
disable: function() {
|
|
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;
|
|
var instance = this;
|
|
|
|
// No suppressDisabledCheck flag, shuffle arguments
|
|
if ( typeof suppressDisabledCheck !== "boolean" ) {
|
|
handlers = element;
|
|
element = suppressDisabledCheck;
|
|
suppressDisabledCheck = false;
|
|
}
|
|
|
|
// No element argument, shuffle and use this.element
|
|
if ( !handlers ) {
|
|
handlers = element;
|
|
element = this.element;
|
|
delegateElement = this.widget();
|
|
} else {
|
|
element = delegateElement = $( element );
|
|
this.bindings = this.bindings.add( element );
|
|
}
|
|
|
|
$.each( handlers, function( event, handler ) {
|
|
function handlerProxy() {
|
|
|
|
// 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" ) ) ) {
|
|
return;
|
|
}
|
|
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
|
.apply( instance, arguments );
|
|
}
|
|
|
|
// 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*(.*)$/ );
|
|
var eventName = match[ 1 ] + instance.eventNamespace;
|
|
var selector = match[ 2 ];
|
|
|
|
if ( selector ) {
|
|
delegateElement.on( eventName, selector, handlerProxy );
|
|
} else {
|
|
element.on( eventName, handlerProxy );
|
|
}
|
|
} );
|
|
},
|
|
|
|
_off: function( element, eventName ) {
|
|
eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
|
|
this.eventNamespace;
|
|
element.off( eventName ).off( eventName );
|
|
|
|
// Clear the stack to avoid memory leaks (#10056)
|
|
this.bindings = $( this.bindings.not( element ).get() );
|
|
this.focusable = $( this.focusable.not( element ).get() );
|
|
this.hoverable = $( this.hoverable.not( element ).get() );
|
|
},
|
|
|
|
_delay: function( handler, delay ) {
|
|
function handlerProxy() {
|
|
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
|
.apply( instance, arguments );
|
|
}
|
|
var instance = this;
|
|
return setTimeout( handlerProxy, delay || 0 );
|
|
},
|
|
|
|
_hoverable: function( element ) {
|
|
this.hoverable = this.hoverable.add( element );
|
|
this._on( element, {
|
|
mouseenter: function( event ) {
|
|
this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
|
|
},
|
|
mouseleave: function( event ) {
|
|
this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
|
|
}
|
|
} );
|
|
},
|
|
|
|
_focusable: function( element ) {
|
|
this.focusable = this.focusable.add( element );
|
|
this._on( element, {
|
|
focusin: function( event ) {
|
|
this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
|
|
},
|
|
focusout: function( event ) {
|
|
this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
|
|
}
|
|
} );
|
|
},
|
|
|
|
_trigger: function( type, event, data ) {
|
|
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
|
|
// 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
|
|
orig = event.originalEvent;
|
|
if ( orig ) {
|
|
for ( prop in orig ) {
|
|
if ( !( prop in event ) ) {
|
|
event[ prop ] = orig[ prop ];
|
|
}
|
|
}
|
|
}
|
|
|
|
this.element.trigger( event, data );
|
|
return !( $.isFunction( callback ) &&
|
|
callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
|
|
event.isDefaultPrevented() );
|
|
}
|
|
};
|
|
|
|
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
|
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
|
|
if ( typeof options === "string" ) {
|
|
options = { effect: options };
|
|
}
|
|
|
|
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 ) {
|
|
$( this )[ method ]();
|
|
if ( callback ) {
|
|
callback.call( element[ 0 ] );
|
|
}
|
|
next();
|
|
} );
|
|
}
|
|
};
|
|
} );
|
|
|
|
var widget = $.widget;
|
|
|
|
|
|
|
|
|
|
// 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 Controlgroup 1.12.1
|
|
* http://jqueryui.com
|
|
*
|
|
* Copyright jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*/
|
|
|
|
//>>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 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 {
|
|
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 );
|
|
}
|
|
|
|
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,
|
|
label: 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() {
|
|
var checked = this.element[ 0 ].checked;
|
|
|
|
this._bindFormResetHandler();
|
|
|
|
if ( this.options.disabled == null ) {
|
|
this.options.disabled = this.element[ 0 ].disabled;
|
|
}
|
|
|
|
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" );
|
|
|
|
if ( this.type === "radio" ) {
|
|
this._addClass( this.label, "ui-checkboxradio-radio-label" );
|
|
}
|
|
|
|
if ( this.options.label && this.options.label !== this.originalLabel ) {
|
|
this._updateLabel();
|
|
} else if ( this.originalLabel ) {
|
|
this.options.label = this.originalLabel;
|
|
}
|
|
|
|
this._enhance();
|
|
|
|
if ( checked ) {
|
|
this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
|
|
if ( this.icon ) {
|
|
this._addClass( this.icon, null, "ui-state-hover" );
|
|
}
|
|
}
|
|
|
|
this._on( {
|
|
change: "_toggleClasses",
|
|
focus: function() {
|
|
this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
|
|
},
|
|
blur: function() {
|
|
this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
|
|
}
|
|
} );
|
|
},
|
|
|
|
_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 );
|
|
}
|
|
},
|
|
|
|
// Support jQuery Mobile enhanced option
|
|
_enhance: function() {
|
|
this._updateIcon( this.element[ 0 ].checked );
|
|
},
|
|
|
|
widget: function() {
|
|
return this.label;
|
|
},
|
|
|
|
_getRadioGroup: function() {
|
|
var group;
|
|
var name = this.element[ 0 ].name;
|
|
var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
|
|
|
|
if ( !name ) {
|
|
return $( [] );
|
|
}
|
|
|
|
if ( this.form.length ) {
|
|
group = $( this.form[ 0 ].elements ).filter( nameSelector );
|
|
} else {
|
|
|
|
// 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 );
|
|
},
|
|
|
|
_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._unbindFormResetHandler();
|
|
|
|
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._toggleClass( this.label, null, "ui-state-disabled", value );
|
|
this.element[ 0 ].disabled = value;
|
|
|
|
// Don't refresh when setting disabled
|
|
return;
|
|
}
|
|
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() {
|
|
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._setOptions( { "disabled": isDisabled } );
|
|
}
|
|
}
|
|
|
|
} ] );
|
|
|
|
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;
|
|
},
|
|
|
|
_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 );
|
|
}
|
|
}
|
|
this._addClass( "ui-button", "ui-widget" );
|
|
this._setOption( "disabled", this.options.disabled );
|
|
this._enhance();
|
|
|
|
if ( this.element.is( "a" ) ) {
|
|
this._on( {
|
|
"keyup": function( event ) {
|
|
if ( event.keyCode === $.ui.keyCode.SPACE ) {
|
|
event.preventDefault();
|
|
|
|
// 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 ( !this.options.showLabel ) {
|
|
this._addClass( "ui-button-icon-only" );
|
|
}
|
|
} else if ( icon ) {
|
|
|
|
// If we are updating the icon remove the old icon class
|
|
this._removeClass( this.icon, null, this.options.icon );
|
|
}
|
|
|
|
// 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 {
|
|
|
|
// 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 );
|
|
}
|
|
},
|
|
|
|
_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" );
|
|
}
|
|
},
|
|
|
|
_attachIconSpace: function( iconPosition ) {
|
|
this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
|
|
},
|
|
|
|
_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 === "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() {
|
|
|
|
// 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 widgetsButton = $.ui.button;
|
|
|
|
|
|
|
|
|
|
// This file is deprecated
|
|
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
|
|
|
/*!
|
|
* 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; }
|
|
} );
|
|
|
|
|
|
|
|
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 Spinner 1.12.1
|
|
* http://jqueryui.com
|
|
*
|
|
* Copyright jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*/
|
|
|
|
//>>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 spinnerModifer( fn ) {
|
|
return function() {
|
|
var previous = this.element.val();
|
|
fn.apply( this, arguments );
|
|
this._refresh();
|
|
if ( previous !== this.element.val() ) {
|
|
this._trigger( "change" );
|
|
}
|
|
};
|
|
}
|
|
|
|
$.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",
|
|
up: "ui-icon-triangle-1-n"
|
|
},
|
|
incremental: true,
|
|
max: null,
|
|
min: null,
|
|
numberFormat: null,
|
|
page: 10,
|
|
step: 1,
|
|
|
|
change: null,
|
|
spin: null,
|
|
start: null,
|
|
stop: null
|
|
},
|
|
|
|
_create: function() {
|
|
|
|
// handle string values that need to be parsed
|
|
this._setOption( "max", this.options.max );
|
|
this._setOption( "min", this.options.min );
|
|
this._setOption( "step", this.options.step );
|
|
|
|
// 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 );
|
|
}
|
|
|
|
this._draw();
|
|
this._on( this._events );
|
|
this._refresh();
|
|
|
|
// 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 = this._super();
|
|
var element = this.element;
|
|
|
|
$.each( [ "min", "max", "step" ], function( i, option ) {
|
|
var value = element.attr( option );
|
|
if ( value != null && value.length ) {
|
|
options[ option ] = value;
|
|
}
|
|
} );
|
|
|
|
return options;
|
|
},
|
|
|
|
_events: {
|
|
keydown: function( event ) {
|
|
if ( this._start( event ) && this._keydown( event ) ) {
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
keyup: "_stop",
|
|
focus: function() {
|
|
this.previous = this.element.val();
|
|
},
|
|
blur: function( event ) {
|
|
if ( this.cancelBlur ) {
|
|
delete this.cancelBlur;
|
|
return;
|
|
}
|
|
|
|
this._stop();
|
|
this._refresh();
|
|
if ( this.previous !== this.element.val() ) {
|
|
this._trigger( "change", event );
|
|
}
|
|
},
|
|
mousewheel: function( event, delta ) {
|
|
if ( !delta ) {
|
|
return;
|
|
}
|
|
if ( !this.spinning && !this._start( event ) ) {
|
|
return false;
|
|
}
|
|
|
|
this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
|
|
clearTimeout( this.mousewheelTimer );
|
|
this.mousewheelTimer = this._delay( function() {
|
|
if ( this.spinning ) {
|
|
this._stop( event );
|
|
}
|
|
}, 100 );
|
|
event.preventDefault();
|
|
},
|
|
"mousedown .ui-spinner-button": function( event ) {
|
|
var previous;
|
|
|
|
// We never want the buttons to have focus; whenever the user is
|
|
// interacting with the spinner, the focus should be on the input.
|
|
// 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 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
|
|
this.previous : this.element.val();
|
|
function checkFocus() {
|
|
var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
|
|
if ( !isActive ) {
|
|
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.previous = previous;
|
|
} );
|
|
}
|
|
}
|
|
|
|
// Ensure focus is on (or stays on) the text field
|
|
event.preventDefault();
|
|
checkFocus.call( this );
|
|
|
|
// 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() {
|
|
delete this.cancelBlur;
|
|
checkFocus.call( this );
|
|
} );
|
|
|
|
if ( this._start( event ) === false ) {
|
|
return;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if ( this._start( event ) === false ) {
|
|
return false;
|
|
}
|
|
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"
|
|
},
|
|
|
|
// Support mobile enhanced option and make backcompat more sane
|
|
_enhance: function() {
|
|
this.uiSpinner = this.element
|
|
.attr( "autocomplete", "off" )
|
|
.wrap( "<span>" )
|
|
.parent()
|
|
|
|
// 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 = this.uiSpinner.children( "a" )
|
|
.attr( "tabIndex", -1 )
|
|
.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( this.uiSpinner.height() * 0.5 ) &&
|
|
this.uiSpinner.height() > 0 ) {
|
|
this.uiSpinner.height( this.uiSpinner.height() );
|
|
}
|
|
},
|
|
|
|
_keydown: function( event ) {
|
|
var options = this.options,
|
|
keyCode = $.ui.keyCode;
|
|
|
|
switch ( event.keyCode ) {
|
|
case keyCode.UP:
|
|
this._repeat( null, 1, event );
|
|
return true;
|
|
case keyCode.DOWN:
|
|
this._repeat( null, -1, event );
|
|
return true;
|
|
case keyCode.PAGE_UP:
|
|
this._repeat( null, options.page, event );
|
|
return true;
|
|
case keyCode.PAGE_DOWN:
|
|
this._repeat( null, -options.page, event );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
_start: function( event ) {
|
|
if ( !this.spinning && this._trigger( "start", event ) === false ) {
|
|
return false;
|
|
}
|
|
|
|
if ( !this.counter ) {
|
|
this.counter = 1;
|
|
}
|
|
this.spinning = true;
|
|
return true;
|
|
},
|
|
|
|
_repeat: function( i, steps, event ) {
|
|
i = i || 500;
|
|
|
|
clearTimeout( this.timer );
|
|
this.timer = this._delay( function() {
|
|
this._repeat( 40, steps, event );
|
|
}, i );
|
|
|
|
this._spin( steps * this.options.step, event );
|
|
},
|
|
|
|
_spin: function( step, event ) {
|
|
var value = this.value() || 0;
|
|
|
|
if ( !this.counter ) {
|
|
this.counter = 1;
|
|
}
|
|
|
|
value = this._adjustValue( value + step * this._increment( this.counter ) );
|
|
|
|
if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
|
|
this._value( value );
|
|
this.counter++;
|
|
}
|
|
},
|
|
|
|
_increment: function( i ) {
|
|
var incremental = this.options.incremental;
|
|
|
|
if ( incremental ) {
|
|
return $.isFunction( incremental ) ?
|
|
incremental( i ) :
|
|
Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
|
|
}
|
|
|
|
return 1;
|
|
},
|
|
|
|
_precision: function() {
|
|
var precision = this._precisionOf( this.options.step );
|
|
if ( this.options.min !== null ) {
|
|
precision = Math.max( precision, this._precisionOf( this.options.min ) );
|
|
}
|
|
return precision;
|
|
},
|
|
|
|
_precisionOf: function( num ) {
|
|
var str = num.toString(),
|
|
decimal = str.indexOf( "." );
|
|
return decimal === -1 ? 0 : str.length - decimal - 1;
|
|
},
|
|
|
|
_adjustValue: function( value ) {
|
|
var base, aboveMin,
|
|
options = this.options;
|
|
|
|
// 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;
|
|
|
|
// - rounding is based on 0, so adjust back to our base
|
|
value = base + aboveMin;
|
|
|
|
// Fix precision from bad JS floating point math
|
|
value = parseFloat( value.toFixed( this._precision() ) );
|
|
|
|
// Clamp the value
|
|
if ( options.max !== null && value > options.max ) {
|
|
return options.max;
|
|
}
|
|
if ( options.min !== null && value < options.min ) {
|
|
return options.min;
|
|
}
|
|
|
|
return value;
|
|
},
|
|
|
|
_stop: function( event ) {
|
|
if ( !this.spinning ) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout( this.timer );
|
|
clearTimeout( this.mousewheelTimer );
|
|
this.counter = 0;
|
|
this.spinning = false;
|
|
this._trigger( "stop", event );
|
|
},
|
|
|
|
_setOption: function( key, value ) {
|
|
var prevValue, first, last;
|
|
|
|
if ( key === "culture" || key === "numberFormat" ) {
|
|
prevValue = this._parse( this.element.val() );
|
|
this.options[ key ] = value;
|
|
this.element.val( this._format( prevValue ) );
|
|
return;
|
|
}
|
|
|
|
if ( key === "max" || key === "min" || key === "step" ) {
|
|
if ( typeof value === "string" ) {
|
|
value = this._parse( value );
|
|
}
|
|
}
|
|
if ( key === "icons" ) {
|
|
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 );
|
|
},
|
|
|
|
_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: spinnerModifer( function( options ) {
|
|
this._super( options );
|
|
} ),
|
|
|
|
_parse: function( val ) {
|
|
if ( typeof val === "string" && val !== "" ) {
|
|
val = window.Globalize && this.options.numberFormat ?
|
|
Globalize.parseFloat( val, 10, this.options.culture ) : +val;
|
|
}
|
|
return val === "" || isNaN( val ) ? null : val;
|
|
},
|
|
|
|
_format: function( value ) {
|
|
if ( value === "" ) {
|
|
return "";
|
|
}
|
|
return window.Globalize && this.options.numberFormat ?
|
|
Globalize.format( value, this.options.numberFormat, this.options.culture ) :
|
|
value;
|
|
},
|
|
|
|
_refresh: function() {
|
|
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
|
|
if ( value === null ) {
|
|
return false;
|
|
}
|
|
|
|
// If value gets adjusted, it's invalid
|
|
return value === this._adjustValue( value );
|
|
},
|
|
|
|
// Update the value without triggering change
|
|
_value: function( value, allowAny ) {
|
|
var parsed;
|
|
if ( value !== "" ) {
|
|
parsed = this._parse( value );
|
|
if ( parsed !== null ) {
|
|
if ( !allowAny ) {
|
|
parsed = this._adjustValue( parsed );
|
|
}
|
|
value = this._format( parsed );
|
|
}
|
|
}
|
|
this.element.val( value );
|
|
this._refresh();
|
|
},
|
|
|
|
_destroy: function() {
|
|
this.element
|
|
.prop( "disabled", false )
|
|
.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
|
|
|
|
this.uiSpinner.replaceWith( this.element );
|
|
},
|
|
|
|
stepUp: spinnerModifer( function( steps ) {
|
|
this._stepUp( steps );
|
|
} ),
|
|
_stepUp: function( steps ) {
|
|
if ( this._start() ) {
|
|
this._spin( ( steps || 1 ) * this.options.step );
|
|
this._stop();
|
|
}
|
|
},
|
|
|
|
stepDown: spinnerModifer( function( steps ) {
|
|
this._stepDown( steps );
|
|
} ),
|
|
_stepDown: function( steps ) {
|
|
if ( this._start() ) {
|
|
this._spin( ( steps || 1 ) * -this.options.step );
|
|
this._stop();
|
|
}
|
|
},
|
|
|
|
pageUp: spinnerModifer( function( pages ) {
|
|
this._stepUp( ( 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() );
|
|
}
|
|
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;
|
|
|
|
|
|
|
|
|
|
}));
|