2018-01-16 06:58:15 +01:00
/ * ! j Q u e r y U I - v 1 . 1 1 . 4 - 2 0 1 6 - 0 4 - 1 4
* http : //jqueryui.com
* Includes : core . js , widget . js , mouse . js , position . js , draggable . js , droppable . js , resizable . js , selectable . js , sortable . js , autocomplete . js , datepicker . js , menu . js , tooltip . js , effect . js , effect - bounce . 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 ( $ ) {
/ * !
* 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 ) ;
}
}
}
} ;
/ * !
* jQuery UI Widget 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/jQuery.widget/
* /
var widget _uuid = 0 ,
widget _slice = 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 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 ] ;
name = name . split ( "." ) [ 1 ] ;
fullName = namespace + "-" + name ;
if ( ! prototype ) {
prototype = base ;
base = $ . Widget ;
}
// 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 ( ) {
var _super = function ( ) {
return base . prototype [ prop ] . apply ( this , arguments ) ;
} ,
_superApply = function ( args ) {
return base . prototype [ prop ] . apply ( this , args ) ;
} ;
return function ( ) {
var _ _super = this . _super ,
_ _superApply = this . _superApply ,
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 = widget _slice . call ( arguments , 1 ) ,
inputIndex = 0 ,
inputLength = input . length ,
key ,
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" ,
args = widget _slice . call ( arguments , 1 ) ,
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 ;
}
} ) ;
} 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 : {
disabled : false ,
// callbacks
create : null
} ,
_createWidget : function ( options , element ) {
element = $ ( element || this . defaultElement || this ) [ 0 ] ;
this . element = $ ( element ) ;
this . uuid = widget _uuid ++ ;
this . eventNamespace = "." + this . widgetName + this . uuid ;
this . bindings = $ ( ) ;
this . hoverable = $ ( ) ;
this . focusable = $ ( ) ;
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 ( ) ;
this . _trigger ( "create" , null , this . _getCreateEventData ( ) ) ;
this . _init ( ) ;
} ,
_getCreateOptions : $ . noop ,
_getCreateEventData : $ . noop ,
_create : $ . noop ,
_init : $ . noop ,
destroy : function ( ) {
this . _destroy ( ) ;
// 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 ) ) ;
this . widget ( )
. unbind ( this . eventNamespace )
. removeAttr ( "aria-disabled" )
. removeClass (
this . widgetFullName + "-disabled " +
"ui-state-disabled" ) ;
// clean up events and states
this . bindings . unbind ( this . eventNamespace ) ;
this . hoverable . removeClass ( "ui-state-hover" ) ;
this . focusable . removeClass ( "ui-state-focus" ) ;
} ,
_destroy : $ . noop ,
widget : function ( ) {
return this . element ;
} ,
option : function ( key , value ) {
var options = key ,
parts ,
curOption ,
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 ) {
this . options [ key ] = value ;
if ( key === "disabled" ) {
this . widget ( )
. toggleClass ( this . widgetFullName + "-disabled" , ! ! 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 ;
} ,
enable : function ( ) {
return this . _setOptions ( { disabled : false } ) ;
} ,
disable : function ( ) {
return this . _setOptions ( { disabled : true } ) ;
} ,
_on : function ( suppressDisabledCheck , element , handlers ) {
var delegateElement ,
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*(.*)$/ ) ,
eventName = match [ 1 ] + instance . eventNamespace ,
selector = match [ 2 ] ;
if ( selector ) {
delegateElement . delegate ( selector , eventName , handlerProxy ) ;
} else {
element . bind ( eventName , handlerProxy ) ;
}
} ) ;
} ,
_off : function ( element , eventName ) {
eventName = ( eventName || "" ) . split ( " " ) . join ( this . eventNamespace + " " ) +
this . eventNamespace ;
element . unbind ( eventName ) . undelegate ( 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 ) {
$ ( event . currentTarget ) . addClass ( "ui-state-hover" ) ;
} ,
mouseleave : function ( event ) {
$ ( event . currentTarget ) . removeClass ( "ui-state-hover" ) ;
}
} ) ;
} ,
_focusable : function ( element ) {
this . focusable = this . focusable . add ( element ) ;
this . _on ( element , {
focusin : function ( event ) {
$ ( event . currentTarget ) . addClass ( "ui-state-focus" ) ;
} ,
focusout : function ( event ) {
$ ( event . currentTarget ) . removeClass ( "ui-state-focus" ) ;
}
} ) ;
} ,
_trigger : function ( type , event , data ) {
var prop , orig ,
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 ,
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 ;
/ * !
* 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
* http : //jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license .
* http : //jquery.org/license
*
* http : //api.jqueryui.com/position/
* /
( function ( ) {
$ . ui = $ . ui || { } ;
var cachedScrollbarWidth , supportsOffsetFractions ,
max = Math . max ,
abs = Math . abs ,
round = Math . round ,
rhorizontal = /left|center|right/ ,
rvertical = /top|center|bottom/ ,
roffset = /[\+\-]\d+(\.[\d]+)?%?/ ,
rposition = /^\w+/ ,
rpercent = /%$/ ,
_position = $ . fn . position ;
function getOffsets ( offsets , width , height ) {
return [
parseFloat ( offsets [ 0 ] ) * ( rpercent . test ( offsets [ 0 ] ) ? width / 100 : 1 ) ,
parseFloat ( offsets [ 1 ] ) * ( rpercent . test ( offsets [ 1 ] ) ? height / 100 : 1 )
] ;
}
function parseCss ( element , property ) {
return parseInt ( $ . css ( element , property ) , 10 ) || 0 ;
}
function getDimensions ( elem ) {
var raw = elem [ 0 ] ;
if ( raw . nodeType === 9 ) {
return {
width : elem . width ( ) ,
height : elem . height ( ) ,
offset : { top : 0 , left : 0 }
} ;
}
if ( $ . isWindow ( raw ) ) {
return {
width : elem . width ( ) ,
height : elem . height ( ) ,
offset : { top : elem . scrollTop ( ) , left : elem . scrollLeft ( ) }
} ;
}
if ( raw . preventDefault ) {
return {
width : 0 ,
height : 0 ,
offset : { top : raw . pageY , left : raw . pageX }
} ;
}
return {
width : elem . outerWidth ( ) ,
height : elem . outerHeight ( ) ,
offset : elem . offset ( )
} ;
}
$ . position = {
scrollbarWidth : function ( ) {
if ( cachedScrollbarWidth !== undefined ) {
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 ] ;
$ ( "body" ) . append ( div ) ;
w1 = innerDiv . offsetWidth ;
div . css ( "overflow" , "scroll" ) ;
w2 = innerDiv . offsetWidth ;
if ( w1 === w2 ) {
w2 = div [ 0 ] . clientWidth ;
}
div . remove ( ) ;
return ( cachedScrollbarWidth = w1 - w2 ) ;
} ,
getScrollInfo : function ( within ) {
var overflowX = within . isWindow || within . isDocument ? "" :
within . element . css ( "overflow-x" ) ,
overflowY = within . isWindow || within . isDocument ? "" :
within . element . css ( "overflow-y" ) ,
hasOverflowX = overflowX === "scroll" ||
( overflowX === "auto" && within . width < within . element [ 0 ] . scrollWidth ) ,
hasOverflowY = overflowY === "scroll" ||
( overflowY === "auto" && within . height < within . element [ 0 ] . scrollHeight ) ;
return {
width : hasOverflowY ? $ . position . scrollbarWidth ( ) : 0 ,
height : hasOverflowX ? $ . position . scrollbarWidth ( ) : 0
} ;
} ,
getWithinInfo : function ( element ) {
var withinElement = $ ( element || window ) ,
isWindow = $ . isWindow ( withinElement [ 0 ] ) ,
isDocument = ! ! withinElement [ 0 ] && withinElement [ 0 ] . nodeType === 9 ;
return {
element : withinElement ,
isWindow : isWindow ,
isDocument : isDocument ,
offset : withinElement . 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 ( )
} ;
}
} ;
$ . fn . position = function ( options ) {
if ( ! options || ! options . of ) {
return _position . apply ( this , arguments ) ;
}
// make a copy, we don't want to modify arguments
options = $ . extend ( { } , options ) ;
var atOffset , targetWidth , targetHeight , targetOffset , basePosition , dimensions ,
target = $ ( options . of ) ,
within = $ . position . getWithinInfo ( options . within ) ,
scrollInfo = $ . position . getScrollInfo ( within ) ,
collision = ( options . collision || "flip" ) . split ( " " ) ,
offsets = { } ;
dimensions = getDimensions ( target ) ;
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
basePosition = $ . extend ( { } , targetOffset ) ;
// 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 ) {
pos = rhorizontal . test ( pos [ 0 ] ) ?
pos . concat ( [ "center" ] ) :
rvertical . test ( pos [ 0 ] ) ?
[ "center" ] . concat ( pos ) :
[ "center" , "center" ] ;
}
pos [ 0 ] = rhorizontal . test ( pos [ 0 ] ) ? pos [ 0 ] : "center" ;
pos [ 1 ] = rvertical . test ( pos [ 1 ] ) ? pos [ 1 ] : "center" ;
// calculate offsets
horizontalOffset = roffset . exec ( pos [ 0 ] ) ;
verticalOffset = roffset . exec ( pos [ 1 ] ) ;
offsets [ this ] = [
horizontalOffset ? horizontalOffset [ 0 ] : 0 ,
verticalOffset ? verticalOffset [ 0 ] : 0
] ;
// reduce to just the positions without the offsets
options [ this ] = [
rposition . exec ( pos [ 0 ] ) [ 0 ] ,
rposition . exec ( pos [ 1 ] ) [ 0 ]
] ;
} ) ;
// normalize collision option
if ( collision . length === 1 ) {
collision [ 1 ] = collision [ 0 ] ;
}
if ( options . at [ 0 ] === "right" ) {
basePosition . left += targetWidth ;
} else if ( options . at [ 0 ] === "center" ) {
basePosition . left += targetWidth / 2 ;
}
if ( options . at [ 1 ] === "bottom" ) {
basePosition . top += targetHeight ;
} else if ( options . at [ 1 ] === "center" ) {
basePosition . top += targetHeight / 2 ;
}
atOffset = getOffsets ( offsets . at , targetWidth , targetHeight ) ;
basePosition . left += atOffset [ 0 ] ;
basePosition . top += atOffset [ 1 ] ;
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 ,
position = $ . extend ( { } , basePosition ) ,
myOffset = getOffsets ( offsets . my , elem . outerWidth ( ) , elem . outerHeight ( ) ) ;
if ( options . my [ 0 ] === "right" ) {
position . left -= elemWidth ;
} else if ( options . my [ 0 ] === "center" ) {
position . left -= elemWidth / 2 ;
}
if ( options . my [ 1 ] === "bottom" ) {
position . top -= elemHeight ;
} else if ( options . my [ 1 ] === "center" ) {
position . top -= elemHeight / 2 ;
}
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
} ;
$ . each ( [ "left" , "top" ] , function ( i , dir ) {
if ( $ . ui . position [ collision [ i ] ] ) {
$ . ui . position [ collision [ i ] ] [ dir ] ( position , {
targetWidth : targetWidth ,
targetHeight : targetHeight ,
elemWidth : elemWidth ,
elemHeight : elemHeight ,
collisionPosition : collisionPosition ,
collisionWidth : collisionWidth ,
collisionHeight : collisionHeight ,
offset : [ atOffset [ 0 ] + myOffset [ 0 ] , atOffset [ 1 ] + myOffset [ 1 ] ] ,
my : options . my ,
at : options . at ,
within : within ,
elem : elem
} ) ;
}
} ) ;
if ( options . using ) {
// adds feedback as second argument to using callback, if present
using = function ( props ) {
var left = targetOffset . left - position . left ,
right = left + targetWidth - elemWidth ,
top = targetOffset . top - position . top ,
bottom = top + targetHeight - elemHeight ,
feedback = {
target : {
element : target ,
left : targetOffset . left ,
top : targetOffset . top ,
width : targetWidth ,
height : targetHeight
} ,
element : {
element : elem ,
left : position . left ,
top : position . top ,
width : elemWidth ,
height : elemHeight
} ,
horizontal : right < 0 ? "left" : left > 0 ? "right" : "center" ,
vertical : bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
} ;
if ( targetWidth < elemWidth && abs ( left + right ) < targetWidth ) {
feedback . horizontal = "center" ;
}
if ( targetHeight < elemHeight && abs ( top + bottom ) < targetHeight ) {
feedback . vertical = "middle" ;
}
if ( max ( abs ( left ) , abs ( right ) ) > max ( abs ( top ) , abs ( bottom ) ) ) {
feedback . important = "horizontal" ;
} else {
feedback . important = "vertical" ;
}
options . using . call ( this , props , feedback ) ;
} ;
}
elem . offset ( $ . extend ( position , { using : using } ) ) ;
} ) ;
} ;
$ . ui . position = {
fit : {
left : function ( position , data ) {
var within = data . within ,
withinOffset = within . isWindow ? within . scrollLeft : within . offset . left ,
outerWidth = within . width ,
collisionPosLeft = position . left - data . collisionPosition . marginLeft ,
overLeft = withinOffset - collisionPosLeft ,
overRight = collisionPosLeft + data . collisionWidth - outerWidth - withinOffset ,
newOverRight ;
// element is wider than within
if ( data . collisionWidth > outerWidth ) {
// element is initially over the left side of within
if ( overLeft > 0 && overRight <= 0 ) {
newOverRight = position . left + overLeft + data . collisionWidth - outerWidth - withinOffset ;
position . left += overLeft - newOverRight ;
// 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
} else {
if ( overLeft > overRight ) {
position . left = withinOffset + outerWidth - data . collisionWidth ;
} else {
position . left = withinOffset ;
}
}
// too far left -> align with left edge
} else if ( overLeft > 0 ) {
position . left += overLeft ;
// too far right -> align with right edge
} else if ( overRight > 0 ) {
position . left -= overRight ;
// adjust based on position and margin
} else {
position . left = max ( position . left - collisionPosLeft , position . left ) ;
}
} ,
top : function ( position , data ) {
var within = data . within ,
withinOffset = within . isWindow ? within . scrollTop : within . offset . top ,
outerHeight = data . within . height ,
collisionPosTop = position . top - data . collisionPosition . marginTop ,
overTop = withinOffset - collisionPosTop ,
overBottom = collisionPosTop + data . collisionHeight - outerHeight - withinOffset ,
newOverBottom ;
// element is taller than within
if ( data . collisionHeight > outerHeight ) {
// element is initially over the top of within
if ( overTop > 0 && overBottom <= 0 ) {
newOverBottom = position . top + overTop + data . collisionHeight - outerHeight - withinOffset ;
position . top += overTop - newOverBottom ;
// 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
} else {
if ( overTop > overBottom ) {
position . top = withinOffset + outerHeight - data . collisionHeight ;
} else {
position . top = withinOffset ;
}
}
// too far up -> align with top
} else if ( overTop > 0 ) {
position . top += overTop ;
// too far down -> align with bottom edge
} else if ( overBottom > 0 ) {
position . top -= overBottom ;
// adjust based on position and margin
} else {
position . top = max ( position . top - collisionPosTop , position . top ) ;
}
}
} ,
flip : {
left : function ( position , data ) {
var within = data . within ,
withinOffset = within . offset . left + within . scrollLeft ,
outerWidth = within . width ,
offsetLeft = within . isWindow ? within . scrollLeft : within . offset . left ,
collisionPosLeft = position . left - data . collisionPosition . marginLeft ,
overLeft = collisionPosLeft - offsetLeft ,
overRight = collisionPosLeft + data . collisionWidth - outerWidth - offsetLeft ,
myOffset = data . my [ 0 ] === "left" ?
- data . elemWidth :
data . my [ 0 ] === "right" ?
data . elemWidth :
0 ,
atOffset = data . at [ 0 ] === "left" ?
data . targetWidth :
data . at [ 0 ] === "right" ?
- data . targetWidth :
0 ,
offset = - 2 * data . offset [ 0 ] ,
newOverRight ,
newOverLeft ;
if ( overLeft < 0 ) {
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 ;
if ( newOverLeft > 0 || abs ( newOverLeft ) < overRight ) {
position . left += myOffset + atOffset + offset ;
}
}
} ,
top : function ( position , data ) {
var within = data . within ,
withinOffset = within . offset . top + within . scrollTop ,
outerHeight = within . height ,
offsetTop = within . isWindow ? within . scrollTop : within . offset . top ,
collisionPosTop = position . top - data . collisionPosition . marginTop ,
overTop = collisionPosTop - offsetTop ,
overBottom = collisionPosTop + data . collisionHeight - outerHeight - offsetTop ,
top = data . my [ 1 ] === "top" ,
myOffset = top ?
- data . elemHeight :
data . my [ 1 ] === "bottom" ?
data . elemHeight :
0 ,
atOffset = data . at [ 1 ] === "top" ?
data . targetHeight :
data . at [ 1 ] === "bottom" ?
- data . targetHeight :
0 ,
offset = - 2 * data . offset [ 1 ] ,
newOverTop ,
newOverBottom ;
if ( overTop < 0 ) {
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 ;
if ( newOverTop > 0 || abs ( newOverTop ) < overBottom ) {
position . top += myOffset + atOffset + offset ;
}
}
}
} ,
flipfit : {
left : function ( ) {
$ . ui . position . flip . left . apply ( this , arguments ) ;
$ . ui . position . fit . left . apply ( this , arguments ) ;
} ,
top : function ( ) {
$ . ui . position . flip . top . apply ( this , arguments ) ;
$ . ui . position . fit . top . apply ( this , arguments ) ;
}
}
} ;
// 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"
} ;
if ( body ) {
$ . extend ( testElementStyle , {
position : "absolute" ,
left : "-1000px" ,
top : "-1000px"
} ) ;
}
for ( i in testElementStyle ) {
testElement . style [ i ] = testElementStyle [ i ] ;
}
testElement . appendChild ( div ) ;
testElementParent = body || document . documentElement ;
testElementParent . insertBefore ( testElement , testElementParent . firstChild ) ;
div . style . cssText = "position: absolute; left: 10.7432222px;" ;
offsetLeft = $ ( div ) . offset ( ) . left ;
supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11 ;
testElement . innerHTML = "" ;
testElementParent . removeChild ( testElement ) ;
} ) ( ) ;
} ) ( ) ;
var position = $ . ui . position ;
/ * !
* jQuery UI Draggable 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/draggable/
* /
$ . widget ( "ui.draggable" , $ . ui . mouse , {
version : "1.11.4" ,
widgetEventPrefix : "drag" ,
options : {
addClasses : true ,
appendTo : "parent" ,
axis : false ,
connectToSortable : false ,
containment : false ,
cursor : "auto" ,
cursorAt : false ,
grid : false ,
handle : false ,
helper : "original" ,
iframeFix : false ,
opacity : false ,
refreshPositions : false ,
revert : false ,
revertDuration : 500 ,
scope : "default" ,
scroll : true ,
scrollSensitivity : 20 ,
scrollSpeed : 20 ,
snap : false ,
snapMode : "both" ,
snapTolerance : 20 ,
stack : false ,
zIndex : false ,
// callbacks
drag : null ,
start : null ,
stop : null
} ,
_create : function ( ) {
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" ) ;
}
this . _setHandleClassName ( ) ;
this . _mouseInit ( ) ;
} ,
_setOption : function ( key , value ) {
this . _super ( key , value ) ;
if ( key === "handle" ) {
this . _removeHandleClassName ( ) ;
this . _setHandleClassName ( ) ;
}
} ,
_destroy : function ( ) {
if ( ( this . helper || this . element ) . is ( ".ui-draggable-dragging" ) ) {
this . destroyOnClear = true ;
return ;
}
this . element . removeClass ( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ) ;
this . _removeHandleClassName ( ) ;
this . _mouseDestroy ( ) ;
} ,
_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 ) {
return false ;
}
//Quit if we're not on a valid handle
this . handle = this . _getHandle ( event ) ;
if ( ! this . handle ) {
return false ;
}
this . _blockFrames ( o . iframeFix === true ? "iframe" : o . iframeFix ) ;
return true ;
} ,
_blockFrames : function ( selector ) {
this . iframeBlocks = this . document . find ( selector ) . map ( function ( ) {
var iframe = $ ( this ) ;
return $ ( "<div>" )
. css ( "position" , "absolute" )
. appendTo ( iframe . parent ( ) )
. outerWidth ( iframe . outerWidth ( ) )
. outerHeight ( iframe . outerHeight ( ) )
. offset ( iframe . offset ( ) ) [ 0 ] ;
} ) ;
} ,
_unblockFrames : function ( ) {
if ( this . iframeBlocks ) {
this . iframeBlocks . remove ( ) ;
delete this . iframeBlocks ;
}
} ,
_blurActiveElement : function ( event ) {
var document = this . document [ 0 ] ;
// Only need to blur if the event occurred on the draggable itself, see #10527
if ( ! this . handleElement . is ( event . target ) ) {
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 ) { }
} ,
_mouseStart : function ( event ) {
var o = this . options ;
//Create and append the visible helper
this . helper = this . _createHelper ( event ) ;
this . helper . addClass ( "ui-draggable-dragging" ) ;
//Cache the helper size
this . _cacheHelperProportions ( ) ;
//If ddmanager is used for droppables, set the global draggable
if ( $ . ui . ddmanager ) {
$ . ui . ddmanager . current = this ;
}
/ *
* - Position generation -
* This block generates everything position related - it ' s the core of draggables .
* /
//Cache the margins of the original element
this . _cacheMargins ( ) ;
//Store the helper's css position
this . cssPosition = this . helper . css ( "position" ) ;
this . scrollParent = this . helper . scrollParent ( true ) ;
this . offsetParent = this . helper . offsetParent ( ) ;
this . hasFixedAncestor = this . helper . parents ( ) . filter ( function ( ) {
return $ ( this ) . css ( "position" ) === "fixed" ;
} ) . length > 0 ;
//The element's absolute position on the page minus margins
this . positionAbs = this . element . offset ( ) ;
this . _refreshOffsets ( event ) ;
//Generate the original position
this . originalPosition = this . position = this . _generatePosition ( event , false ) ;
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 ) ) ;
//Set a containment if given in the options
this . _setContainment ( ) ;
//Trigger event + callbacks
if ( this . _trigger ( "start" , event ) === false ) {
this . _clear ( ) ;
return false ;
}
//Recache the helper size
this . _cacheHelperProportions ( ) ;
//Prepare the droppable offsets
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 ( ) ;
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 ( $ . ui . ddmanager ) {
$ . ui . ddmanager . dragStart ( this , event ) ;
}
return true ;
} ,
_refreshOffsets : function ( event ) {
this . offset = {
top : this . positionAbs . top - this . margins . top ,
left : this . positionAbs . left - this . margins . left ,
scroll : false ,
parent : this . _getParentOffset ( ) ,
relative : this . _getRelativeOffset ( )
} ;
this . offset . click = {
left : event . pageX - this . offset . left ,
top : event . pageY - this . offset . top
} ;
} ,
_mouseDrag : function ( event , noPropagation ) {
// reset any necessary cached properties (see #5009)
if ( this . hasFixedAncestor ) {
this . offset . parent = this . _getParentOffset ( ) ;
}
//Compute the helpers position
this . position = this . _generatePosition ( event , true ) ;
this . positionAbs = this . _convertPositionTo ( "absolute" ) ;
//Call plugins and callbacks and use the resulting position if something is returned
if ( ! noPropagation ) {
var ui = this . _uiHash ( ) ;
if ( this . _trigger ( "drag" , event , ui ) === false ) {
this . _mouseUp ( { } ) ;
return false ;
}
this . position = ui . position ;
}
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 ) ;
}
return false ;
} ,
_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 a drop comes from outside (a sortable)
if ( this . dropped ) {
dropped = this . dropped ;
this . dropped = false ;
}
if ( ( this . options . revert === "invalid" && ! dropped ) || ( this . options . revert === "valid" && dropped ) || this . options . revert === true || ( $ . isFunction ( this . options . revert ) && this . options . revert . call ( this . element , dropped ) ) ) {
$ ( 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 ) {
this . _clear ( ) ;
}
}
return false ;
} ,
_mouseUp : function ( event ) {
this . _unblockFrames ( ) ;
//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
if ( $ . ui . ddmanager ) {
$ . 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 ( ) ;
}
return $ . ui . mouse . prototype . _mouseUp . call ( this , event ) ;
} ,
cancel : function ( ) {
if ( this . helper . is ( ".ui-draggable-dragging" ) ) {
this . _mouseUp ( { } ) ;
} else {
this . _clear ( ) ;
}
return this ;
} ,
_getHandle : function ( event ) {
return this . options . handle ?
! ! $ ( event . target ) . closest ( this . element . find ( this . options . handle ) ) . length :
true ;
} ,
_setHandleClassName : function ( ) {
this . handleElement = this . options . handle ?
this . element . find ( this . options . handle ) : this . element ;
this . handleElement . addClass ( "ui-draggable-handle" ) ;
} ,
_removeHandleClassName : function ( ) {
this . handleElement . removeClass ( "ui-draggable-handle" ) ;
} ,
_createHelper : function ( event ) {
var o = this . options ,
helperIsFunction = $ . isFunction ( o . helper ) ,
helper = helperIsFunction ?
$ ( o . helper . apply ( this . element [ 0 ] , [ event ] ) ) :
( o . helper === "clone" ?
this . element . clone ( ) . removeAttr ( "id" ) :
this . element ) ;
if ( ! helper . parents ( "body" ) . length ) {
helper . appendTo ( ( o . appendTo === "parent" ? this . element [ 0 ] . parentNode : o . appendTo ) ) ;
}
// 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" ) ;
}
return helper ;
} ,
_setPositionRelative : function ( ) {
if ( ! ( /^(?:r|a|f)/ ) . test ( this . element . css ( "position" ) ) ) {
this . element [ 0 ] . style . position = "relative" ;
}
} ,
_adjustOffsetFromHelper : function ( obj ) {
if ( typeof obj === "string" ) {
obj = obj . split ( " " ) ;
}
if ( $ . isArray ( obj ) ) {
obj = { left : + obj [ 0 ] , top : + obj [ 1 ] || 0 } ;
}
if ( "left" in obj ) {
this . offset . click . left = obj . left + this . margins . left ;
}
if ( "right" in obj ) {
this . offset . click . left = this . helperProportions . width - obj . right + this . margins . left ;
}
if ( "top" in obj ) {
this . offset . click . top = obj . top + this . margins . top ;
}
if ( "bottom" in obj ) {
this . offset . click . top = this . helperProportions . height - obj . bottom + this . margins . top ;
}
} ,
_isRootNode : function ( element ) {
return ( /(html|body)/i ) . test ( element . tagName ) || element === this . document [ 0 ] ;
} ,
_getParentOffset : function ( ) {
//Get the offsetParent and cache its position
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 ] ) ) {
po . left += this . scrollParent . scrollLeft ( ) ;
po . top += this . scrollParent . scrollTop ( ) ;
}
if ( this . _isRootNode ( this . offsetParent [ 0 ] ) ) {
po = { top : 0 , left : 0 } ;
}
return {
top : po . top + ( parseInt ( this . offsetParent . css ( "borderTopWidth" ) , 10 ) || 0 ) ,
left : po . left + ( parseInt ( this . offsetParent . css ( "borderLeftWidth" ) , 10 ) || 0 )
} ;
} ,
_getRelativeOffset : function ( ) {
if ( this . cssPosition !== "relative" ) {
return { top : 0 , left : 0 } ;
}
var p = this . element . position ( ) ,
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 )
} ;
} ,
_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 )
} ;
} ,
_cacheHelperProportions : function ( ) {
this . helperProportions = {
width : this . helper . outerWidth ( ) ,
height : this . helper . outerHeight ( )
} ;
} ,
_setContainment : function ( ) {
var isUserScrollable , c , ce ,
o = this . options ,
document = this . document [ 0 ] ;
this . relativeContainer = null ;
if ( ! o . containment ) {
this . containment = null ;
return ;
}
if ( o . containment === "window" ) {
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
] ;
return ;
}
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
] ;
return ;
}
if ( o . containment . constructor === Array ) {
this . containment = o . containment ;
return ;
}
if ( o . containment === "parent" ) {
o . containment = this . helper [ 0 ] . parentNode ;
}
c = $ ( o . containment ) ;
ce = c [ 0 ] ;
if ( ! ce ) {
return ;
}
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 ) ,
( isUserScrollable ? Math . max ( ce . scrollWidth , ce . offsetWidth ) : ce . offsetWidth ) -
( parseInt ( c . css ( "borderRightWidth" ) , 10 ) || 0 ) -
( parseInt ( c . css ( "paddingRight" ) , 10 ) || 0 ) -
this . helperProportions . width -
this . margins . left -
this . margins . right ,
( isUserScrollable ? Math . max ( ce . scrollHeight , ce . offsetHeight ) : ce . offsetHeight ) -
( parseInt ( c . css ( "borderBottomWidth" ) , 10 ) || 0 ) -
( parseInt ( c . css ( "paddingBottom" ) , 10 ) || 0 ) -
this . helperProportions . height -
this . margins . top -
this . margins . bottom
] ;
this . relativeContainer = c ;
} ,
_convertPositionTo : function ( d , pos ) {
if ( ! pos ) {
pos = this . position ;
}
var mod = d === "absolute" ? 1 : - 1 ,
scrollIsRootNode = this . _isRootNode ( this . scrollParent [ 0 ] ) ;
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 )
) ,
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 )
)
} ;
} ,
_generatePosition : function ( event , constrainPosition ) {
var containment , co , top , left ,
o = this . options ,
scrollIsRootNode = this . _isRootNode ( this . scrollParent [ 0 ] ) ,
pageX = event . pageX ,
pageY = event . pageY ;
// Cache the scroll
if ( ! scrollIsRootNode || ! this . offset . scroll ) {
this . offset . scroll = {
top : this . scrollParent . scrollTop ( ) ,
left : this . scrollParent . scrollLeft ( )
} ;
}
/ *
* - Position constraining -
* Constrain the position to a mix of grid , containment .
* /
// If we are not dragging yet, we won't check for options
if ( constrainPosition ) {
if ( this . containment ) {
if ( this . relativeContainer ) {
co = this . relativeContainer . offset ( ) ;
containment = [
this . containment [ 0 ] + co . left ,
this . containment [ 1 ] + co . top ,
this . containment [ 2 ] + co . left ,
this . containment [ 3 ] + co . top
] ;
} else {
containment = this . containment ;
}
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 . 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 ( 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 ;
}
if ( o . axis === "y" ) {
pageX = this . originalPageX ;
}
if ( o . axis === "x" ) {
pageY = this . originalPageY ;
}
}
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 ) )
) ,
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 ) )
)
} ;
} ,
_clear : function ( ) {
this . helper . removeClass ( "ui-draggable-dragging" ) ;
if ( this . helper [ 0 ] !== this . element [ 0 ] && ! this . cancelHelperRemoval ) {
this . helper . remove ( ) ;
}
this . helper = null ;
this . cancelHelperRemoval = false ;
if ( this . destroyOnClear ) {
this . destroy ( ) ;
}
} ,
_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 ) {
ui = ui || this . _uiHash ( ) ;
$ . ui . plugin . call ( this , type , [ event , ui , this ] , true ) ;
// Absolute position and offset (see #6884 ) have to be recalculated after plugins
if ( /^(drag|start|stop)/ . test ( type ) ) {
this . positionAbs = this . _convertPositionTo ( "absolute" ) ;
ui . offset = this . positionAbs ;
}
return $ . Widget . prototype . _trigger . call ( this , type , event , ui ) ;
} ,
plugins : { } ,
_uiHash : function ( ) {
return {
helper : this . helper ,
position : this . position ,
originalPosition : this . originalPosition ,
offset : this . positionAbs
} ;
}
} ) ;
$ . ui . plugin . add ( "draggable" , "connectToSortable" , {
start : function ( event , ui , draggable ) {
var uiSortable = $ . extend ( { } , ui , {
item : draggable . element
} ) ;
draggable . sortables = [ ] ;
$ ( 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
// 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 ) ;
}
} ) ;
} ,
stop : function ( event , ui , draggable ) {
var uiSortable = $ . extend ( { } , ui , {
item : draggable . element
} ) ;
draggable . cancelHelperRemoval = false ;
$ . each ( draggable . sortables , function ( ) {
var sortable = this ;
if ( sortable . isOver ) {
sortable . isOver = 0 ;
// Allow this sortable to handle removing the helper
draggable . cancelHelperRemoval = true ;
sortable . cancelHelperRemoval = false ;
// Use _storedCSS To restore properties in the sortable,
// as this also handles revert (#9675) since the draggable
// may have modified them in unexpected ways (#8809)
sortable . _storedCSS = {
position : sortable . placeholder . css ( "position" ) ,
top : sortable . placeholder . css ( "top" ) ,
left : sortable . placeholder . css ( "left" )
} ;
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.
sortable . cancelHelperRemoval = true ;
sortable . _trigger ( "deactivate" , event , uiSortable ) ;
}
} ) ;
} ,
drag : function ( event , ui , draggable ) {
$ . each ( draggable . sortables , function ( ) {
var innermostIntersecting = false ,
sortable = this ;
// Copy over variables that sortable's _intersectsWith uses
sortable . positionAbs = draggable . positionAbs ;
sortable . helperProportions = draggable . helperProportions ;
sortable . offset . click = draggable . offset . click ;
if ( sortable . _intersectsWith ( sortable . containerCache ) ) {
innermostIntersecting = true ;
$ . each ( draggable . sortables , function ( ) {
// Copy over variables that sortable's _intersectsWith uses
this . positionAbs = draggable . positionAbs ;
this . helperProportions = draggable . helperProportions ;
this . offset . click = draggable . offset . click ;
if ( this !== sortable &&
this . _intersectsWith ( this . containerCache ) &&
$ . contains ( sortable . element [ 0 ] , this . element [ 0 ] ) ) {
innermostIntersecting = false ;
}
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 ) {
sortable . isOver = 1 ;
// Store draggable's parent in case we need to reappend to it later.
draggable . _parent = ui . helper . parent ( ) ;
sortable . currentItem = ui . helper
. appendTo ( sortable . element )
. data ( "ui-sortable-item" , true ) ;
// Store helper option to later restore it
sortable . options . _helper = sortable . options . helper ;
sortable . options . helper = function ( ) {
return ui . helper [ 0 ] ;
} ;
// Fire the start events of the sortable with our passed browser event,
// and our own helper (so it doesn't create a new one)
event . target = sortable . currentItem [ 0 ] ;
sortable . _mouseCapture ( event , true ) ;
sortable . _mouseStart ( event , true , true ) ;
// Because the browser event is way off the new appended portlet,
// modify necessary variables to reflect the changes
sortable . offset . click . top = draggable . offset . click . top ;
sortable . offset . click . left = draggable . offset . click . left ;
sortable . offset . parent . left -= draggable . offset . parent . left -
sortable . offset . parent . left ;
sortable . offset . parent . top -= draggable . offset . parent . top -
sortable . offset . parent . top ;
draggable . _trigger ( "toSortable" , event ) ;
// Inform draggable that the helper is in a valid drop zone,
// used solely in the revert option to handle "valid/invalid".
draggable . dropped = sortable . element ;
// Need to refreshPositions of all sortables in the case that
// 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)
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.
if ( sortable . isOver ) {
sortable . isOver = 0 ;
sortable . cancelHelperRemoval = true ;
// Calling sortable's mouseStop would trigger a revert,
// so revert must be temporarily false until after mouseStop is called.
sortable . options . _revert = sortable . options . revert ;
sortable . options . revert = false ;
sortable . _trigger ( "out" , event , sortable . _uiHash ( sortable ) ) ;
sortable . _mouseStop ( event , true ) ;
// 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 ;
if ( sortable . placeholder ) {
sortable . placeholder . remove ( ) ;
}
// Restore and recalculate the draggable's offset considering the sortable
// may have modified them in unexpected ways. (#8809, #10669)
ui . helper . appendTo ( draggable . _parent ) ;
draggable . _refreshOffsets ( event ) ;
ui . position = draggable . _generatePosition ( event , true ) ;
draggable . _trigger ( "fromSortable" , event ) ;
// Inform draggable that the helper is no longer in a valid drop zone
draggable . dropped = false ;
// Need to refreshPositions of all sortables just in case removing
// from one sortable changes the location of other sortables (#9675)
$ . each ( draggable . sortables , function ( ) {
this . refreshPositions ( ) ;
} ) ;
}
}
} ) ;
}
} ) ;
$ . 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" ) ;
}
t . css ( "cursor" , o . cursor ) ;
} ,
stop : function ( event , ui , instance ) {
var o = instance . options ;
if ( o . _cursor ) {
$ ( "body" ) . css ( "cursor" , o . _cursor ) ;
}
}
} ) ;
$ . 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" ) ;
}
t . css ( "opacity" , o . opacity ) ;
} ,
stop : function ( event , ui , instance ) {
var o = instance . options ;
if ( o . _opacity ) {
$ ( ui . helper ) . css ( "opacity" , o . _opacity ) ;
}
}
} ) ;
$ . 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" ) {
i . overflowOffset = i . scrollParentNotHidden . offset ( ) ;
}
} ,
drag : function ( event , ui , i ) {
var o = i . options ,
scrolled = false ,
scrollParent = i . scrollParentNotHidden [ 0 ] ,
document = i . document [ 0 ] ;
if ( scrollParent !== document && scrollParent . tagName !== "HTML" ) {
if ( ! o . axis || o . axis !== "x" ) {
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 ;
}
}
if ( ! o . axis || o . axis !== "y" ) {
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 ;
}
}
} 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 !== "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 ) ;
}
}
} ) ;
$ . 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
} ) ;
}
} ) ;
} ,
drag : function ( event , ui , inst ) {
var ts , bs , ls , rs , l , r , t , b , i , first ,
o = inst . options ,
d = o . snapTolerance ,
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 } ) ) ) ;
}
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 ( bs ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : b , left : 0 } ) . top ;
}
if ( ls ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l - inst . helperProportions . width } ) . left ;
}
if ( rs ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r } ) . left ;
}
}
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 ( bs ) {
ui . position . top = inst . _convertPositionTo ( "relative" , { top : b - inst . helperProportions . height , left : 0 } ) . top ;
}
if ( ls ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : l } ) . left ;
}
if ( rs ) {
ui . position . left = inst . _convertPositionTo ( "relative" , { top : 0 , left : r - inst . helperProportions . width } ) . left ;
}
}
if ( ! inst . snapElements [ i ] . snapping && ( ts || bs || ls || rs || first ) ) {
( inst . options . snap . snap && inst . options . snap . snap . call ( inst . element , event , $ . extend ( inst . _uiHash ( ) , { snapItem : inst . snapElements [ i ] . item } ) ) ) ;
}
inst . snapElements [ i ] . snapping = ( ts || bs || ls || rs || first ) ;
}
}
} ) ;
$ . ui . plugin . add ( "draggable" , "stack" , {
start : function ( event , ui , 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 ) ) ;
}
} ) ;
$ . 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" ) ;
}
t . css ( "zIndex" , o . zIndex ) ;
} ,
stop : function ( event , ui , instance ) {
var o = instance . options ;
if ( o . _zIndex ) {
$ ( ui . helper ) . css ( "zIndex" , o . _zIndex ) ;
}
}
} ) ;
var draggable = $ . ui . draggable ;
/ * !
* jQuery UI Droppable 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/droppable/
* /
$ . widget ( "ui.droppable" , {
version : "1.11.4" ,
widgetEventPrefix : "drop" ,
options : {
accept : "*" ,
activeClass : false ,
addClasses : true ,
greedy : false ,
hoverClass : false ,
scope : "default" ,
tolerance : "intersect" ,
// callbacks
activate : null ,
deactivate : null ,
drop : null ,
out : null ,
over : null
} ,
_create : function ( ) {
var proportions ,
o = this . options ,
accept = o . accept ;
this . isover = false ;
this . isout = true ;
this . accept = $ . isFunction ( accept ) ? accept : function ( d ) {
return d . is ( accept ) ;
} ;
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 :
proportions = {
width : this . element [ 0 ] . offsetWidth ,
height : this . element [ 0 ] . offsetHeight
} ;
}
} ;
this . _addToManager ( o . scope ) ;
o . addClasses && this . element . 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 ) ;
} ,
_splice : function ( drop ) {
var i = 0 ;
for ( ; i < drop . length ; i ++ ) {
if ( drop [ i ] === this ) {
drop . splice ( i , 1 ) ;
}
}
} ,
_destroy : function ( ) {
var drop = $ . ui . ddmanager . droppables [ this . options . scope ] ;
this . _splice ( drop ) ;
this . element . removeClass ( "ui-droppable ui-droppable-disabled" ) ;
} ,
_setOption : function ( key , value ) {
if ( key === "accept" ) {
this . accept = $ . isFunction ( value ) ? value : function ( d ) {
return d . is ( value ) ;
} ;
} else if ( key === "scope" ) {
var drop = $ . ui . ddmanager . droppables [ this . options . scope ] ;
this . _splice ( drop ) ;
this . _addToManager ( value ) ;
}
this . _super ( key , value ) ;
} ,
_activate : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
if ( this . options . activeClass ) {
this . element . addClass ( this . options . activeClass ) ;
}
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 . _trigger ( "deactivate" , event , this . ui ( draggable ) ) ;
}
} ,
_over : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
// Bail if draggable and droppable are same element
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 ) ;
}
this . _trigger ( "over" , event , this . ui ( draggable ) ) ;
}
} ,
_out : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
// Bail if draggable and droppable are same element
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 ) ;
}
this . _trigger ( "out" , event , this . ui ( draggable ) ) ;
}
} ,
_drop : function ( event , custom ) {
var draggable = custom || $ . ui . ddmanager . current ,
childrenIntersection = false ;
// Bail if draggable and droppable are same element
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 ; }
} ) ;
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 ) ;
}
this . _trigger ( "drop" , event , this . ui ( draggable ) ) ;
return this . element ;
}
return false ;
} ,
ui : function ( c ) {
return {
draggable : ( c . currentItem || c . element ) ,
helper : c . helper ,
position : c . position ,
offset : c . positionAbs
} ;
}
} ) ;
$ . ui . intersect = ( function ( ) {
function isOverAxis ( x , reference , size ) {
return ( x >= reference ) && ( x < ( reference + size ) ) ;
}
return function ( draggable , droppable , toleranceMode , event ) {
if ( ! droppable . offset ) {
return false ;
}
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 ,
t = droppable . offset . top ,
r = l + droppable . proportions ( ) . width ,
b = t + droppable . proportions ( ) . height ;
switch ( toleranceMode ) {
case "fit" :
return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ) ;
case "intersect" :
return ( l < x1 + ( draggable . helperProportions . width / 2 ) && // Right Half
x2 - ( draggable . helperProportions . width / 2 ) < r && // Left Half
t < y1 + ( draggable . helperProportions . height / 2 ) && // Bottom Half
y2 - ( draggable . helperProportions . height / 2 ) < b ) ; // Top Half
case "pointer" :
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
( y2 >= t && y2 <= b ) || // Bottom edge touching
( y1 < t && y2 > b ) // Surrounded vertically
) && (
( x1 >= l && x1 <= r ) || // Left edge touching
( x2 >= l && x2 <= r ) || // Right edge touching
( x1 < l && x2 > r ) // Surrounded horizontally
) ;
default :
return false ;
}
} ;
} ) ( ) ;
/ *
This manager tracks offsets of draggables and droppables
* /
$ . ui . ddmanager = {
current : null ,
droppables : { "default" : [ ] } ,
prepareOffsets : function ( t , event ) {
var i , j ,
m = $ . ui . ddmanager . droppables [ t . options . scope ] || [ ] ,
type = event ? event . type : null , // workaround for #2317
list = ( t . currentItem || t . element ) . find ( ":data(ui-droppable)" ) . addBack ( ) ;
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 ) ) ) ) {
continue ;
}
// Filter out elements in the current dragged item
for ( j = 0 ; j < list . length ; j ++ ) {
if ( list [ j ] === m [ i ] . element [ 0 ] ) {
m [ i ] . proportions ( ) . height = 0 ;
continue droppablesLoop ;
}
}
m [ i ] . visible = m [ i ] . element . css ( "display" ) !== "none" ;
if ( ! m [ i ] . visible ) {
continue ;
}
// Activate the droppable if used directly from draggables
if ( type === "mousedown" ) {
m [ i ] . _activate . call ( m [ i ] , event ) ;
}
m [ i ] . offset = m [ i ] . element . offset ( ) ;
m [ i ] . proportions ( { width : m [ i ] . element [ 0 ] . offsetWidth , height : m [ i ] . element [ 0 ] . offsetHeight } ) ;
}
} ,
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 ) ) {
dropped = this . _drop . call ( this , event ) || dropped ;
}
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 ( ) {
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 ( draggable . options . refreshPositions ) {
$ . ui . ddmanager . prepareOffsets ( draggable , event ) ;
}
// Run through all droppables and check their positions based on specific tolerance options
$ . each ( $ . ui . ddmanager . droppables [ draggable . options . scope ] || [ ] , function ( ) {
if ( this . options . disabled || this . greedyChild || ! this . visible ) {
return ;
}
var parentInstance , scope , parent ,
intersects = $ . ui . 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 ( ) {
return $ ( this ) . droppable ( "instance" ) . options . scope === scope ;
} ) ;
if ( parent . length ) {
parentInstance = $ ( parent [ 0 ] ) . droppable ( "instance" ) ;
parentInstance . greedyChild = ( c === "isover" ) ;
}
}
// we just moved into a greedy child
if ( parentInstance && c === "isover" ) {
parentInstance . isover = false ;
parentInstance . isout = true ;
parentInstance . _out . call ( parentInstance , event ) ;
}
this [ c ] = true ;
this [ c === "isout" ? "isover" : "isout" ] = false ;
this [ c === "isover" ? "_over" : "_out" ] . call ( this , event ) ;
// 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)
if ( ! draggable . options . refreshPositions ) {
$ . ui . ddmanager . prepareOffsets ( draggable , event ) ;
}
}
} ;
var droppable = $ . ui . droppable ;
/ * !
* jQuery UI Resizable 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/resizable/
* /
$ . widget ( "ui.resizable" , $ . ui . mouse , {
version : "1.11.4" ,
widgetEventPrefix : "resize" ,
options : {
alsoResize : false ,
animate : false ,
animateDuration : "slow" ,
animateEasing : "swing" ,
aspectRatio : false ,
autoHide : false ,
containment : false ,
ghost : false ,
grid : false ,
handles : "e,s,se" ,
helper : false ,
maxHeight : null ,
maxWidth : null ,
minHeight : 10 ,
minWidth : 10 ,
// See #7960
zIndex : 90 ,
// callbacks
resize : null ,
start : null ,
stop : null
} ,
_num : function ( value ) {
return parseInt ( value , 10 ) || 0 ;
} ,
_isNumber : function ( value ) {
return ! isNaN ( parseInt ( value , 10 ) ) ;
} ,
_hasScroll : function ( el , a ) {
if ( $ ( el ) . css ( "overflow" ) === "hidden" ) {
return false ;
}
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop" ,
has = false ;
if ( el [ scroll ] > 0 ) {
return true ;
}
// TODO: determine which cases actually cause this to happen
// if the element doesn't have the scroll set, see if it's possible to
// set the scroll
el [ scroll ] = 1 ;
has = ( el [ scroll ] > 0 ) ;
el [ scroll ] = 0 ;
return has ;
} ,
_create : function ( ) {
var n , i , handle , axis , hname ,
that = this ,
o = this . options ;
this . element . addClass ( "ui-resizable" ) ;
$ . 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 ) ) {
this . element . wrap (
$ ( "<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" )
} )
) ;
this . element = this . element . parent ( ) . data (
"ui-resizable" , this . element . resizable ( "instance" )
) ;
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
} ) ;
// support: Safari
// Prevent Safari textarea resize
this . originalResizeStyle = this . originalElement . css ( "resize" ) ;
this . originalElement . css ( "resize" , "none" ) ;
this . _proportionallyResizeElements . push ( this . originalElement . css ( {
position : "static" ,
zoom : 1 ,
display : "block"
} ) ) ;
// support: IE9
// avoid IE jump (hard set the margin)
this . originalElement . css ( { margin : this . originalElement . css ( "margin" ) } ) ;
this . _proportionallyResize ( ) ;
}
this . handles = o . handles ||
( ! $ ( ".ui-resizable-handle" , this . element ) . length ?
"e,s,se" : {
n : ".ui-resizable-n" ,
e : ".ui-resizable-e" ,
s : ".ui-resizable-s" ,
w : ".ui-resizable-w" ,
se : ".ui-resizable-se" ,
sw : ".ui-resizable-sw" ,
ne : ".ui-resizable-ne" ,
nw : ".ui-resizable-nw"
} ) ;
this . _handles = $ ( ) ;
if ( this . handles . constructor === String ) {
if ( this . handles === "all" ) {
this . handles = "n,e,s,w,se,sw,ne,nw" ;
}
n = this . handles . split ( "," ) ;
this . handles = { } ;
for ( i = 0 ; i < n . length ; i ++ ) {
handle = $ . trim ( n [ i ] ) ;
hname = "ui-resizable-" + handle ;
axis = $ ( "<div class='ui-resizable-handle " + hname + "'></div>" ) ;
axis . css ( { zIndex : o . zIndex } ) ;
// TODO : What's going on here?
if ( "se" === handle ) {
axis . addClass ( "ui-icon ui-icon-gripsmall-diagonal-se" ) ;
}
this . handles [ handle ] = ".ui-resizable-" + handle ;
this . element . append ( axis ) ;
}
}
this . _renderAxis = function ( target ) {
var i , axis , padPos , padWrapper ;
target = target || this . element ;
for ( i in this . handles ) {
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 } ) ;
}
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 ( ) ;
padPos = [ "padding" ,
/ne|nw|n/ . test ( i ) ? "Top" :
/se|sw|s/ . test ( i ) ? "Bottom" :
/^e$/ . test ( i ) ? "Right" : "Left" ] . join ( "" ) ;
target . css ( padPos , padWrapper ) ;
this . _proportionallyResize ( ) ;
}
this . _handles = this . _handles . add ( this . handles [ i ] ) ;
}
} ;
// TODO: make renderAxis a prototype function
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 ) ;
}
that . axis = axis && axis [ 1 ] ? axis [ 1 ] : "se" ;
}
} ) ;
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 . _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 ;
} ,
_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 ) ) {
capture = true ;
}
}
return ! this . options . disabled && capture ;
} ,
_mouseStart : function ( event ) {
var curleft , curtop , cursor ,
o = this . options ,
el = this . element ;
this . resizing = true ;
this . _renderProxy ( ) ;
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 ;
}
this . offset = this . helper . offset ( ) ;
this . position = { left : curleft , top : curtop } ;
this . size = this . _helper ? {
width : this . helper . width ( ) ,
height : this . helper . height ( )
} : {
width : el . width ( ) ,
height : el . height ( )
} ;
this . originalSize = this . _helper ? {
width : el . outerWidth ( ) ,
height : el . outerHeight ( )
} : {
width : el . width ( ) ,
height : el . height ( )
} ;
this . sizeDiff = {
width : el . outerWidth ( ) - el . width ( ) ,
height : el . outerHeight ( ) - el . height ( )
} ;
this . originalPosition = { left : curleft , top : curtop } ;
this . originalMousePosition = { left : event . pageX , top : event . pageY } ;
this . aspectRatio = ( typeof o . aspectRatio === "number" ) ?
o . aspectRatio :
( ( this . originalSize . width / this . originalSize . height ) || 1 ) ;
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 ) ;
return true ;
} ,
_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 ] ;
this . _updatePrevProperties ( ) ;
if ( ! trigger ) {
return false ;
}
data = trigger . apply ( this , [ event , dx , dy ] ) ;
this . _updateVirtualBoundaries ( event . shiftKey ) ;
if ( this . _aspectRatio || event . shiftKey ) {
data = this . _updateRatio ( data , event ) ;
}
data = this . _respectSize ( data , event ) ;
this . _updateCache ( data ) ;
this . _propagate ( "resize" , event ) ;
props = this . _applyChanges ( ) ;
if ( ! this . _helper && this . _proportionallyResizeElements . length ) {
this . _proportionallyResize ( ) ;
}
if ( ! $ . isEmptyObject ( props ) ) {
this . _updatePrevProperties ( ) ;
this . _trigger ( "resize" , event , this . ui ( ) ) ;
this . _applyChanges ( ) ;
}
return false ;
} ,
_mouseStop : function ( event ) {
this . resizing = false ;
var pr , ista , soffseth , soffsetw , s , left , top ,
o = this . options , that = this ;
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 ;
soffsetw = ista ? 0 : that . sizeDiff . width ;
s = {
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 ;
if ( ! o . animate ) {
this . element . css ( $ . extend ( s , { top : top , left : left } ) ) ;
}
that . helper . height ( that . size . height ) ;
that . helper . width ( that . size . width ) ;
if ( this . _helper && ! o . animate ) {
this . _proportionallyResize ( ) ;
}
}
$ ( "body" ) . css ( "cursor" , "auto" ) ;
this . element . removeClass ( "ui-resizable-resizing" ) ;
this . _propagate ( "stop" , event ) ;
if ( this . _helper ) {
this . helper . remove ( ) ;
}
return false ;
} ,
_updatePrevProperties : function ( ) {
this . prevPosition = {
top : this . position . top ,
left : this . position . left
} ;
this . prevSize = {
width : this . size . width ,
height : this . size . height
} ;
} ,
_applyChanges : function ( ) {
var props = { } ;
if ( this . position . top !== this . prevPosition . top ) {
props . top = this . position . top + "px" ;
}
if ( this . position . left !== this . prevPosition . left ) {
props . left = this . position . left + "px" ;
}
if ( this . size . width !== this . prevSize . width ) {
props . width = this . size . width + "px" ;
}
if ( this . size . height !== this . prevSize . height ) {
props . height = this . size . height + "px" ;
}
this . helper . css ( props ) ;
return props ;
} ,
_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
} ;
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 ) {
b . minWidth = pMinWidth ;
}
if ( pMinHeight > b . minHeight ) {
b . minHeight = pMinHeight ;
}
if ( pMaxWidth < b . maxWidth ) {
b . maxWidth = pMaxWidth ;
}
if ( pMaxHeight < b . maxHeight ) {
b . maxHeight = pMaxHeight ;
}
}
this . _vBoundaries = b ;
} ,
_updateCache : function ( data ) {
this . offset = this . helper . offset ( ) ;
if ( this . _isNumber ( data . left ) ) {
this . position . left = data . left ;
}
if ( this . _isNumber ( data . top ) ) {
this . position . top = data . top ;
}
if ( this . _isNumber ( data . height ) ) {
this . size . height = data . height ;
}
if ( this . _isNumber ( data . width ) ) {
this . size . width = data . width ;
}
} ,
_updateRatio : function ( data ) {
var cpos = this . position ,
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 ( a === "sw" ) {
data . left = cpos . left + ( csize . width - data . width ) ;
data . top = null ;
}
if ( a === "nw" ) {
data . top = cpos . top + ( csize . height - data . height ) ;
data . left = cpos . left + ( csize . width - data . width ) ;
}
return data ;
} ,
_respectSize : function ( data ) {
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 ) ,
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 ) {
data . width = o . minWidth ;
}
if ( isminh ) {
data . height = o . minHeight ;
}
if ( ismaxw ) {
data . width = o . maxWidth ;
}
if ( ismaxh ) {
data . height = o . maxHeight ;
}
if ( isminw && cw ) {
data . left = dw - o . minWidth ;
}
if ( ismaxw && cw ) {
data . left = dw - o . maxWidth ;
}
if ( isminh && ch ) {
data . top = dh - o . minHeight ;
}
if ( ismaxh && ch ) {
data . top = dh - o . maxHeight ;
}
// Fixing jump error on top/left - bug #2330
if ( ! data . width && ! data . height && ! data . left && data . top ) {
data . top = null ;
} else if ( ! data . width && ! data . height && ! data . top && data . left ) {
data . left = null ;
}
return data ;
} ,
_getPaddingPlusBorderDimensions : function ( element ) {
var i = 0 ,
widths = [ ] ,
borders = [
element . css ( "borderTopWidth" ) ,
element . css ( "borderRightWidth" ) ,
element . css ( "borderBottomWidth" ) ,
element . css ( "borderLeftWidth" )
] ,
paddings = [
element . css ( "paddingTop" ) ,
element . css ( "paddingRight" ) ,
element . css ( "paddingBottom" ) ,
element . css ( "paddingLeft" )
] ;
for ( ; i < 4 ; i ++ ) {
widths [ i ] = ( parseInt ( borders [ i ] , 10 ) || 0 ) ;
widths [ i ] += ( parseInt ( paddings [ i ] , 10 ) || 0 ) ;
}
return {
height : widths [ 0 ] + widths [ 2 ] ,
width : widths [ 1 ] + widths [ 3 ]
} ;
} ,
_proportionallyResize : function ( ) {
if ( ! this . _proportionallyResizeElements . length ) {
return ;
}
var prel ,
i = 0 ,
element = this . helper || this . element ;
for ( ; i < this . _proportionallyResizeElements . length ; i ++ ) {
prel = this . _proportionallyResizeElements [ i ] ;
// TODO: Seems like a bug to cache this.outerDimensions
// considering that we are in a loop.
if ( ! this . outerDimensions ) {
this . outerDimensions = this . _getPaddingPlusBorderDimensions ( prel ) ;
}
prel . css ( {
height : ( element . height ( ) - this . outerDimensions . height ) || 0 ,
width : ( element . width ( ) - this . outerDimensions . width ) || 0
} ) ;
}
} ,
_renderProxy : function ( ) {
var el = this . element , o = this . options ;
this . elementOffset = el . offset ( ) ;
if ( this . _helper ) {
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 ,
position : "absolute" ,
left : this . elementOffset . left + "px" ,
top : this . elementOffset . top + "px" ,
zIndex : ++ o . zIndex //TODO: Don't modify option
} ) ;
this . helper
. appendTo ( "body" )
. disableSelection ( ) ;
} else {
this . helper = this . element ;
}
} ,
_change : {
e : function ( event , dx ) {
return { width : this . originalSize . width + 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 ) {
var cs = this . originalSize , sp = this . originalPosition ;
return { top : sp . top + dy , height : cs . height - dy } ;
} ,
s : function ( event , dx , dy ) {
return { height : this . originalSize . height + dy } ;
} ,
se : function ( event , dx , dy ) {
return $ . extend ( this . _change . s . apply ( this , arguments ) ,
this . _change . e . apply ( this , [ event , dx , dy ] ) ) ;
} ,
sw : function ( event , dx , dy ) {
return $ . extend ( this . _change . s . apply ( this , arguments ) ,
this . _change . w . apply ( this , [ event , dx , dy ] ) ) ;
} ,
ne : function ( event , dx , dy ) {
return $ . extend ( this . _change . n . apply ( this , arguments ) ,
this . _change . e . apply ( this , [ event , dx , dy ] ) ) ;
} ,
nw : function ( event , dx , dy ) {
return $ . extend ( this . _change . n . apply ( this , arguments ) ,
this . _change . w . apply ( this , [ event , dx , dy ] ) ) ;
}
} ,
_propagate : function ( n , event ) {
$ . ui . plugin . call ( this , n , [ event , this . ui ( ) ] ) ;
( n !== "resize" && this . _trigger ( n , event , this . ui ( ) ) ) ;
} ,
plugins : { } ,
ui : function ( ) {
return {
originalElement : this . originalElement ,
element : this . element ,
helper : this . helper ,
position : this . position ,
size : this . size ,
originalSize : this . originalSize ,
originalPosition : this . originalPosition
} ;
}
} ) ;
/ *
* Resizable Extensions
* /
$ . ui . plugin . add ( "resizable" , "animate" , {
stop : function ( event ) {
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 ,
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 ;
that . element . animate (
$ . 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 )
} ;
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 ) ;
}
}
) ;
}
} ) ;
$ . ui . plugin . add ( "resizable" , "containment" , {
start : function ( ) {
var element , p , co , ch , cw , width , height ,
that = $ ( this ) . resizable ( "instance" ) ,
o = that . options ,
el = that . element ,
oc = o . containment ,
ce = ( oc instanceof $ ) ? oc . get ( 0 ) : ( /parent/ . test ( oc ) ) ? el . parent ( ) . get ( 0 ) : oc ;
if ( ! ce ) {
return ;
}
that . containerElement = $ ( ce ) ;
if ( /document/ . test ( oc ) || oc === document ) {
that . containerOffset = {
left : 0 ,
top : 0
} ;
that . containerPosition = {
left : 0 ,
top : 0
} ;
that . parentData = {
element : $ ( document ) ,
left : 0 ,
top : 0 ,
width : $ ( document ) . width ( ) ,
height : $ ( document ) . height ( ) || document . body . parentNode . scrollHeight
} ;
} else {
element = $ ( ce ) ;
p = [ ] ;
$ ( [ "Top" , "Right" , "Left" , "Bottom" ] ) . each ( function ( i , name ) {
p [ i ] = that . _num ( element . css ( "padding" + name ) ) ;
} ) ;
that . containerOffset = element . offset ( ) ;
that . containerPosition = element . position ( ) ;
that . containerSize = {
height : ( element . innerHeight ( ) - p [ 3 ] ) ,
width : ( element . innerWidth ( ) - p [ 1 ] )
} ;
co = that . containerOffset ;
ch = that . containerSize . height ;
cw = that . containerSize . width ;
width = ( that . _hasScroll ( ce , "left" ) ? ce . scrollWidth : cw ) ;
height = ( that . _hasScroll ( ce ) ? ce . scrollHeight : ch ) ;
that . parentData = {
element : ce ,
left : co . left ,
top : co . top ,
width : width ,
height : height
} ;
}
} ,
resize : function ( event ) {
var woset , hoset , isParent , isOffsetRelative ,
that = $ ( this ) . resizable ( "instance" ) ,
o = that . options ,
co = that . containerOffset ,
cp = that . position ,
pRatio = that . _aspectRatio || event . shiftKey ,
cop = {
top : 0 ,
left : 0
} ,
ce = that . containerElement ,
continueResize = true ;
if ( ce [ 0 ] !== document && ( /static/ ) . test ( ce . css ( "position" ) ) ) {
cop = co ;
}
if ( cp . left < ( that . _helper ? co . left : 0 ) ) {
that . size . width = that . size . width +
( that . _helper ?
( that . position . left - co . left ) :
( that . position . left - cop . left ) ) ;
if ( pRatio ) {
that . size . height = that . size . width / that . aspectRatio ;
continueResize = false ;
}
that . position . left = o . helper ? co . left : 0 ;
}
if ( cp . top < ( that . _helper ? co . top : 0 ) ) {
that . size . height = that . size . height +
( that . _helper ?
( that . position . top - co . top ) :
that . position . top ) ;
if ( pRatio ) {
that . size . width = that . size . height * that . aspectRatio ;
continueResize = false ;
}
that . position . top = that . _helper ? co . top : 0 ;
}
isParent = that . containerElement . get ( 0 ) === that . element . parent ( ) . get ( 0 ) ;
isOffsetRelative = /relative|absolute/ . test ( that . containerElement . css ( "position" ) ) ;
if ( isParent && isOffsetRelative ) {
that . offset . left = that . parentData . left + that . position . left ;
that . offset . top = that . parentData . top + that . position . top ;
} else {
that . offset . left = that . element . offset ( ) . left ;
that . offset . top = that . element . offset ( ) . top ;
}
woset = Math . abs ( that . sizeDiff . width +
( that . _helper ?
that . offset . left - cop . left :
( that . offset . left - co . left ) ) ) ;
hoset = Math . abs ( that . sizeDiff . height +
( that . _helper ?
that . offset . top - cop . top :
( that . offset . top - co . top ) ) ) ;
if ( woset + that . size . width >= that . parentData . width ) {
that . size . width = that . parentData . width - woset ;
if ( pRatio ) {
that . size . height = that . size . width / that . aspectRatio ;
continueResize = false ;
}
}
if ( hoset + that . size . height >= that . parentData . height ) {
that . size . height = that . parentData . height - hoset ;
if ( pRatio ) {
that . size . width = that . size . height * that . aspectRatio ;
continueResize = false ;
}
}
if ( ! continueResize ) {
that . position . left = that . prevPosition . left ;
that . position . top = that . prevPosition . top ;
that . size . width = that . prevSize . width ;
that . size . height = that . prevSize . height ;
}
} ,
stop : function ( ) {
var that = $ ( this ) . resizable ( "instance" ) ,
o = that . options ,
co = that . containerOffset ,
cop = that . containerPosition ,
ce = that . containerElement ,
helper = $ ( that . helper ) ,
ho = helper . offset ( ) ,
w = helper . outerWidth ( ) - that . sizeDiff . width ,
h = helper . outerHeight ( ) - that . sizeDiff . height ;
if ( that . _helper && ! o . animate && ( /relative/ ) . test ( ce . css ( "position" ) ) ) {
$ ( 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 ( {
left : ho . left - cop . left - co . left ,
width : w ,
height : h
} ) ;
}
}
} ) ;
$ . ui . plugin . add ( "resizable" , "alsoResize" , {
start : function ( ) {
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 )
} ) ;
} ) ;
} ,
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
} ;
$ ( 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 ;
}
} ) ;
el . css ( style ) ;
} ) ;
} ,
stop : function ( ) {
$ ( this ) . removeData ( "resizable-alsoresize" ) ;
}
} ) ;
$ . ui . plugin . add ( "resizable" , "ghost" , {
start : function ( ) {
var that = $ ( this ) . resizable ( "instance" ) , o = that . options , 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 . appendTo ( that . helper ) ;
} ,
resize : function ( ) {
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 ) ) ;
}
}
} ) ;
$ . ui . plugin . add ( "resizable" , "grid" , {
resize : function ( ) {
var outerDimensions ,
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 ,
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 ) ;
o . grid = grid ;
if ( isMinWidth ) {
newWidth += gridX ;
}
if ( isMinHeight ) {
newHeight += gridY ;
}
if ( isMaxWidth ) {
newWidth -= gridX ;
}
if ( isMaxHeight ) {
newHeight -= gridY ;
}
if ( /^(se|s|e)$/ . test ( a ) ) {
that . size . width = newWidth ;
that . size . height = newHeight ;
} else if ( /^(ne)$/ . test ( a ) ) {
that . size . width = newWidth ;
that . size . height = newHeight ;
that . position . top = op . top - oy ;
} 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 ) {
outerDimensions = that . _getPaddingPlusBorderDimensions ( this ) ;
}
if ( newHeight - gridY > 0 ) {
that . size . height = newHeight ;
that . position . top = op . top - oy ;
} else {
newHeight = gridY - outerDimensions . height ;
that . size . height = newHeight ;
that . position . top = op . top + os . height - newHeight ;
}
if ( newWidth - gridX > 0 ) {
that . size . width = newWidth ;
that . position . left = op . left - ox ;
} else {
newWidth = gridX - outerDimensions . width ;
that . size . width = newWidth ;
that . position . left = op . left + os . width - newWidth ;
}
}
}
} ) ;
var resizable = $ . ui . resizable ;
/ * !
* jQuery UI Selectable 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/selectable/
* /
var selectable = $ . widget ( "ui.selectable" , $ . ui . mouse , {
version : "1.11.4" ,
options : {
appendTo : "body" ,
autoRefresh : true ,
distance : 0 ,
filter : "*" ,
tolerance : "touch" ,
// callbacks
selected : null ,
selecting : null ,
start : null ,
stop : null ,
unselected : null ,
unselecting : null
} ,
_create : function ( ) {
var selectees ,
that = this ;
this . element . addClass ( "ui-selectable" ) ;
this . dragged = false ;
// 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" , {
element : this ,
$element : $this ,
left : pos . left ,
top : pos . top ,
right : pos . left + $this . outerWidth ( ) ,
bottom : pos . top + $this . outerHeight ( ) ,
startselected : false ,
selected : $this . hasClass ( "ui-selected" ) ,
selecting : $this . hasClass ( "ui-selecting" ) ,
unselecting : $this . hasClass ( "ui-unselecting" )
} ) ;
} ) ;
} ;
this . refresh ( ) ;
this . selectees = selectees . addClass ( "ui-selectee" ) ;
this . _mouseInit ( ) ;
this . helper = $ ( "<div class='ui-selectable-helper'></div>" ) ;
} ,
_destroy : function ( ) {
this . selectees
. removeClass ( "ui-selectee" )
. removeData ( "selectable-item" ) ;
this . element
. removeClass ( "ui-selectable ui-selectable-disabled" ) ;
this . _mouseDestroy ( ) ;
} ,
_mouseStart : function ( event ) {
var that = this ,
options = this . options ;
this . opos = [ event . pageX , event . pageY ] ;
if ( this . options . disabled ) {
return ;
}
this . selectees = $ ( options . filter , this . element [ 0 ] ) ;
this . _trigger ( "start" , event ) ;
$ ( options . appendTo ) . append ( this . helper ) ;
// position helper (lasso)
this . helper . css ( {
"left" : event . pageX ,
"top" : event . pageY ,
"width" : 0 ,
"height" : 0
} ) ;
if ( options . autoRefresh ) {
this . refresh ( ) ;
}
this . selectees . filter ( ".ui-selected" ) . each ( function ( ) {
var selectee = $ . data ( this , "selectable-item" ) ;
selectee . startselected = true ;
if ( ! event . metaKey && ! event . ctrlKey ) {
selectee . $element . removeClass ( "ui-selected" ) ;
selectee . selected = false ;
selectee . $element . addClass ( "ui-unselecting" ) ;
selectee . unselecting = true ;
// selectable UNSELECTING callback
that . _trigger ( "unselecting" , event , {
unselecting : selectee . element
} ) ;
}
} ) ;
$ ( 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 . unselecting = ! doSelect ;
selectee . selecting = doSelect ;
selectee . selected = doSelect ;
// selectable (UN)SELECTING callback
if ( doSelect ) {
that . _trigger ( "selecting" , event , {
selecting : selectee . element
} ) ;
} else {
that . _trigger ( "unselecting" , event , {
unselecting : selectee . element
} ) ;
}
return false ;
}
} ) ;
} ,
_mouseDrag : function ( event ) {
this . dragged = true ;
if ( this . options . disabled ) {
return ;
}
var tmp ,
that = this ,
options = this . options ,
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 } ) ;
this . selectees . each ( function ( ) {
var selectee = $ . data ( this , "selectable-item" ) ,
hit = false ;
//prevent helper from being selected if appendTo: selectable
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 ) ;
}
if ( hit ) {
// SELECT
if ( selectee . selected ) {
selectee . $element . removeClass ( "ui-selected" ) ;
selectee . selected = false ;
}
if ( selectee . unselecting ) {
selectee . $element . removeClass ( "ui-unselecting" ) ;
selectee . unselecting = false ;
}
if ( ! selectee . selecting ) {
selectee . $element . addClass ( "ui-selecting" ) ;
selectee . selecting = true ;
// selectable SELECTING callback
that . _trigger ( "selecting" , event , {
selecting : selectee . element
} ) ;
}
} else {
// UNSELECT
if ( selectee . selecting ) {
if ( ( event . metaKey || event . ctrlKey ) && selectee . startselected ) {
selectee . $element . removeClass ( "ui-selecting" ) ;
selectee . selecting = false ;
selectee . $element . addClass ( "ui-selected" ) ;
selectee . selected = true ;
} else {
selectee . $element . removeClass ( "ui-selecting" ) ;
selectee . selecting = false ;
if ( selectee . startselected ) {
selectee . $element . addClass ( "ui-unselecting" ) ;
selectee . unselecting = true ;
}
// selectable UNSELECTING callback
that . _trigger ( "unselecting" , event , {
unselecting : selectee . element
} ) ;
}
}
if ( selectee . selected ) {
if ( ! event . metaKey && ! event . ctrlKey && ! selectee . startselected ) {
selectee . $element . removeClass ( "ui-selected" ) ;
selectee . selected = false ;
selectee . $element . addClass ( "ui-unselecting" ) ;
selectee . unselecting = true ;
// selectable UNSELECTING callback
that . _trigger ( "unselecting" , event , {
unselecting : selectee . element
} ) ;
}
}
}
} ) ;
return false ;
} ,
_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" ) ;
selectee . unselecting = false ;
selectee . startselected = false ;
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" ) ;
selectee . selecting = false ;
selectee . selected = true ;
selectee . startselected = true ;
that . _trigger ( "selected" , event , {
selected : selectee . element
} ) ;
} ) ;
this . _trigger ( "stop" , event ) ;
this . helper . remove ( ) ;
return false ;
}
} ) ;
/ * !
* jQuery UI Sortable 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/sortable/
* /
var sortable = $ . widget ( "ui.sortable" , $ . ui . mouse , {
version : "1.11.4" ,
widgetEventPrefix : "sort" ,
ready : false ,
options : {
appendTo : "parent" ,
axis : false ,
connectWith : false ,
containment : false ,
cursor : "auto" ,
cursorAt : false ,
dropOnEmpty : true ,
forcePlaceholderSize : false ,
forceHelperSize : false ,
grid : false ,
handle : false ,
helper : "original" ,
items : "> *" ,
opacity : false ,
placeholder : false ,
revert : false ,
scroll : true ,
scrollSensitivity : 20 ,
scrollSpeed : 20 ,
scope : "default" ,
tolerance : "intersect" ,
zIndex : 1000 ,
// callbacks
activate : null ,
beforeStop : null ,
change : null ,
deactivate : null ,
out : null ,
over : null ,
receive : null ,
remove : null ,
sort : null ,
start : null ,
stop : null ,
update : null
} ,
_isOverAxis : function ( x , reference , size ) {
return ( x >= reference ) && ( x < ( reference + size ) ) ;
} ,
_isFloating : function ( item ) {
return ( /left|right/ ) . test ( item . css ( "float" ) ) || ( /inline|table-cell/ ) . test ( item . css ( "display" ) ) ;
} ,
_create : function ( ) {
this . containerCache = { } ;
this . element . addClass ( "ui-sortable" ) ;
//Get the items
this . refresh ( ) ;
//Let's determine the parent's offset
this . offset = this . element . offset ( ) ;
//Initialize mouse events for interaction
this . _mouseInit ( ) ;
this . _setHandleClassName ( ) ;
//We're ready to go
this . ready = true ;
} ,
_setOption : function ( key , value ) {
this . _super ( key , value ) ;
if ( key === "handle" ) {
this . _setHandleClassName ( ) ;
}
} ,
_setHandleClassName : function ( ) {
this . element . find ( ".ui-sortable-handle" ) . removeClass ( "ui-sortable-handle" ) ;
$ . each ( this . items , function ( ) {
( this . instance . options . handle ?
this . item . find ( this . instance . options . handle ) : this . item )
. addClass ( "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" ) ;
}
return this ;
} ,
_mouseCapture : function ( event , overrideHandle ) {
var currentItem = null ,
validHandle = false ,
that = this ;
if ( this . reverting ) {
return false ;
}
if ( this . options . disabled || this . options . type === "static" ) {
return false ;
}
//We have to refresh the items data once first
this . _refreshItems ( event ) ;
//Find out if the clicked node (or one of its parents) is a actual item in this.items
$ ( 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 ( ! currentItem ) {
return false ;
}
if ( this . options . handle && ! overrideHandle ) {
$ ( this . options . handle , currentItem ) . find ( "*" ) . addBack ( ) . each ( function ( ) {
if ( this === event . target ) {
validHandle = true ;
}
} ) ;
if ( ! validHandle ) {
return false ;
}
}
this . currentItem = currentItem ;
this . _removeCurrentsFromItems ( ) ;
return true ;
} ,
_mouseStart : function ( event , overrideHandle , noActivation ) {
var i , body ,
o = this . options ;
this . currentContainer = this ;
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
this . refreshPositions ( ) ;
//Create and append the visible helper
this . helper = this . _createHelper ( event ) ;
//Cache the helper size
this . _cacheHelperProportions ( ) ;
/ *
* - Position generation -
* This block generates everything position related - it ' s the core of draggables .
* /
//Cache the margins of the original element
this . _cacheMargins ( ) ;
//Get the next scrolling parent
this . scrollParent = this . helper . scrollParent ( ) ;
//The element's absolute position on the page minus margins
this . offset = this . currentItem . offset ( ) ;
this . offset = {
top : this . offset . top - this . margins . top ,
left : this . offset . left - this . margins . left
} ;
$ . 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
} ) ;
// 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" ) ;
//Generate the original position
this . originalPosition = this . _generatePosition ( event ) ;
this . originalPageX = event . pageX ;
this . originalPageY = event . pageY ;
//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
( o . cursorAt && this . _adjustOffsetFromHelper ( o . cursorAt ) ) ;
//Cache the former DOM position
this . domPosition = { prev : this . currentItem . prev ( ) [ 0 ] , parent : this . currentItem . parent ( ) [ 0 ] } ;
//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
if ( this . helper [ 0 ] !== this . currentItem [ 0 ] ) {
this . currentItem . hide ( ) ;
}
//Create the placeholder
this . _createPlaceholder ( ) ;
//Set a containment if given in the options
if ( o . containment ) {
this . _setContainment ( ) ;
}
if ( o . cursor && o . cursor !== "auto" ) { // cursor option
body = this . document . find ( "body" ) ;
// support: IE
this . storedCursor = body . css ( "cursor" ) ;
body . css ( "cursor" , o . cursor ) ;
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" ) ;
}
this . helper . css ( "opacity" , o . opacity ) ;
}
if ( o . zIndex ) { // zIndex option
if ( this . helper . css ( "zIndex" ) ) {
this . _storedZIndex = this . helper . css ( "zIndex" ) ;
}
this . helper . css ( "zIndex" , o . zIndex ) ;
}
//Prepare scrolling
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 ( ) ) ;
//Recache the helper size
if ( ! this . _preserveHelperProportions ) {
this . _cacheHelperProportions ( ) ;
}
//Post "activate" events to possible containers
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 ) {
$ . ui . ddmanager . current = this ;
}
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
return true ;
} ,
_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" ) ;
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 . 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 . 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 ) ;
}
}
//Regenerate the absolute position used for position checks
this . positionAbs = this . _convertPositionTo ( "absolute" ) ;
//Set the helper position
if ( ! this . options . axis || this . options . axis !== "y" ) {
this . helper [ 0 ] . style . left = this . position . left + "px" ;
}
if ( ! this . options . axis || this . options . axis !== "x" ) {
this . helper [ 0 ] . style . top = this . position . top + "px" ;
}
//Rearrange
for ( 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 ) {
continue ;
}
// Only put the placeholder inside the current Container, skip all
// items from other containers. This works because when moving
// an item from one container to another the
// currentContainer is switched before the placeholder is moved.
//
// Without this, moving items in "sub-sortables" can cause
// the placeholder to jitter between the outer and inner container.
if ( item . instance !== this . currentContainer ) {
continue ;
}
// 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 )
) {
this . direction = intersection === 1 ? "down" : "up" ;
if ( this . options . tolerance === "pointer" || this . _intersectsWithSides ( item ) ) {
this . _rearrange ( event , item ) ;
} else {
break ;
}
this . _trigger ( "change" , event , this . _uiHash ( ) ) ;
break ;
}
}
//Post events to containers
this . _contactContainers ( event ) ;
//Interconnect with droppables
if ( $ . ui . ddmanager ) {
$ . ui . ddmanager . drag ( this , event ) ;
}
//Call callbacks
this . _trigger ( "sort" , event , this . _uiHash ( ) ) ;
this . lastPositionAbs = this . positionAbs ;
return false ;
} ,
_mouseStop : function ( event , noPropagation ) {
if ( ! event ) {
return ;
}
//If we are using droppables, inform the manager about the drop
if ( $ . ui . ddmanager && ! this . options . dropBehaviour ) {
$ . ui . ddmanager . drop ( this , event ) ;
}
if ( this . options . revert ) {
var 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 ) ;
}
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 ) ;
}
this . reverting = true ;
$ ( this . helper ) . animate ( animation , parseInt ( this . options . revert , 10 ) || 500 , function ( ) {
that . _clear ( event ) ;
} ) ;
} else {
this . _clear ( event , noPropagation ) ;
}
return false ;
} ,
cancel : function ( ) {
if ( this . dragging ) {
this . _mouseUp ( { target : null } ) ;
if ( this . options . helper === "original" ) {
this . currentItem . css ( this . _storedCSS ) . removeClass ( "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 ;
}
}
}
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 ) {
this . helper . remove ( ) ;
}
$ . extend ( this , {
helper : null ,
dragging : false ,
reverting : false ,
_noFinalSort : null
} ) ;
if ( this . domPosition . prev ) {
$ ( this . domPosition . prev ) . after ( this . currentItem ) ;
} else {
$ ( this . domPosition . parent ) . prepend ( this . currentItem ) ;
}
}
return this ;
} ,
serialize : function ( o ) {
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 ] ) ) ;
}
} ) ;
if ( ! str . length && o . key ) {
str . push ( o . key + "=" ) ;
}
return str . join ( "&" ) ;
} ,
toArray : function ( o ) {
var items = this . _getItemsAsjQuery ( o && o . connected ) ,
ret = [ ] ;
o = o || { } ;
items . each ( function ( ) { ret . push ( $ ( o . item || this ) . attr ( o . attribute || "id" ) || "" ) ; } ) ;
return ret ;
} ,
/* Be careful with the following core functions */
_intersectsWith : function ( item ) {
var x1 = this . positionAbs . left ,
x2 = x1 + this . helperProportions . width ,
y1 = this . positionAbs . top ,
y2 = y1 + this . helperProportions . height ,
l = item . left ,
r = l + item . width ,
t = item . top ,
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 ) ,
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" ] )
) {
return isOverElement ;
} else {
return ( l < x1 + ( this . helperProportions . width / 2 ) && // Right Half
x2 - ( this . helperProportions . width / 2 ) < r && // Left Half
t < y1 + ( this . helperProportions . height / 2 ) && // Bottom Half
y2 - ( this . helperProportions . height / 2 ) < b ) ; // Top Half
}
} ,
_intersectsWithPointer : function ( item ) {
var isOverElementHeight = ( 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 ( ) ;
if ( ! isOverElement ) {
return false ;
}
return this . floating ?
( ( ( horizontalDirection && horizontalDirection === "right" ) || verticalDirection === "down" ) ? 2 : 1 )
: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ) ;
} ,
_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 ) ,
verticalDirection = this . _getDragVerticalDirection ( ) ,
horizontalDirection = this . _getDragHorizontalDirection ( ) ;
if ( this . floating && horizontalDirection ) {
return ( ( horizontalDirection === "right" && isOverRightHalf ) || ( horizontalDirection === "left" && ! isOverRightHalf ) ) ;
} else {
return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || ( verticalDirection === "up" && ! isOverBottomHalf ) ) ;
}
} ,
_getDragVerticalDirection : function ( ) {
var delta = this . positionAbs . top - this . lastPositionAbs . top ;
return delta !== 0 && ( delta > 0 ? "down" : "up" ) ;
} ,
_getDragHorizontalDirection : function ( ) {
var delta = this . positionAbs . left - this . lastPositionAbs . left ;
return delta !== 0 && ( delta > 0 ? "right" : "left" ) ;
} ,
refresh : function ( event ) {
this . _refreshItems ( event ) ;
this . _setHandleClassName ( ) ;
this . refreshPositions ( ) ;
return this ;
} ,
_connectWith : function ( ) {
var options = this . options ;
return options . connectWith . constructor === String ? [ options . connectWith ] : options . connectWith ;
} ,
_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 ] ) ;
}
}
}
}
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 ) ;
}
return $ ( items ) ;
} ,
_removeCurrentsFromItems : function ( ) {
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 ] ) {
return false ;
}
}
return true ;
} ) ;
} ,
_refreshItems : function ( event ) {
this . items = [ ] ;
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 ] ] ,
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 ) ;
}
}
}
}
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 ] ) ;
item . data ( this . widgetName + "-item" , targetData ) ; // Data for target checking (mouse manager)
items . push ( {
item : item ,
instance : targetData ,
width : 0 , height : 0 ,
left : 0 , top : 0
} ) ;
}
}
} ,
refreshPositions : function ( fast ) {
// 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 . offset . parent = this . _getParentOffset ( ) ;
}
var i , item , t , p ;
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 ] ) {
continue ;
}
t = this . options . toleranceElement ? $ ( this . options . toleranceElement , item . item ) : item . item ;
if ( ! fast ) {
item . width = t . outerWidth ( ) ;
item . height = t . outerHeight ( ) ;
}
p = t . offset ( ) ;
item . left = p . left ;
item . top = p . top ;
}
if ( this . options . custom && this . options . custom . refreshContainers ) {
this . options . custom . refreshContainers . call ( this ) ;
} else {
for ( 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 ) {
that = that || this ;
var className ,
o = that . options ;
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" ) ;
if ( nodeName === "tbody" ) {
that . _createTrPlaceholder (
that . currentItem . find ( "tr" ) . eq ( 0 ) ,
$ ( "<tr>" , that . document [ 0 ] ) . appendTo ( element )
) ;
} else if ( nodeName === "tr" ) {
that . _createTrPlaceholder ( that . currentItem , element ) ;
} else if ( nodeName === "img" ) {
element . attr ( "src" , that . currentItem . attr ( "src" ) ) ;
}
if ( ! className ) {
element . css ( "visibility" , "hidden" ) ;
}
return element ;
} ,
update : function ( container , p ) {
// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
if ( className && ! o . forcePlaceholderSize ) {
return ;
}
//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
if ( ! p . height ( ) ) { p . height ( 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 ) ) ;
//Append it after the actual current item
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 ) ;
} ,
_createTrPlaceholder : function ( sourceTr , targetTr ) {
var that = this ;
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 ,
innermostContainer = null ,
innermostIndex = null ;
// 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 ] ) ) {
continue ;
}
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 ] ) ) {
continue ;
}
innermostContainer = this . containers [ i ] ;
innermostIndex = i ;
} else {
// container doesn't intersect. trigger "out" event if necessary
if ( this . containers [ i ] . containerCache . over ) {
this . containers [ i ] . _trigger ( "out" , event , this . _uiHash ( this ) ) ;
this . containers [ i ] . containerCache . over = 0 ;
}
}
}
// if no intersecting containers found, return
if ( ! innermostContainer ) {
return ;
}
// move the item into the container if it's not there already
if ( this . containers . length === 1 ) {
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
dist = 10000 ;
itemWithLeastDistance = null ;
floating = innermostContainer . floating || this . _isFloating ( this . currentItem ) ;
posProperty = floating ? "left" : "top" ;
sizeProperty = floating ? "width" : "height" ;
axis = floating ? "clientX" : "clientY" ;
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 ] ) {
continue ;
}
cur = this . items [ j ] . item . offset ( ) [ posProperty ] ;
nearBottom = false ;
if ( event [ axis ] - cur > this . items [ j ] [ sizeProperty ] / 2 ) {
nearBottom = true ;
}
if ( Math . abs ( event [ axis ] - cur ) < dist ) {
dist = Math . abs ( event [ axis ] - cur ) ;
itemWithLeastDistance = this . items [ j ] ;
this . direction = nearBottom ? "up" : "down" ;
}
}
//Check if dropOnEmpty is enabled
if ( ! itemWithLeastDistance && ! this . options . dropOnEmpty ) {
return ;
}
if ( this . currentContainer === this . containers [ innermostIndex ] ) {
if ( ! this . currentContainer . containerCache . over ) {
this . containers [ innermostIndex ] . _trigger ( "over" , event , this . _uiHash ( ) ) ;
this . currentContainer . containerCache . over = 1 ;
}
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 ] ;
//Update the placeholder
this . options . placeholder . update ( this . currentContainer , this . placeholder ) ;
this . containers [ innermostIndex ] . _trigger ( "over" , event , this . _uiHash ( this ) ) ;
this . containers [ innermostIndex ] . containerCache . over = 1 ;
}
} ,
_createHelper : function ( event ) {
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 ) ;
//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 [ 0 ] . style . width || o . forceHelperSize ) {
helper . width ( this . currentItem . width ( ) ) ;
}
if ( ! helper [ 0 ] . style . height || o . forceHelperSize ) {
helper . height ( this . currentItem . height ( ) ) ;
}
return helper ;
} ,
_adjustOffsetFromHelper : function ( obj ) {
if ( typeof obj === "string" ) {
obj = obj . split ( " " ) ;
}
if ( $ . isArray ( obj ) ) {
obj = { left : + obj [ 0 ] , top : + obj [ 1 ] || 0 } ;
}
if ( "left" in obj ) {
this . offset . click . left = obj . left + this . margins . left ;
}
if ( "right" in obj ) {
this . offset . click . left = this . helperProportions . width - obj . right + this . margins . left ;
}
if ( "top" in obj ) {
this . offset . click . top = obj . top + this . margins . top ;
}
if ( "bottom" in obj ) {
this . offset . click . top = this . helperProportions . height - obj . bottom + this . margins . top ;
}
} ,
_getParentOffset : function ( ) {
//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 ] ) ) {
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 ) ) {
po = { top : 0 , left : 0 } ;
}
return {
top : po . top + ( parseInt ( this . offsetParent . css ( "borderTopWidth" ) , 10 ) || 0 ) ,
left : po . left + ( parseInt ( this . offsetParent . css ( "borderLeftWidth" ) , 10 ) || 0 )
} ;
} ,
_getRelativeOffset : function ( ) {
if ( this . cssPosition === "relative" ) {
var p = this . currentItem . position ( ) ;
return {
top : p . top - ( parseInt ( this . helper . css ( "top" ) , 10 ) || 0 ) + this . scrollParent . scrollTop ( ) ,
left : p . left - ( parseInt ( this . helper . css ( "left" ) , 10 ) || 0 ) + this . scrollParent . scrollLeft ( )
} ;
} else {
return { top : 0 , left : 0 } ;
}
} ,
_cacheMargins : function ( ) {
this . margins = {
left : ( parseInt ( this . currentItem . css ( "marginLeft" ) , 10 ) || 0 ) ,
top : ( parseInt ( this . currentItem . css ( "marginTop" ) , 10 ) || 0 )
} ;
} ,
_cacheHelperProportions : function ( ) {
this . helperProportions = {
width : this . helper . outerWidth ( ) ,
height : this . helper . outerHeight ( )
} ;
} ,
_setContainment : function ( ) {
var ce , co , over ,
o = this . options ;
if ( o . containment === "parent" ) {
o . containment = this . helper [ 0 ] . parentNode ;
}
if ( o . containment === "document" || o . containment === "window" ) {
this . containment = [
0 - this . offset . relative . left - this . offset . parent . left ,
0 - this . offset . relative . top - this . offset . parent . top ,
o . containment === "document" ? 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
] ;
}
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
] ;
}
} ,
_convertPositionTo : function ( d , 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 ) ;
return {
top : (
pos . top + // The absolute mouse position
this . offset . relative . top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
this . offset . parent . top * mod - // The offsetParent's offset without borders (offset + border)
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollTop ( ) : ( scrollIsRootNode ? 0 : scroll . scrollTop ( ) ) ) * mod )
) ,
left : (
pos . left + // The absolute mouse position
this . offset . relative . left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
this . offset . parent . left * mod - // The offsetParent's offset without borders (offset + border)
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollLeft ( ) : scrollIsRootNode ? 0 : scroll . scrollLeft ( ) ) * mod )
)
} ;
} ,
_generatePosition : function ( event ) {
var 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 ) ;
// 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 ] ) ) {
this . offset . relative = this . _getRelativeOffset ( ) ;
}
/ *
* - Position constraining -
* Constrain the position to a mix of grid , containment .
* /
if ( this . originalPosition ) { //If we are not dragging yet, we won't check for options
if ( this . containment ) {
if ( event . pageX - this . offset . click . left < this . containment [ 0 ] ) {
pageX = this . containment [ 0 ] + this . offset . click . left ;
}
if ( event . pageY - this . offset . click . top < this . containment [ 1 ] ) {
pageY = this . containment [ 1 ] + this . offset . click . top ;
}
if ( event . pageX - this . offset . click . left > this . containment [ 2 ] ) {
pageX = this . containment [ 2 ] + this . offset . click . left ;
}
if ( event . pageY - this . offset . click . top > this . containment [ 3 ] ) {
pageY = this . containment [ 3 ] + this . offset . click . top ;
}
}
if ( o . grid ) {
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 ;
}
}
return {
top : (
pageY - // The absolute mouse position
this . offset . click . top - // Click offset (relative to the element)
this . offset . relative . top - // Only for relative positioned nodes: Relative offset from element to offset parent
this . offset . parent . top + // The offsetParent's offset without borders (offset + border)
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollTop ( ) : ( scrollIsRootNode ? 0 : scroll . scrollTop ( ) ) ) )
) ,
left : (
pageX - // The absolute mouse position
this . offset . click . left - // Click offset (relative to the element)
this . offset . relative . left - // Only for relative positioned nodes: Relative offset from element to offset parent
this . offset . parent . left + // The offsetParent's offset without borders (offset + border)
( ( this . cssPosition === "fixed" ? - this . scrollParent . scrollLeft ( ) : scrollIsRootNode ? 0 : scroll . scrollLeft ( ) ) )
)
} ;
} ,
_rearrange : function ( event , i , a , hardRefresh ) {
a ? a [ 0 ] . appendChild ( this . placeholder [ 0 ] ) : i . item [ 0 ] . parentNode . insertBefore ( this . placeholder [ 0 ] , ( this . direction === "down" ? i . item [ 0 ] : i . item [ 0 ] . nextSibling ) ) ;
//Various things done here to improve the performance:
// 1. we create a setTimeout, that calls refreshPositions
// 2. on the instance, we have a counter variable, that get's higher after every append
// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
// 4. this lets only the last addition to the timeout stack through
this . counter = this . counter ? ++ this . counter : 1 ;
var counter = this . counter ;
this . _delay ( function ( ) {
if ( counter === this . counter ) {
this . refreshPositions ( ! hardRefresh ) ; //Precompute after each DOM insertion, NOT on mousemove
}
} ) ;
} ,
_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
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 ) ;
}
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 ] = "" ;
}
}
this . currentItem . css ( this . _storedCSS ) . removeClass ( "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 || 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
}
// 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 ) ) ;
}
}
//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 ) {
delayedTriggers . push ( delayEvent ( "deactivate" , this , this . containers [ i ] ) ) ;
}
if ( this . containers [ i ] . containerCache . over ) {
delayedTriggers . push ( delayEvent ( "out" , this , this . containers [ i ] ) ) ;
this . containers [ i ] . containerCache . over = 0 ;
}
}
//Do what was originally in plugins
if ( this . storedCursor ) {
this . document . find ( "body" ) . css ( "cursor" , this . storedCursor ) ;
this . storedStylesheet . remove ( ) ;
}
if ( this . _storedOpacity ) {
this . helper . css ( "opacity" , this . _storedOpacity ) ;
}
if ( this . _storedZIndex ) {
this . helper . css ( "zIndex" , this . _storedZIndex === "auto" ? "" : this . _storedZIndex ) ;
}
this . dragging = false ;
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 ] ) ;
if ( ! this . cancelHelperRemoval ) {
if ( this . helper [ 0 ] !== this . currentItem [ 0 ] ) {
this . helper . remove ( ) ;
}
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 ( ) ) ;
}
this . fromOutside = false ;
return ! this . cancelHelperRemoval ;
} ,
_trigger : function ( ) {
if ( $ . Widget . prototype . _trigger . apply ( this , arguments ) === false ) {
this . cancel ( ) ;
}
} ,
_uiHash : function ( _inst ) {
var inst = _inst || this ;
return {
helper : inst . helper ,
placeholder : inst . placeholder || $ ( [ ] ) ,
position : inst . position ,
originalPosition : inst . originalPosition ,
offset : inst . positionAbs ,
item : inst . currentItem ,
sender : _inst ? _inst . element : null
} ;
}
} ) ;
/ * !
* jQuery UI Menu 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/menu/
* /
var menu = $ . widget ( "ui.menu" , {
version : "1.11.4" ,
defaultElement : "<ul>" ,
delay : 300 ,
options : {
icons : {
submenu : "ui-icon-carat-1-e"
} ,
items : "> *" ,
menus : "ul" ,
position : {
my : "left-1 top" ,
at : "right top"
} ,
role : "menu" ,
// callbacks
blur : null ,
focus : null ,
select : null
} ,
_create : function ( ) {
this . activeMenu = this . element ;
// Flag used to prevent firing of the click handler
// as the event bubbles up through nested menus
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 ( {
role : this . options . role ,
tabIndex : 0
} ) ;
if ( this . options . disabled ) {
this . element
. addClass ( "ui-state-disabled" )
. attr ( "aria-disabled" , "true" ) ;
}
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 ) {
event . preventDefault ( ) ;
} ,
"click .ui-menu-item" : function ( event ) {
var target = $ ( event . target ) ;
if ( ! this . mouseHandled && target . not ( ".ui-state-disabled" ) . length ) {
this . select ( event ) ;
// Only set the mouseHandled flag if the event will bubble, see #9469.
if ( ! event . isPropagationStopped ( ) ) {
this . mouseHandled = true ;
}
// 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 ) {
// Redirect focus to the menu
this . element . trigger ( "focus" , [ true ] ) ;
// If the active item is on the top level, let it stay active.
// Otherwise, blur the active item since it is no longer visible.
if ( this . active && this . active . parents ( ".ui-menu" ) . length === 1 ) {
clearTimeout ( this . timer ) ;
}
}
}
} ,
"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 ) ;
// 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 . 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 ) ;
if ( ! keepActiveItem ) {
this . focus ( event , item ) ;
}
} ,
blur : function ( event ) {
this . _delay ( function ( ) {
if ( ! $ . contains ( this . element [ 0 ] , this . document [ 0 ] . activeElement ) ) {
this . collapseAll ( event ) ;
}
} ) ;
} ,
keydown : "_keydown"
} ) ;
this . refresh ( ) ;
// Clicks outside of a menu collapse any open menus
this . _on ( this . document , {
click : function ( event ) {
if ( this . _closeOnDocumentClick ( event ) ) {
this . collapseAll ( event ) ;
}
// Reset the mouseHandled flag
this . mouseHandled = false ;
}
} ) ;
} ,
_destroy : function ( ) {
// 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" )
. 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" ) ;
} ,
_keydown : function ( event ) {
var match , prev , character , skip ,
preventDefault = true ;
switch ( event . keyCode ) {
case $ . ui . keyCode . PAGE _UP :
this . previousPage ( event ) ;
break ;
case $ . ui . keyCode . PAGE _DOWN :
this . nextPage ( event ) ;
break ;
case $ . ui . keyCode . HOME :
this . _move ( "first" , "first" , event ) ;
break ;
case $ . ui . keyCode . END :
this . _move ( "last" , "last" , event ) ;
break ;
case $ . ui . keyCode . UP :
this . previous ( event ) ;
break ;
case $ . ui . keyCode . DOWN :
this . next ( event ) ;
break ;
case $ . ui . keyCode . LEFT :
this . collapse ( event ) ;
break ;
case $ . ui . keyCode . RIGHT :
if ( this . active && ! this . active . is ( ".ui-state-disabled" ) ) {
this . expand ( event ) ;
}
break ;
case $ . ui . keyCode . ENTER :
case $ . ui . keyCode . SPACE :
this . _activate ( event ) ;
break ;
case $ . ui . keyCode . ESCAPE :
this . collapse ( event ) ;
break ;
default :
preventDefault = false ;
prev = this . previousFilter || "" ;
character = String . fromCharCode ( event . keyCode ) ;
skip = false ;
clearTimeout ( this . filterTimer ) ;
if ( character === prev ) {
skip = true ;
} else {
character = prev + character ;
}
match = this . _filterMenuItems ( character ) ;
match = skip && match . index ( this . active . next ( ) ) !== - 1 ?
this . active . nextAll ( ".ui-menu-item" ) :
match ;
// If no matches on the current filter, reset to the last character pressed
// to move down the menu to the first item that starts with that character
if ( ! match . length ) {
character = String . fromCharCode ( event . keyCode ) ;
match = this . _filterMenuItems ( character ) ;
}
if ( match . length ) {
this . focus ( event , match ) ;
this . previousFilter = character ;
this . filterTimer = this . _delay ( function ( ) {
delete this . previousFilter ;
} , 1000 ) ;
} else {
delete this . previousFilter ;
}
}
if ( preventDefault ) {
event . preventDefault ( ) ;
}
} ,
_activate : function ( event ) {
if ( ! this . active . is ( ".ui-state-disabled" ) ) {
if ( this . active . is ( "[aria-haspopup='true']" ) ) {
this . expand ( event ) ;
} else {
this . select ( event ) ;
}
}
} ,
refresh : function ( ) {
var menus , items ,
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 ) ;
// Initialize nested menus
submenus . filter ( ":not(.ui-menu)" )
. addClass ( "ui-menu ui-widget ui-widget-content ui-front" )
. hide ( )
. attr ( {
role : this . options . role ,
"aria-hidden" : "true" ,
"aria-expanded" : "false"
} )
. each ( function ( ) {
var menu = $ ( this ) ,
item = menu . parent ( ) ,
submenuCarat = $ ( "<span>" )
. addClass ( "ui-menu-icon ui-icon " + icon )
. data ( "ui-menu-submenu-carat" , true ) ;
item
. attr ( "aria-haspopup" , "true" )
. prepend ( submenuCarat ) ;
menu . attr ( "aria-labelledby" , item . attr ( "id" ) ) ;
} ) ;
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 ( ) {
var item = $ ( this ) ;
if ( that . _isDivider ( item ) ) {
item . addClass ( "ui-widget-content ui-menu-divider" ) ;
}
} ) ;
// 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 ( )
} ) ;
// Add aria-disabled attribute to any disabled menu item
items . filter ( ".ui-state-disabled" ) . attr ( "aria-disabled" , "true" ) ;
// If the active item has been removed, blur the menu
if ( this . active && ! $ . contains ( this . element [ 0 ] , this . active [ 0 ] ) ) {
this . blur ( ) ;
}
} ,
_itemRole : function ( ) {
return {
menu : "menuitem" ,
listbox : "option"
} [ this . options . role ] ;
} ,
_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 ) ;
}
this . _super ( key , value ) ;
} ,
focus : function ( event , item ) {
var nested , focused ;
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" ) ;
// Only update aria-activedescendant if there's a role
// otherwise we assume focus is managed elsewhere
if ( this . options . role ) {
this . element . attr ( "aria-activedescendant" , focused . attr ( "id" ) ) ;
}
// Highlight active parent menu item, if any
this . active
. parent ( )
. closest ( ".ui-menu-item" )
. addClass ( "ui-state-active" ) ;
if ( event && event . type === "keydown" ) {
this . _close ( ) ;
} else {
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 . activeMenu = item . parent ( ) ;
this . _trigger ( "focus" , event , { item : item } ) ;
} ,
_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 ;
offset = item . offset ( ) . top - this . activeMenu . offset ( ) . top - borderTop - paddingTop ;
scroll = this . activeMenu . scrollTop ( ) ;
elementHeight = this . activeMenu . height ( ) ;
itemHeight = item . outerHeight ( ) ;
if ( offset < 0 ) {
this . activeMenu . scrollTop ( scroll + offset ) ;
} else if ( offset + itemHeight > elementHeight ) {
this . activeMenu . scrollTop ( scroll + offset - elementHeight + itemHeight ) ;
}
}
} ,
blur : function ( event , fromFocus ) {
if ( ! fromFocus ) {
clearTimeout ( this . timer ) ;
}
if ( ! this . active ) {
return ;
}
this . active . removeClass ( "ui-state-focus" ) ;
this . active = null ;
this . _trigger ( "blur" , event , { item : this . active } ) ;
} ,
_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
if ( submenu . attr ( "aria-hidden" ) !== "true" ) {
return ;
}
this . timer = this . _delay ( function ( ) {
this . _close ( ) ;
this . _open ( submenu ) ;
} , this . delay ) ;
} ,
_open : function ( submenu ) {
var position = $ . extend ( {
of : this . active
} , this . options . position ) ;
clearTimeout ( this . timer ) ;
this . element . find ( ".ui-menu" ) . not ( submenu . parents ( ".ui-menu" ) )
. hide ( )
. attr ( "aria-hidden" , "true" ) ;
submenu
. show ( )
. removeAttr ( "aria-hidden" )
. attr ( "aria-expanded" , "true" )
. position ( position ) ;
} ,
collapseAll : function ( event , all ) {
clearTimeout ( this . timer ) ;
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 ( ! currentMenu . length ) {
currentMenu = this . element ;
}
this . _close ( currentMenu ) ;
this . blur ( event ) ;
this . activeMenu = currentMenu ;
} , this . delay ) ;
} ,
// With no arguments, closes the currently active menu - if nothing is active
// it closes all menus. If passed an argument, it will search for menus BELOW
_close : function ( startMenu ) {
if ( ! startMenu ) {
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" ) ;
} ,
_closeOnDocumentClick : function ( event ) {
return ! $ ( event . target ) . closest ( ".ui-menu" ) . length ;
} ,
_isDivider : function ( item ) {
// Match hyphen, em dash, en dash
return ! /[^\-\u2014\u2013\s]/ . test ( item . text ( ) ) ;
} ,
collapse : function ( event ) {
var newItem = this . active &&
this . active . parent ( ) . closest ( ".ui-menu-item" , this . element ) ;
if ( newItem && newItem . length ) {
this . _close ( ) ;
this . focus ( event , newItem ) ;
}
} ,
expand : function ( event ) {
var newItem = this . active &&
this . active
. children ( ".ui-menu " )
. 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 . focus ( event , newItem ) ;
} ) ;
}
} ,
next : function ( event ) {
this . _move ( "next" , "first" , event ) ;
} ,
previous : function ( event ) {
this . _move ( "prev" , "last" , event ) ;
} ,
isFirstItem : function ( ) {
return this . active && ! this . active . prevAll ( ".ui-menu-item" ) . length ;
} ,
isLastItem : function ( ) {
return this . active && ! this . active . nextAll ( ".ui-menu-item" ) . length ;
} ,
_move : function ( direction , filter , event ) {
var next ;
if ( this . active ) {
if ( direction === "first" || direction === "last" ) {
next = this . active
[ direction === "first" ? "prevAll" : "nextAll" ] ( ".ui-menu-item" )
. eq ( - 1 ) ;
} else {
next = this . active
[ direction + "All" ] ( ".ui-menu-item" )
. eq ( 0 ) ;
}
}
if ( ! next || ! next . length || ! this . active ) {
next = this . activeMenu . find ( this . options . items ) [ filter ] ( ) ;
}
this . focus ( event , next ) ;
} ,
nextPage : function ( event ) {
var item , base , height ;
if ( ! this . active ) {
this . next ( event ) ;
return ;
}
if ( this . isLastItem ( ) ) {
return ;
}
if ( this . _hasScroll ( ) ) {
base = this . active . offset ( ) . top ;
height = this . element . height ( ) ;
this . active . nextAll ( ".ui-menu-item" ) . each ( function ( ) {
item = $ ( this ) ;
return item . offset ( ) . top - base - height < 0 ;
} ) ;
this . focus ( event , item ) ;
} else {
this . focus ( event , this . activeMenu . find ( this . options . items )
[ ! this . active ? "first" : "last" ] ( ) ) ;
}
} ,
previousPage : function ( event ) {
var item , base , height ;
if ( ! this . active ) {
this . next ( event ) ;
return ;
}
if ( this . isFirstItem ( ) ) {
return ;
}
if ( this . _hasScroll ( ) ) {
base = this . active . offset ( ) . top ;
height = this . element . height ( ) ;
this . active . prevAll ( ".ui-menu-item" ) . each ( function ( ) {
item = $ ( this ) ;
return item . offset ( ) . top - base + height > 0 ;
} ) ;
this . focus ( event , item ) ;
} else {
this . focus ( event , this . activeMenu . find ( this . options . items ) . first ( ) ) ;
}
} ,
_hasScroll : function ( ) {
return this . element . outerHeight ( ) < this . element . prop ( "scrollHeight" ) ;
} ,
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" ) ;
var ui = { item : this . active } ;
if ( ! this . active . has ( ".ui-menu" ) . length ) {
this . collapseAll ( event , true ) ;
}
this . _trigger ( "select" , event , ui ) ;
} ,
_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 ( ) ) ) ;
} ) ;
}
} ) ;
/ * !
* jQuery UI Autocomplete 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/autocomplete/
* /
$ . widget ( "ui.autocomplete" , {
version : "1.11.4" ,
defaultElement : "<input>" ,
options : {
appendTo : null ,
autoFocus : false ,
delay : 300 ,
minLength : 1 ,
position : {
my : "left top" ,
at : "left bottom" ,
collision : "none"
} ,
source : null ,
// callbacks
change : null ,
close : null ,
focus : null ,
open : null ,
response : null ,
search : null ,
select : null
} ,
requestIndex : 0 ,
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
// Unfortunately the code for & in keypress is the same as the up arrow,
// so we use the suppressKeyPressRepeat flag to avoid handling keypress
// events when we know the keydown event was used to modify the
// search term. #7799
var suppressKeyPress , suppressKeyPressRepeat , suppressInput ,
nodeName = this . element [ 0 ] . nodeName . toLowerCase ( ) ,
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" ) ;
this . valueMethod = this . element [ isTextarea || isInput ? "val" : "text" ] ;
this . isNewMenu = true ;
this . element
. addClass ( "ui-autocomplete-input" )
. attr ( "autocomplete" , "off" ) ;
this . _on ( this . element , {
keydown : function ( event ) {
if ( this . element . prop ( "readOnly" ) ) {
suppressKeyPress = true ;
suppressInput = true ;
suppressKeyPressRepeat = true ;
return ;
}
suppressKeyPress = false ;
suppressInput = false ;
suppressKeyPressRepeat = false ;
var keyCode = $ . ui . keyCode ;
switch ( event . keyCode ) {
case keyCode . PAGE _UP :
suppressKeyPress = true ;
this . _move ( "previousPage" , event ) ;
break ;
case keyCode . PAGE _DOWN :
suppressKeyPress = true ;
this . _move ( "nextPage" , event ) ;
break ;
case keyCode . UP :
suppressKeyPress = true ;
this . _keyEvent ( "previous" , event ) ;
break ;
case keyCode . DOWN :
suppressKeyPress = true ;
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 ;
event . preventDefault ( ) ;
this . menu . select ( event ) ;
}
break ;
case keyCode . TAB :
if ( this . menu . active ) {
this . menu . select ( event ) ;
}
break ;
case keyCode . ESCAPE :
if ( this . menu . element . is ( ":visible" ) ) {
if ( ! this . isMultiLine ) {
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
event . preventDefault ( ) ;
}
break ;
default :
suppressKeyPressRepeat = true ;
// search timeout should be triggered before the input value is changed
this . _searchTimeout ( event ) ;
break ;
}
} ,
keypress : function ( event ) {
if ( suppressKeyPress ) {
suppressKeyPress = false ;
if ( ! this . isMultiLine || this . menu . element . is ( ":visible" ) ) {
event . preventDefault ( ) ;
}
return ;
}
if ( suppressKeyPressRepeat ) {
return ;
}
// replicate some key handlers to allow them to repeat in Firefox and Opera
var keyCode = $ . ui . keyCode ;
switch ( event . keyCode ) {
case keyCode . PAGE _UP :
this . _move ( "previousPage" , event ) ;
break ;
case keyCode . PAGE _DOWN :
this . _move ( "nextPage" , event ) ;
break ;
case keyCode . UP :
this . _keyEvent ( "previous" , event ) ;
break ;
case keyCode . DOWN :
this . _keyEvent ( "next" , event ) ;
break ;
}
} ,
input : function ( event ) {
if ( suppressInput ) {
suppressInput = false ;
event . preventDefault ( ) ;
return ;
}
this . _searchTimeout ( event ) ;
} ,
focus : function ( ) {
this . selectedItem = null ;
this . previous = this . _value ( ) ;
} ,
blur : function ( event ) {
if ( this . cancelBlur ) {
delete this . cancelBlur ;
return ;
}
clearTimeout ( this . searching ) ;
this . close ( event ) ;
this . _change ( event ) ;
}
} ) ;
this . _initSource ( ) ;
this . menu = $ ( "<ul>" )
. addClass ( "ui-autocomplete ui-front" )
. appendTo ( this . _appendTo ( ) )
. menu ( {
// disable ARIA support, the live region takes care of that
role : null
} )
. hide ( )
. menu ( "instance" ) ;
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 ( ) {
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 ( ) ;
}
} ) ;
} ) ;
}
} ,
menufocus : function ( event , ui ) {
var label , item ;
// support: Firefox
// Prevent accidental activation of menu items in Firefox (#7024 #9118)
if ( this . isNewMenu ) {
this . isNewMenu = false ;
if ( event . originalEvent && /^mouse/ . test ( event . originalEvent . type ) ) {
this . menu . blur ( ) ;
this . document . one ( "mousemove" , function ( ) {
$ ( event . target ) . trigger ( event . originalEvent ) ;
} ) ;
return ;
}
}
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 ) ;
}
}
// Announce the value in the liveRegion
label = ui . item . attr ( "aria-label" ) || item . value ;
if ( label && $ . trim ( label ) . length ) {
this . liveRegion . children ( ) . hide ( ) ;
$ ( "<div>" ) . text ( label ) . appendTo ( this . liveRegion ) ;
}
} ,
menuselect : function ( event , ui ) {
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 ( ) ;
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 . 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 ( ) ;
this . close ( event ) ;
this . selectedItem = item ;
}
} ) ;
this . liveRegion = $ ( "<span>" , {
role : "status" ,
"aria-live" : "assertive" ,
"aria-relevant" : "additions"
} )
. addClass ( "ui-helper-hidden-accessible" )
. appendTo ( this . document [ 0 ] . body ) ;
// 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 . menu . element . remove ( ) ;
this . liveRegion . remove ( ) ;
} ,
_setOption : function ( key , value ) {
this . _super ( key , value ) ;
if ( key === "source" ) {
this . _initSource ( ) ;
}
if ( key === "appendTo" ) {
this . menu . element . appendTo ( this . _appendTo ( ) ) ;
}
if ( key === "disabled" && value && this . xhr ) {
this . xhr . abort ( ) ;
}
} ,
_appendTo : function ( ) {
var element = this . options . appendTo ;
if ( element ) {
element = element . jquery || element . nodeType ?
$ ( element ) :
this . document . find ( element ) . eq ( 0 ) ;
}
if ( ! element || ! element [ 0 ] ) {
element = this . element . closest ( ".ui-front" ) ;
}
if ( ! element . length ) {
element = this . document [ 0 ] . body ;
}
return element ;
} ,
_initSource : function ( ) {
var array , url ,
that = this ;
if ( $ . isArray ( this . options . source ) ) {
array = this . options . source ;
this . source = function ( request , response ) {
response ( $ . ui . autocomplete . filter ( array , request . term ) ) ;
} ;
} else if ( typeof this . options . source === "string" ) {
url = this . options . source ;
this . source = function ( request , response ) {
if ( that . xhr ) {
that . xhr . abort ( ) ;
}
that . xhr = $ . ajax ( {
url : url ,
data : request ,
dataType : "json" ,
success : function ( data ) {
response ( data ) ;
} ,
error : function ( ) {
response ( [ ] ) ;
}
} ) ;
} ;
} else {
this . source = this . options . source ;
}
} ,
_searchTimeout : function ( event ) {
clearTimeout ( this . searching ) ;
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 ( ) ,
menuVisible = this . menu . element . is ( ":visible" ) ,
modifierKey = event . altKey || event . ctrlKey || event . metaKey || event . shiftKey ;
if ( ! equalValues || ( equalValues && ! menuVisible && ! modifierKey ) ) {
this . selectedItem = null ;
this . search ( null , event ) ;
}
} , this . options . delay ) ;
} ,
search : function ( value , event ) {
value = value != null ? value : this . _value ( ) ;
// always save the actual value, not the one passed as an argument
this . term = this . _value ( ) ;
if ( value . length < this . options . minLength ) {
return this . close ( event ) ;
}
if ( this . _trigger ( "search" , event ) === false ) {
return ;
}
return this . _search ( value ) ;
} ,
_search : function ( value ) {
this . pending ++ ;
this . element . addClass ( "ui-autocomplete-loading" ) ;
this . cancelSearch = false ;
this . source ( { term : value } , this . _response ( ) ) ;
} ,
_response : function ( ) {
var index = ++ this . requestIndex ;
return $ . proxy ( function ( content ) {
if ( index === this . requestIndex ) {
this . _ _response ( content ) ;
}
this . pending -- ;
if ( ! this . pending ) {
this . element . removeClass ( "ui-autocomplete-loading" ) ;
}
} , this ) ;
} ,
_ _response : function ( content ) {
if ( content ) {
content = this . _normalize ( content ) ;
}
this . _trigger ( "response" , null , { content : content } ) ;
if ( ! this . options . disabled && content && content . length && ! this . cancelSearch ) {
this . _suggest ( content ) ;
this . _trigger ( "open" ) ;
} else {
// use ._close() instead of .close() so we don't cancel future searches
this . _close ( ) ;
}
} ,
close : function ( event ) {
this . cancelSearch = true ;
this . _close ( event ) ;
} ,
_close : function ( event ) {
if ( this . menu . element . is ( ":visible" ) ) {
this . menu . element . hide ( ) ;
this . menu . blur ( ) ;
this . isNewMenu = true ;
this . _trigger ( "close" , event ) ;
}
} ,
_change : function ( event ) {
if ( this . previous !== this . _value ( ) ) {
this . _trigger ( "change" , event , { item : this . selectedItem } ) ;
}
} ,
_normalize : function ( items ) {
// assume all items have the right format when the first item is complete
if ( items . length && items [ 0 ] . label && items [ 0 ] . value ) {
return items ;
}
return $ . map ( items , function ( item ) {
if ( typeof item === "string" ) {
return {
label : item ,
value : item
} ;
}
return $ . extend ( { } , item , {
label : item . label || item . value ,
value : item . value || item . label
} ) ;
} ) ;
} ,
_suggest : function ( items ) {
var ul = this . menu . element . empty ( ) ;
this . _renderMenu ( ul , items ) ;
this . isNewMenu = true ;
this . menu . refresh ( ) ;
// size and position menu
ul . show ( ) ;
this . _resizeMenu ( ) ;
ul . position ( $ . extend ( {
of : this . element
} , this . options . position ) ) ;
if ( this . options . autoFocus ) {
this . menu . next ( ) ;
}
} ,
_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 ,
this . element . outerWidth ( )
) ) ;
} ,
_renderMenu : function ( ul , items ) {
var that = this ;
$ . each ( items , function ( index , item ) {
that . _renderItemData ( ul , item ) ;
} ) ;
} ,
_renderItemData : function ( ul , item ) {
return this . _renderItem ( ul , item ) . data ( "ui-autocomplete-item" , item ) ;
} ,
_renderItem : function ( ul , item ) {
return $ ( "<li>" ) . text ( item . label ) . appendTo ( ul ) ;
} ,
_move : function ( direction , event ) {
if ( ! this . menu . element . is ( ":visible" ) ) {
this . search ( null , event ) ;
return ;
}
if ( this . menu . isFirstItem ( ) && /^previous/ . test ( direction ) ||
this . menu . isLastItem ( ) && /^next/ . test ( direction ) ) {
if ( ! this . isMultiLine ) {
this . _value ( this . term ) ;
}
this . menu . blur ( ) ;
return ;
}
this . menu [ direction ] ( event ) ;
} ,
widget : function ( ) {
return this . menu . element ;
} ,
_value : function ( ) {
return this . valueMethod . apply ( this . element , arguments ) ;
} ,
_keyEvent : function ( keyEvent , event ) {
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
event . preventDefault ( ) ;
}
}
} ) ;
$ . extend ( $ . ui . autocomplete , {
escapeRegex : function ( value ) {
return value . replace ( /[\-\[\]{}()*+?.,\\\^$|#\s]/g , "\\$&" ) ;
} ,
filter : function ( array , term ) {
var matcher = new RegExp ( $ . ui . autocomplete . escapeRegex ( term ) , "i" ) ;
return $ . grep ( array , function ( value ) {
return matcher . test ( value . label || value . value || value ) ;
} ) ;
}
} ) ;
// 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 , {
options : {
messages : {
noResults : "No search results." ,
results : function ( amount ) {
return amount + ( amount > 1 ? " results are" : " result is" ) +
" available, use up and down arrow keys to navigate." ;
}
}
} ,
_ _response : function ( content ) {
var message ;
this . _superApply ( arguments ) ;
if ( this . options . disabled || this . cancelSearch ) {
return ;
}
if ( content && content . length ) {
message = this . options . messages . results ( content . length ) ;
} else {
message = this . options . messages . noResults ;
}
this . liveRegion . children ( ) . hide ( ) ;
$ ( "<div>" ) . text ( message ) . appendTo ( this . liveRegion ) ;
}
} ) ;
var autocomplete = $ . ui . autocomplete ;
/ * !
* jQuery UI Datepicker 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/datepicker/
* /
$ . extend ( $ . ui , { datepicker : { version : "1.11.4" } } ) ;
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
// <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 ;
}
/ * D a t e p i c k e r m a n a g e r .
Use the singleton instance of this class , $ . datepicker , to interact with the date picker .
Settings for ( groups of ) date pickers are maintained in an instance object ,
allowing multiple different settings on the same page . * /
function Datepicker ( ) {
this . _curInst = null ; // The current instance in use
this . _keyEvent = false ; // If the last event was a key event
this . _disabledInputs = [ ] ; // List of date picker inputs that have been disabled
this . _datepickerShowing = false ; // True if the popup picker is showing , false if not
this . _inDialog = false ; // True if showing within a "dialog", false if not
this . _mainDivId = "ui-datepicker-div" ; // The ID of the main datepicker division
this . _inlineClass = "ui-datepicker-inline" ; // The name of the inline marker class
this . _appendClass = "ui-datepicker-append" ; // The name of the append marker class
this . _triggerClass = "ui-datepicker-trigger" ; // The name of the trigger marker class
this . _dialogClass = "ui-datepicker-dialog" ; // The name of the dialog marker class
this . _disableClass = "ui-datepicker-disabled" ; // The name of the disabled covering marker class
this . _unselectableClass = "ui-datepicker-unselectable" ; // The name of the unselectable cell marker class
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
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
weekHeader : "Wk" , // Column header for week of the year
dateFormat : "mm/dd/yy" , // See format options on parseDate
firstDay : 0 , // The first day of the week, Sun = 0, Mon = 1, ...
isRTL : false , // True if right-to-left language, false if left-to-right
showMonthAfterYear : false , // True if the year select precedes month, false for month then year
yearSuffix : "" // Additional text to append to the year in the month headers
} ;
this . _defaults = { // Global defaults for all the date picker instances
showOn : "focus" , // "focus" for popup on focus,
// "button" for trigger button, or "both" for either
showAnim : "fadeIn" , // Name of jQuery animation for popup
showOptions : { } , // Options for enhanced animations
defaultDate : null , // Used when field is blank: actual date,
// +/-number for offset from today, null for today
appendText : "" , // Display text following the input box, e.g. showing the format
buttonText : "..." , // Text for trigger button
buttonImage : "" , // URL for trigger button image
buttonImageOnly : false , // True if the image appears alone, false if it appears on a button
hideIfNoPrevNext : false , // True to hide next/previous month links
// if not applicable, false to just disable them
navigationAsDateFormat : false , // True if date formatting applied to prev/today/next links
gotoCurrent : false , // True if today link goes back to current selection instead
changeMonth : false , // True if month can be selected directly, false if only prev/next
changeYear : false , // True if year can be selected directly, false if only prev/next
yearRange : "c-10:c+10" , // Range of years to display in drop-down,
// either relative to today's year (-nn:+nn), relative to currently displayed year
// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
showOtherMonths : false , // True to show dates in other months, false to leave blank
selectOtherMonths : false , // True to allow selection of dates in other months, false for unselectable
showWeek : false , // True to show week of the year, false to not show it
calculateWeek : this . iso8601Week , // How to calculate the week of the year,
// takes a Date and returns the number of the week for it
shortYearCutoff : "+10" , // Short year values < this are in the current century,
// > this are in the previous century,
// string value starting with "+" for current year + value
minDate : null , // The earliest selectable date, or null for no limit
maxDate : null , // The latest selectable date, or null for no limit
duration : "fast" , // Duration of display/closure
beforeShowDay : null , // Function that takes a date and returns an array with
// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
// [2] = cell title (optional), e.g. $.datepicker.noWeekends
beforeShow : null , // Function that takes an input field and
// returns a set of custom settings for the date picker
onSelect : null , // Define a callback function when a date is selected
onChangeMonthYear : null , // Define a callback function when the month or year is changed
onClose : null , // Define a callback function when the datepicker is closed
numberOfMonths : 1 , // Number of months to show at a time
showCurrentAtPos : 0 , // The position in multipe months at which to show the current month (starting at 0)
stepMonths : 1 , // Number of months to step back/forward
stepBigMonths : 12 , // Number of months to step back/forward for the big links
altField : "" , // Selector for an alternate field to store selected dates into
altFormat : "" , // The date format to use for the alternate field
constrainInput : true , // The input is constrained by the current date format
showButtonPanel : false , // True to show button panel, false to not show it
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 [ "" ] ) ;
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>" ) ) ;
}
$ . extend ( Datepicker . prototype , {
/* Class name added to elements to indicate already configured with a date picker. */
markerClassName : "hasDatepicker" ,
//Keep track of the maximum number of rows displayed (see #7043)
maxRows : 4 ,
// TODO rename to "widget" when switching to widget factory
_widgetDatepicker : function ( ) {
return this . dpDiv ;
} ,
/ * O v e r r i d e t h e d e f a u l t s e t t i n g s f o r a l l i n s t a n c e s o f t h e d a t e p i c k e r .
* @ param settings object - the new settings to use as defaults ( anonymous object )
* @ return the manager object
* /
setDefaults : function ( settings ) {
datepicker _extendRemove ( this . _defaults , settings || { } ) ;
return this ;
} ,
/ * A t t a c h t h e d a t e p i c k e r t o a j Q u e r y s e l e c t i o n .
* @ 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 ) {
var nodeName , inline , inst ;
nodeName = target . nodeName . toLowerCase ( ) ;
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 ) ;
}
} ,
/* 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
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>" ) ) ) } ;
} ,
/* Attach the date picker to an input field. */
_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 ) ;
//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
if ( inst . settings . disabled ) {
this . _disableDatepicker ( target ) ;
}
} ,
/* Make attachments based on settings. */
_attachments : function ( input , inst ) {
var showOn , buttonText , buttonImage ,
appendText = this . _get ( inst , "appendText" ) ,
isRTL = this . _get ( inst , "isRTL" ) ;
if ( inst . append ) {
inst . append . remove ( ) ;
}
if ( appendText ) {
inst . append = $ ( "<span class='" + this . _appendClass + "'>" + appendText + "</span>" ) ;
input [ isRTL ? "before" : "after" ] ( inst . append ) ;
}
input . unbind ( "focus" , this . _showDatepicker ) ;
if ( inst . trigger ) {
inst . trigger . remove ( ) ;
}
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 ] ) {
$ . datepicker . _hideDatepicker ( ) ;
} else if ( $ . datepicker . _datepickerShowing && $ . datepicker . _lastInput !== input [ 0 ] ) {
$ . datepicker . _hideDatepicker ( ) ;
$ . datepicker . _showDatepicker ( input [ 0 ] ) ;
} else {
$ . datepicker . _showDatepicker ( input [ 0 ] ) ;
}
return false ;
} ) ;
}
} ,
/* Apply the maximum length for the date format. */
_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" ) ;
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 ;
maxI = i ;
}
}
return maxI ;
} ;
date . setMonth ( findMax ( this . _get ( inst , ( dateFormat . match ( /MM/ ) ?
"monthNames" : "monthNamesShort" ) ) ) ) ;
date . setDate ( findMax ( this . _get ( inst , ( dateFormat . match ( /DD/ ) ?
"dayNames" : "dayNamesShort" ) ) ) + 20 - date . getDay ( ) ) ;
}
inst . input . attr ( "size" , this . _formatDate ( inst , date ) . length ) ;
}
} ,
/* Attach an inline date picker to a div. */
_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 ) ;
//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
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" ) ;
} ,
/ * P o p - u p t h e d a t e p i c k e r i n a " d i a l o g " b o x .
* @ param input element - ignored
* @ param date string or Date - the initial date to display
* @ param onSelect function - the function to call when a date is selected
* @ param settings object - update the dialog date picker instance ' s settings ( anonymous object )
* @ param pos int [ 2 ] - coordinates for the dialog ' s position within the screen or
* event - with x / y coordinates or
* leave empty for default ( screen centre )
* @ return the manager object
* /
_dialogDatepicker : function ( input , date , onSelect , settings , pos ) {
var id , browserWidth , browserHeight , scrollX , scrollY ,
inst = this . _dialogInst ; // internal instance
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 ) ;
inst . settings = { } ;
$ . 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 ) ;
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 ] ;
}
// 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 ) ;
}
$ . data ( this . _dialogInput [ 0 ] , "datepicker" , inst ) ;
return this ;
} ,
/ * D e t a c h a d a t e p i c k e r f r o m i t s c o n t r o l .
* @ param target element - the target input field or division or span
* /
_destroyDatepicker : function ( target ) {
var nodeName ,
$target = $ ( target ) ,
inst = $ . data ( target , "datepicker" ) ;
if ( ! $target . hasClass ( this . markerClassName ) ) {
return ;
}
nodeName = target . nodeName . toLowerCase ( ) ;
$ . 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 ( ) ;
}
if ( datepicker _instActive === inst ) {
datepicker _instActive = null ;
}
} ,
/ * E n a b l e t h e d a t e p i c k e r t o a j Q u e r y s e l e c t i o n .
* @ param target element - the target input field or division or span
* /
_enableDatepicker : function ( target ) {
var nodeName , inline ,
$target = $ ( target ) ,
inst = $ . data ( target , "datepicker" ) ;
if ( ! $target . hasClass ( this . markerClassName ) ) {
return ;
}
nodeName = target . nodeName . toLowerCase ( ) ;
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 ) ;
}
this . _disabledInputs = $ . map ( this . _disabledInputs ,
function ( value ) { return ( value === target ? null : value ) ; } ) ; // delete entry
} ,
/ * D i s a b l e t h e d a t e p i c k e r t o a j Q u e r y s e l e c t i o n .
* @ param target element - the target input field or division or span
* /
_disableDatepicker : function ( target ) {
var nodeName , inline ,
$target = $ ( target ) ,
inst = $ . data ( target , "datepicker" ) ;
if ( ! $target . hasClass ( this . markerClassName ) ) {
return ;
}
nodeName = target . nodeName . toLowerCase ( ) ;
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 ) ;
}
this . _disabledInputs = $ . map ( this . _disabledInputs ,
function ( value ) { return ( value === target ? null : value ) ; } ) ; // delete entry
this . _disabledInputs [ this . _disabledInputs . length ] = target ;
} ,
/ * I s t h e f i r s t f i e l d i n a j Q u e r y c o l l e c t i o n d i s a b l e d a s a d a t e p i c k e r ?
* @ param target element - the target input field or division or span
* @ return boolean - true if disabled , false if enabled
* /
_isDisabledDatepicker : function ( target ) {
if ( ! target ) {
return false ;
}
for ( var i = 0 ; i < this . _disabledInputs . length ; i ++ ) {
if ( this . _disabledInputs [ i ] === target ) {
return true ;
}
}
return false ;
} ,
/ * R e t r i e v e t h e i n s t a n c e d a t a f o r t h e t a r g e t c o n t r o l .
* @ param target element - the target input field or division or span
* @ return object - the associated instance data
* @ throws error if a jQuery problem getting data
* /
_getInst : function ( target ) {
try {
return $ . data ( target , "datepicker" ) ;
}
catch ( err ) {
throw "Missing instance data for this datepicker" ;
}
} ,
/ * U p d a t e o r r e t r i e v e t h e s e t t i n g s f o r a d a t e p i c k e r a t t a c h e d t o a n i n p u t f i e l d o r d i v i s i o n .
* @ param target element - the target input field or division or span
* @ param name object - the new settings to update or
* string - the name of the setting to change or retrieve ,
* when retrieving also "all" for all instance settings or
* "defaults" for all global defaults
* @ 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 ) {
var settings , date , minDate , maxDate ,
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 ) ) ;
}
settings = name || { } ;
if ( typeof name === "string" ) {
settings = { } ;
settings [ name ] = value ;
}
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 ) ;
// 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 ( 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 ) ;
} else {
this . _enableDatepicker ( target ) ;
}
}
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 ) ;
} ,
/ * R e d r a w t h e d a t e p i c k e r a t t a c h e d t o a n i n p u t f i e l d o r d i v i s i o n .
* @ param target element - the target input field or division or span
* /
_refreshDatepicker : function ( target ) {
var inst = this . _getInst ( target ) ;
if ( inst ) {
this . _updateDatepicker ( inst ) ;
}
} ,
/ * S e t t h e d a t e s f o r a j Q u e r y s e l e c t i o n .
* @ 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 ) ;
}
} ,
/ * G e t t h e d a t e ( s ) f o r t h e f i r s t e n t r y i n a j Q u e r y s e l e c t i o n .
* @ param target element - the target input field or division or span
* @ param noDefault boolean - true if no default date is to be used
* @ return Date - the current date
* /
_getDateDatepicker : function ( target , noDefault ) {
var inst = this . _getInst ( target ) ;
if ( inst && ! inst . inline ) {
this . _setDateFromField ( inst , noDefault ) ;
}
return ( inst ? this . _getDate ( inst ) : null ) ;
} ,
/* Handle keystrokes. */
_doKeyDown : function ( event ) {
var onSelect , dateStr , sel ,
inst = $ . datepicker . _getInst ( event . target ) ,
handled = true ,
isRTL = inst . dpDiv . is ( ".ui-datepicker-rtl" ) ;
inst . _keyEvent = true ;
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 ] ) ;
}
onSelect = $ . datepicker . _get ( inst , "onSelect" ) ;
if ( onSelect ) {
dateStr = $ . datepicker . _formatDate ( inst ) ;
// trigger custom callback
onSelect . apply ( ( inst . input ? inst . input [ 0 ] : null ) , [ dateStr , inst ] ) ;
} else {
$ . datepicker . _hideDatepicker ( ) ;
}
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" ) ;
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" ) ;
break ; // next month/year on page down/+ ctrl
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 ) ;
}
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" ) ;
}
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" ) ;
}
// next month/year on alt +left on Mac
break ;
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" ) ;
}
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" ) ;
}
// next month/year on alt +right
break ;
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 {
handled = false ;
}
if ( handled ) {
event . preventDefault ( ) ;
event . stopPropagation ( ) ;
}
} ,
/* Filter entered characters - based on date format. */
_doKeyPress : function ( event ) {
var chars , chr ,
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 ) ;
}
} ,
/* Synchronise manual entry and field/alternate field. */
_doKeyUp : function ( event ) {
var date ,
inst = $ . datepicker . _getInst ( event . target ) ;
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 ) ;
}
}
catch ( err ) {
}
}
return true ;
} ,
/ * P o p - u p t h e d a t e p i c k e r f o r a g i v e n i n p u t f i e l d .
* If false returned from beforeShow event handler do not show .
* @ param input element - the input field attached to the date picker or
* event - if triggered by focus
* /
_showDatepicker : function ( input ) {
input = input . target || input ;
if ( input . nodeName . toLowerCase ( ) !== "input" ) { // find from button/image trigger
input = $ ( "input" , input . parentNode ) [ 0 ] ;
}
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 ) ;
if ( inst && $ . datepicker . _datepickerShowing ) {
$ . datepicker . _hideDatepicker ( $ . datepicker . _curInst . input [ 0 ] ) ;
}
}
beforeShow = $ . datepicker . _get ( inst , "beforeShow" ) ;
beforeShowSettings = beforeShow ? beforeShow . apply ( input , [ input , inst ] ) : { } ;
if ( beforeShowSettings === false ) {
return ;
}
datepicker _extendRemove ( inst . settings , beforeShowSettings ) ;
inst . lastVal = null ;
$ . datepicker . _lastInput = input ;
$ . datepicker . _setDateFromField ( inst ) ;
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
}
isFixed = false ;
$ ( input ) . parents ( ) . each ( function ( ) {
isFixed |= $ ( this ) . css ( "position" ) === "fixed" ;
return ! isFixed ;
} ) ;
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 ) ;
// 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" ) ;
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 ) ;
} else {
inst . dpDiv [ showAnim || "show" ] ( showAnim ? duration : null ) ;
}
if ( $ . datepicker . _shouldFocusInput ( inst ) ) {
inst . input . focus ( ) ;
}
$ . datepicker . _curInst = inst ;
}
} ,
/* Generate the date picker content. */
_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 ) ;
var origyearshtml ,
numMonths = this . _getNumberOfMonths ( inst ) ,
cols = numMonths [ 1 ] ,
width = 17 ,
activeCell = inst . dpDiv . find ( "." + this . _dayOverClass + " a" ) ;
if ( activeCell . length > 0 ) {
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 [ ( 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 ( ) ;
}
// deffered render of the years select (to avoid flashes on Firefox)
if ( inst . yearshtml ) {
origyearshtml = inst . yearshtml ;
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 ) ;
}
origyearshtml = inst . yearshtml = null ;
} , 0 ) ;
}
} ,
// #6694 - don't focus the input if it's already focused
// this breaks the change event in IE
// Support: IE and jQuery <1.9
_shouldFocusInput : function ( inst ) {
return inst . input && inst . input . is ( ":visible" ) && ! inst . input . is ( ":disabled" ) && ! inst . input . is ( ":focus" ) ;
} ,
/* Check positioning to remain on screen. */
_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 ( ) ) ;
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 ) ;
return offset ;
} ,
/* Find an object's position on the screen. */
_findPos : function ( obj ) {
var position ,
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" ] ;
}
position = $ ( obj ) . offset ( ) ;
return [ position . left , position . top ] ;
} ,
/ * H i d e t h e d a t e p i c k e r f r o m v i e w .
* @ param input element - the input field attached to the date picker
* /
_hideDatepicker : function ( input ) {
var showAnim , duration , postProcess , onClose ,
inst = this . _curInst ;
if ( ! inst || ( input && inst !== $ . data ( input , "datepicker" ) ) ) {
return ;
}
if ( this . _datepickerShowing ) {
showAnim = this . _get ( inst , "showAnim" ) ;
duration = this . _get ( inst , "duration" ) ;
postProcess = function ( ) {
$ . 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 ) ;
} else {
inst . dpDiv [ ( showAnim === "slideDown" ? "slideUp" :
( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ] ( ( showAnim ? duration : null ) , postProcess ) ;
}
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 ] ) ;
}
this . _lastInput = null ;
if ( this . _inDialog ) {
this . _dialogInput . css ( { position : "absolute" , left : "0" , top : "-100px" } ) ;
if ( $ . blockUI ) {
$ . unblockUI ( ) ;
$ ( "body" ) . append ( this . dpDiv ) ;
}
}
this . _inDialog = false ;
}
} ,
/* Tidy up after a dialog display. */
_tidyDialog : function ( inst ) {
inst . dpDiv . removeClass ( this . _dialogClass ) . unbind ( ".ui-datepicker-calendar" ) ;
} ,
/* Close date picker if clicked elsewhere. */
_checkExternalClick : function ( event ) {
if ( ! $ . datepicker . _curInst ) {
return ;
}
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 ) ) {
$ . datepicker . _hideDatepicker ( ) ;
}
} ,
/* Adjust one of the date sub-fields. */
_adjustDate : function ( id , offset , period ) {
var target = $ ( id ) ,
inst = this . _getInst ( 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 ) ;
} ,
/* Action for current link. */
_gotoToday : function ( id ) {
var date ,
target = $ ( id ) ,
inst = this . _getInst ( target [ 0 ] ) ;
if ( this . _get ( inst , "gotoCurrent" ) && inst . currentDay ) {
inst . selectedDay = inst . currentDay ;
inst . drawMonth = inst . selectedMonth = inst . currentMonth ;
inst . drawYear = inst . selectedYear = inst . currentYear ;
} else {
date = new Date ( ) ;
inst . selectedDay = date . getDate ( ) ;
inst . drawMonth = inst . selectedMonth = date . getMonth ( ) ;
inst . drawYear = inst . selectedYear = date . getFullYear ( ) ;
}
this . _notifyChange ( inst ) ;
this . _adjustDate ( target ) ;
} ,
/* Action for selecting a new month/year. */
_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 ) ;
this . _notifyChange ( inst ) ;
this . _adjustDate ( target ) ;
} ,
/* Action for selecting a day. */
_selectDay : function ( id , month , year , td ) {
var inst ,
target = $ ( id ) ;
if ( $ ( td ) . hasClass ( this . _unselectableClass ) || this . _isDisabledDatepicker ( target [ 0 ] ) ) {
return ;
}
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 ) ) ;
} ,
/* Erase the input field and hide the date picker. */
_clearDate : function ( id ) {
var target = $ ( id ) ;
this . _selectDate ( target , "" ) ;
} ,
/* Update the input field with the selected date. */
_selectDate : function ( id , dateStr ) {
var onSelect ,
target = $ ( id ) ,
inst = this . _getInst ( target [ 0 ] ) ;
dateStr = ( dateStr != null ? dateStr : this . _formatDate ( inst ) ) ;
if ( inst . input ) {
inst . input . val ( dateStr ) ;
}
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
}
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 = null ;
}
} ,
/* Update any alternate field to synchronise with the main field. */
_updateAlternate : function ( inst ) {
var altFormat , date , dateStr ,
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 ) ; } ) ;
}
} ,
/ * S e t a s b e f o r e S h o w D a y f u n c t i o n t o p r e v e n t s e l e c t i o n o f w e e k e n d s .
* @ param date Date - the date to customise
* @ return [ boolean , string ] - is this date selectable ? , what is its CSS class ?
* /
noWeekends : function ( date ) {
var day = date . getDay ( ) ;
return [ ( day > 0 && day < 6 ) , "" ] ;
} ,
/ * S e t a s c a l c u l a t e W e e k t o d e t e r m i n e t h e w e e k o f t h e y e a r b a s e d o n t h e I S O 8 6 0 1 d e f i n i t i o n .
* @ param date Date - the date to get the week for
* @ return number - the number of the week within the year that contains this date
* /
iso8601Week : function ( date ) {
var time ,
checkDate = new Date ( date . getTime ( ) ) ;
// Find Thursday of this week starting on Monday
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 ;
} ,
/ * P a r s e a s t r i n g v a l u e i n t o a d a t e o b j e c t .
* See formatDate below for the possible formats .
*
* @ param format string - the expected format of the date
* @ param value string - the date in the above format
* @ param settings Object - attributes include :
* shortYearCutoff number - the cutoff year for determining the century ( optional )
* dayNamesShort string [ 7 ] - abbreviated names of the days from Sunday ( optional )
* dayNames string [ 7 ] - names of the days from Sunday ( optional )
* monthNamesShort string [ 12 ] - abbreviated names of the months ( optional )
* 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 ) {
throw "Invalid arguments" ;
}
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 ,
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 ) {
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 ) {
throw "Missing number at position " + iValue ;
}
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 ) {
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 ] ;
iValue += name . length ;
return false ;
}
} ) ;
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 ) ) {
throw "Unexpected literal at position " + iValue ;
}
iValue ++ ;
} ;
for ( iFormat = 0 ; iFormat < format . length ; iFormat ++ ) {
if ( literal ) {
if ( format . charAt ( iFormat ) === "'" && ! lookAhead ( "'" ) ) {
literal = false ;
} else {
checkLiteral ( ) ;
}
} else {
switch ( format . charAt ( iFormat ) ) {
case "d" :
day = getNumber ( "d" ) ;
break ;
case "D" :
getName ( "D" , dayNamesShort , dayNames ) ;
break ;
case "o" :
doy = getNumber ( "o" ) ;
break ;
case "m" :
month = getNumber ( "m" ) ;
break ;
case "M" :
month = getName ( "M" , monthNamesShort , monthNames ) ;
break ;
case "y" :
year = getNumber ( "y" ) ;
break ;
case "@" :
date = new Date ( getNumber ( "@" ) ) ;
year = date . getFullYear ( ) ;
month = date . getMonth ( ) + 1 ;
day = date . getDate ( ) ;
break ;
case "!" :
date = new Date ( ( getNumber ( "!" ) - this . _ticksTo1970 ) / 10000 ) ;
year = date . getFullYear ( ) ;
month = date . getMonth ( ) + 1 ;
day = date . getDate ( ) ;
break ;
case "'" :
if ( lookAhead ( "'" ) ) {
checkLiteral ( ) ;
} else {
literal = true ;
}
break ;
default :
checkLiteral ( ) ;
}
}
}
if ( iValue < value . length ) {
extra = value . substr ( iValue ) ;
if ( ! /^\s+/ . test ( extra ) ) {
throw "Extra/unparsed characters found in date: " + extra ;
}
}
if ( year === - 1 ) {
year = new Date ( ) . getFullYear ( ) ;
} else if ( year < 100 ) {
year += new Date ( ) . getFullYear ( ) - new Date ( ) . getFullYear ( ) % 100 +
( year <= shortYearCutoff ? 0 : - 100 ) ;
}
if ( doy > - 1 ) {
month = 1 ;
day = doy ;
do {
dim = this . _getDaysInMonth ( year , month - 1 ) ;
if ( day <= dim ) {
break ;
}
month ++ ;
day -= dim ;
} while ( true ) ;
}
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 ;
} ,
/* Standard date formats. */
ATOM : "yy-mm-dd" , // RFC 3339 (ISO 8601)
COOKIE : "D, dd M yy" ,
ISO _8601 : "yy-mm-dd" ,
RFC _822 : "D, d M y" ,
RFC _850 : "DD, dd-M-y" ,
RFC _1036 : "D, d M y" ,
RFC _1123 : "D, d M yy" ,
RFC _2822 : "D, d M yy" ,
RSS : "D, d M y" , // RFC 822
TICKS : "!" ,
TIMESTAMP : "@" ,
W3C : "yy-mm-dd" , // ISO 8601
_ticksTo1970 : ( ( ( 1970 - 1 ) * 365 + Math . floor ( 1970 / 4 ) - Math . floor ( 1970 / 100 ) +
Math . floor ( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ) ,
/ * F o r m a t a d a t e o b j e c t i n t o a s t r i n g v a l u e .
* The format can be combinations of the following :
* d - day of month ( no leading zero )
* dd - day of month ( two digit )
* o - day of year ( no leading zeros )
* oo - day of year ( three digit )
* D - day name short
* DD - day name long
* m - month of year ( no leading zero )
* mm - month of year ( two digit )
* M - month name short
* MM - month name long
* y - year ( two digit )
* yy - year ( four digit )
* @ - Unix timestamp ( ms since 01 / 01 / 1970 )
* ! - Windows ticks ( 100 ns since 01 / 01 / 0001 )
* "..." - literal text
* '' - single quote
*
* @ param format string - the desired format of the date
* @ param date Date - the date value to format
* @ param settings Object - attributes include :
* dayNamesShort string [ 7 ] - abbreviated names of the days from Sunday ( optional )
* dayNames string [ 7 ] - names of the days from Sunday ( optional )
* monthNamesShort string [ 12 ] - abbreviated names of the months ( optional )
* monthNames string [ 12 ] - names of the months ( optional )
* @ return string - the date in the above format
* /
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 ,
// Check whether a format character is doubled
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 ) {
var num = "" + value ;
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 ] ) ;
} ,
output = "" ,
literal = false ;
if ( date ) {
for ( iFormat = 0 ; iFormat < format . length ; iFormat ++ ) {
if ( literal ) {
if ( format . charAt ( iFormat ) === "'" && ! lookAhead ( "'" ) ) {
literal = false ;
} else {
output += format . charAt ( iFormat ) ;
}
} else {
switch ( format . charAt ( iFormat ) ) {
case "d" :
output += formatNumber ( "d" , date . getDate ( ) , 2 ) ;
break ;
case "D" :
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 ) ;
break ;
case "m" :
output += formatNumber ( "m" , date . getMonth ( ) + 1 , 2 ) ;
break ;
case "M" :
output += formatName ( "M" , date . getMonth ( ) , monthNamesShort , monthNames ) ;
break ;
case "y" :
output += ( lookAhead ( "y" ) ? date . getFullYear ( ) :
( date . getYear ( ) % 100 < 10 ? "0" : "" ) + date . getYear ( ) % 100 ) ;
break ;
case "@" :
output += date . getTime ( ) ;
break ;
case "!" :
output += date . getTime ( ) * 10000 + this . _ticksTo1970 ;
break ;
case "'" :
if ( lookAhead ( "'" ) ) {
output += "'" ;
} else {
literal = true ;
}
break ;
default :
output += format . charAt ( iFormat ) ;
}
}
}
}
return output ;
} ,
/* Extract all possible characters from the date 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 ) {
iFormat ++ ;
}
return matches ;
} ;
for ( iFormat = 0 ; iFormat < format . length ; iFormat ++ ) {
if ( literal ) {
if ( format . charAt ( iFormat ) === "'" && ! lookAhead ( "'" ) ) {
literal = false ;
} else {
chars += format . charAt ( iFormat ) ;
}
} else {
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 ( "'" ) ) {
chars += "'" ;
} else {
literal = true ;
}
break ;
default :
chars += format . charAt ( iFormat ) ;
}
}
}
return chars ;
} ,
/* Get a setting value, defaulting if necessary. */
_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 ) {
return ;
}
var dateFormat = this . _get ( inst , "dateFormat" ) ,
dates = inst . lastVal = inst . input ? inst . input . val ( ) : null ,
defaultDate = this . _getDefaultDate ( inst ) ,
date = defaultDate ,
settings = this . _getFormatConfig ( inst ) ;
try {
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 ) ;
} ,
/* Retrieve the default date shown on opening. */
_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 ) {
var date = new Date ( ) ;
date . setDate ( date . getDate ( ) + offset ) ;
return date ;
} ,
offsetString = function ( offset ) {
try {
return $ . datepicker . parseDate ( $ . datepicker . _get ( inst , "dateFormat" ) ,
offset , $ . datepicker . _getFormatConfig ( inst ) ) ;
}
catch ( e ) {
// Ignore
}
var date = ( offset . toLowerCase ( ) . match ( /^c/ ) ?
$ . datepicker . _getDate ( inst ) : null ) || new Date ( ) ,
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 ) ;
while ( matches ) {
switch ( matches [ 2 ] || "d" ) {
case "d" : case "D" :
day += parseInt ( matches [ 1 ] , 10 ) ; break ;
case "w" : case "W" :
day += parseInt ( matches [ 1 ] , 10 ) * 7 ; break ;
case "m" : case "M" :
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 ) ) ;
break ;
}
matches = pattern . exec ( offset ) ;
}
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 = ( 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 ) ;
} ,
/ * H a n d l e s w i t c h t o / f r o m d a y l i g h t s a v i n g .
* Hours may be non - zero on daylight saving cut - over :
* > 12 when midnight changeover , but then cannot generate
* midnight datetime , so jump to 1 AM , otherwise reset .
* @ param date ( Date ) the date to check
* @ return ( Date ) the corrected date
* /
_daylightSavingAdjust : function ( date ) {
if ( ! date ) {
return null ;
}
date . setHours ( date . getHours ( ) > 12 ? date . getHours ( ) + 2 : 0 ) ;
return date ;
} ,
/* Set the date(s) directly. */
_setDate : function ( inst , date , noChange ) {
var clear = ! date ,
origMonth = inst . selectedMonth ,
origYear = inst . selectedYear ,
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 ) ;
}
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 ) ) ) ;
return startDate ;
} ,
/ * A t t a c h t h e o n x x x h a n d l e r s . T h e s e a r e d e c l a r e d s t a t i c a l l y s o
* they work with static code transformers like Caja .
* /
_attachHandlers : function ( inst ) {
var stepMonths = this . _get ( inst , "stepMonths" ) ,
id = "#" + inst . id . replace ( /\\\\/g , "\\" ) ;
inst . dpDiv . find ( "[data-handler]" ) . map ( function ( ) {
var handler = {
prev : function ( ) {
$ . datepicker . _adjustDate ( id , - stepMonths , "M" ) ;
} ,
next : function ( ) {
$ . datepicker . _adjustDate ( id , + stepMonths , "M" ) ;
} ,
hide : function ( ) {
$ . datepicker . _hideDatepicker ( ) ;
} ,
today : function ( ) {
$ . datepicker . _gotoToday ( id ) ;
} ,
selectDay : function ( ) {
$ . datepicker . _selectDay ( id , + this . getAttribute ( "data-month" ) , + this . getAttribute ( "data-year" ) , this ) ;
return false ;
} ,
selectMonth : function ( ) {
$ . datepicker . _selectMonthYear ( id , this , "M" ) ;
return false ;
} ,
selectYear : function ( ) {
$ . datepicker . _selectMonthYear ( id , this , "Y" ) ;
return false ;
}
} ;
$ ( this ) . bind ( this . getAttribute ( "data-event" ) , handler [ this . getAttribute ( "data-handler" ) ] ) ;
} ) ;
} ,
/* Generate the HTML for the current state of the date picker. */
_generateHTML : function ( inst ) {
var maxDraw , prevText , prev , nextText , next , currentText , gotoDate ,
controls , buttonPanel , firstDay , showWeek , dayNames , dayNamesMin ,
monthNames , monthNamesShort , beforeShowDay , showOtherMonths ,
selectOtherMonths , defaultDate , html , dow , row , group , col , selectedDate ,
cornerClass , calender , thead , day , daysInMonth , leadDays , curRows , numRows ,
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" ) ,
drawMonth = inst . drawMonth - showCurrentAtPos ,
drawYear = inst . drawYear ;
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 ) {
drawMonth -- ;
if ( drawMonth < 0 ) {
drawMonth = 11 ;
drawYear -- ;
}
}
}
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 ) ) ) ;
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>" ) ) ;
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 ) ?
"<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 ) ;
html = "" ;
dow ;
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 ) ) ;
cornerClass = " ui-corner-all" ;
calender = "" ;
if ( isMultiMonth ) {
calender += "<div class='ui-datepicker-group" ;
if ( numMonths [ 1 ] > 1 ) {
switch ( col ) {
case 0 : calender += " ui-datepicker-group-first" ;
cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ) ; break ;
case numMonths [ 1 ] - 1 : calender += " ui-datepicker-group-last" ;
cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ) ; break ;
default : calender += " ui-datepicker-group-middle" ; cornerClass = "" ; break ;
}
}
calender += "'>" ;
}
calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
( /all|left/ . test ( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
( /all|right/ . test ( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
this . _generateMonthYearHeader ( inst , drawMonth , drawYear , minDate , maxDate ,
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>" ;
}
calender += thead + "</tr></thead><tbody>" ;
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)
this . maxRows = numRows ;
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 += "<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 ( ) ) ?
// 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 ) ;
}
calender += tbody + "</tr>" ;
}
drawMonth ++ ;
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>" : "" ) : "" ) ;
group += calender ;
}
html += group ;
}
html += buttonPanel ;
inst . _keyEvent = false ;
return html ;
} ,
/* Generate the month and year header. */
_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" ) ,
html = "<div class='ui-datepicker-title'>" ,
monthHtml = "" ;
// 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 ) ;
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 ( ) ) ) {
monthHtml += "<option value='" + month + "'" +
( month === drawMonth ? " selected='selected'" : "" ) +
">" + monthNamesShort [ month ] + "</option>" ;
}
}
monthHtml += "</select>" ;
}
if ( ! showMonthAfterYear ) {
html += monthHtml + ( secondary || ! ( changeMonth && changeYear ) ? " " : "" ) ;
}
// year selection
if ( ! inst . yearshtml ) {
inst . yearshtml = "" ;
if ( secondary || ! changeYear ) {
html += "<span class='ui-datepicker-year'>" + drawYear + "</span>" ;
} else {
// determine range of years to display
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 ) ;
} ;
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 ++ ) {
inst . yearshtml += "<option value='" + year + "'" +
( year === drawYear ? " selected='selected'" : "" ) +
">" + year + "</option>" ;
}
inst . yearshtml += "</select>" ;
html += inst . yearshtml ;
inst . yearshtml = null ;
}
}
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 ) ) ) ;
inst . selectedDay = date . getDate ( ) ;
inst . drawMonth = inst . selectedMonth = date . getMonth ( ) ;
inst . drawYear = inst . selectedYear = date . getFullYear ( ) ;
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 ) ;
} ,
/* 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 ] ) ;
}
} ,
/* 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 ) ) ;
} ,
/* Determine the current maximum date - ensure no time components are set. */
_getMinMaxDate : function ( inst , minMax ) {
return this . _determineDate ( inst , this . _get ( inst , minMax + "Date" ) , null ) ;
} ,
/* Find the number of days in a given month. */
_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 ( ) ;
} ,
/* 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 ) ) ;
if ( offset < 0 ) {
date . setDate ( this . _getDaysInMonth ( date . getFullYear ( ) , date . getMonth ( ) ) ) ;
}
return this . _isInRange ( inst , date ) ;
} ,
/* Is the given date in the accepted range? */
_isInRange : function ( inst , date ) {
var yearSplit , currentYear ,
minDate = this . _getMinMaxDate ( inst , "min" ) ,
maxDate = this . _getMinMaxDate ( inst , "max" ) ,
minYear = null ,
maxYear = null ,
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 += currentYear ;
}
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 ) ) ;
} ,
/* 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" ) } ;
} ,
/* Format the given date for display. */
_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 ) ) ;
}
} ) ;
/ *
* 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 ) {
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" ) ;
}
if ( this . className . indexOf ( "ui-datepicker-next" ) !== - 1 ) {
$ ( this ) . removeClass ( "ui-datepicker-next-hover" ) ;
}
} )
. delegate ( selector , "mouseover" , 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 ( 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 ] ;
}
}
return target ;
}
/ * I n v o k e t h e d a t e p i c k e r f u n c t i o n a l i t y .
@ 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 ) {
/* Verify an empty collection wasn't passed - Fixes #6976 */
if ( ! this . length ) {
return this ;
}
/* Initialise the date picker. */
if ( ! $ . datepicker . initialized ) {
$ ( document ) . mousedown ( $ . datepicker . _checkExternalClick ) ;
$ . datepicker . initialized = true ;
}
/* Append datepicker main container to body if not exist. */
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 ) ) ;
}
if ( options === "option" && arguments . length === 2 && typeof arguments [ 1 ] === "string" ) {
return $ . datepicker [ "_" + options + "Datepicker" ] .
apply ( $ . datepicker , [ this [ 0 ] ] . concat ( otherArgs ) ) ;
}
return this . each ( function ( ) {
typeof options === "string" ?
$ . 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" ;
var datepicker = $ . datepicker ;
/ * !
* jQuery UI Tooltip 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/tooltip/
* /
var tooltip = $ . widget ( "ui.tooltip" , {
version : "1.11.4" ,
options : {
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 : {
my : "left top+15" ,
at : "left bottom" ,
collision : "flipfit flip"
} ,
show : true ,
tooltipClass : null ,
track : false ,
// callbacks
close : null ,
open : null
} ,
_addDescribedBy : function ( elem , id ) {
var describedby = ( elem . attr ( "aria-describedby" ) || "" ) . split ( /\s+/ ) ;
describedby . push ( id ) ;
elem
. data ( "ui-tooltip-id" , id )
. attr ( "aria-describedby" , $ . trim ( describedby . join ( " " ) ) ) ;
} ,
_removeDescribedBy : function ( elem ) {
var id = elem . data ( "ui-tooltip-id" ) ,
describedby = ( elem . attr ( "aria-describedby" ) || "" ) . split ( /\s+/ ) ,
index = $ . inArray ( id , describedby ) ;
if ( index !== - 1 ) {
describedby . splice ( index , 1 ) ;
}
elem . removeData ( "ui-tooltip-id" ) ;
describedby = $ . trim ( describedby . join ( " " ) ) ;
if ( describedby ) {
elem . attr ( "aria-describedby" , describedby ) ;
} else {
elem . removeAttr ( "aria-describedby" ) ;
}
} ,
_create : function ( ) {
this . _on ( {
mouseover : "open" ,
focusin : "open"
} ) ;
// IDs of generated tooltips, needed for destroy
this . tooltips = { } ;
// 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 ( {
role : "log" ,
"aria-live" : "assertive" ,
"aria-relevant" : "additions"
} )
. addClass ( "ui-helper-hidden-accessible" )
. appendTo ( this . document [ 0 ] . body ) ;
} ,
_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 ) ;
} ) ;
}
} ,
_disable : function ( ) {
var that = this ;
// 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" ) ;
}
} ) ;
} ,
_enable : function ( ) {
// restore title attributes
this . element . find ( this . options . items ) . addBack ( ) . each ( function ( ) {
var element = $ ( this ) ;
if ( element . data ( "ui-tooltip-title" ) ) {
element . attr ( "title" , element . data ( "ui-tooltip-title" ) ) ;
}
} ) ;
} ,
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 ) ;
// No element to show a tooltip for or the tooltip is already open
if ( ! target . length || target . data ( "ui-tooltip-id" ) ) {
return ;
}
if ( target . attr ( "title" ) ) {
target . data ( "ui-tooltip-title" , target . attr ( "title" ) ) ;
}
target . data ( "ui-tooltip-open" , true ) ;
// kill parent tooltips, custom or native, for hover
if ( event && event . type === "mouseover" ) {
target . parents ( ) . each ( function ( ) {
var parent = $ ( this ) ,
blurEvent ;
if ( parent . data ( "ui-tooltip-open" ) ) {
blurEvent = $ . Event ( "blur" ) ;
blurEvent . target = blurEvent . currentTarget = this ;
that . close ( blurEvent , true ) ;
}
if ( parent . attr ( "title" ) ) {
parent . uniqueId ( ) ;
that . parents [ this . id ] = {
element : this ,
title : parent . attr ( "title" )
} ;
parent . attr ( "title" , "" ) ;
}
} ) ;
}
this . _registerCloseHandlers ( event , target ) ;
this . _updateContent ( target , event ) ;
} ,
_updateContent : function ( target , event ) {
var content ,
contentOption = this . options . content ,
that = this ,
eventType = event ? event . type : null ;
if ( typeof contentOption === "string" ) {
return this . _open ( event , target , contentOption ) ;
}
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 ( ) {
// 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
// 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
// bubbling, so we set it back to the previous value. (#8740)
if ( event ) {
event . type = eventType ;
}
this . _open ( event , target , response ) ;
} ) ;
} ) ;
if ( content ) {
this . _open ( event , target , content ) ;
}
} ,
_open : function ( event , target , content ) {
var tooltipData , tooltip , delayedShow , a11yContent ,
positionOption = $ . extend ( { } , this . options . position ) ;
if ( ! content ) {
return ;
}
// Content can be updated multiple times. If the tooltip already
// exists, then just update the content and bail.
tooltipData = this . _find ( target ) ;
if ( tooltipData ) {
tooltipData . tooltip . find ( ".ui-tooltip-content" ) . html ( content ) ;
return ;
}
// 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])
//
// We use removeAttr only for key events, to allow IE to export the correct
// accessible attributes. For mouse events, set to empty string to avoid
// native tooltip showing up (happens only when removing inside mouseover).
if ( target . is ( "[title]" ) ) {
if ( event && event . type === "mouseover" ) {
target . attr ( "title" , "" ) ;
} else {
target . removeAttr ( "title" ) ;
}
}
tooltipData = this . _tooltip ( target ) ;
tooltip = tooltipData . tooltip ;
this . _addDescribedBy ( target , tooltip . attr ( "id" ) ) ;
tooltip . find ( ".ui-tooltip-content" ) . html ( content ) ;
// Support: Voiceover on OS X, JAWS on IE <= 9
// 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 ) ;
function position ( event ) {
positionOption . of = event ;
if ( tooltip . is ( ":hidden" ) ) {
return ;
}
tooltip . position ( positionOption ) ;
}
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 ( {
of : target
} , this . options . position ) ) ;
}
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 ( ) {
if ( tooltip . is ( ":visible" ) ) {
position ( positionOption . of ) ;
clearInterval ( delayedShow ) ;
}
} , $ . fx . interval ) ;
}
this . _trigger ( "open" , event , { tooltip : tooltip } ) ;
} ,
_registerCloseHandlers : function ( event , target ) {
var events = {
keyup : function ( event ) {
if ( event . keyCode === $ . ui . keyCode . ESCAPE ) {
var fakeEvent = $ . Event ( event ) ;
fakeEvent . currentTarget = target [ 0 ] ;
this . close ( fakeEvent , true ) ;
}
}
} ;
// Only bind remove handler for delegated targets. Non-delegated
// tooltips will handle this in destroy.
if ( target [ 0 ] !== this . element [ 0 ] ) {
events . remove = function ( ) {
this . _removeTooltip ( this . _find ( target ) . tooltip ) ;
} ;
}
if ( ! event || event . type === "mouseover" ) {
events . mouseleave = "close" ;
}
if ( ! event || event . type === "focusin" ) {
events . focusout = "close" ;
}
this . _on ( true , target , events ) ;
} ,
close : function ( event ) {
var tooltip ,
that = this ,
target = $ ( event ? event . currentTarget : this . element ) ,
tooltipData = this . _find ( target ) ;
// The tooltip may already be closed
if ( ! tooltipData ) {
// We set ui-tooltip-open immediately upon open (in open()), but only set the
// additional data once there's actually content to show (in _open()). So even if the
// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
// the period between open() and _open().
target . removeData ( "ui-tooltip-open" ) ;
return ;
}
tooltip = tooltipData . tooltip ;
// 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 ;
}
// Clear the interval for delayed tracking tooltips
clearInterval ( this . delayedShow ) ;
// 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" ) ) ;
}
this . _removeDescribedBy ( target ) ;
tooltipData . hiding = true ;
tooltip . stop ( true ) ;
this . _hide ( tooltip , this . options . hide , function ( ) {
that . _removeTooltip ( $ ( this ) ) ;
} ) ;
target . removeData ( "ui-tooltip-open" ) ;
this . _off ( target , "mouseleave focusout keyup" ) ;
// Remove 'remove' binding only on delegated targets
if ( target [ 0 ] !== this . element [ 0 ] ) {
this . _off ( target , "remove" ) ;
}
this . _off ( this . document , "mousemove" ) ;
if ( event && event . type === "mouseleave" ) {
$ . each ( this . parents , function ( id , parent ) {
$ ( parent . element ) . attr ( "title" , parent . title ) ;
delete that . parents [ id ] ;
} ) ;
}
tooltipData . closing = true ;
this . _trigger ( "close" , event , { tooltip : tooltip } ) ;
if ( ! tooltipData . hiding ) {
tooltipData . closing = false ;
}
} ,
_tooltip : function ( element ) {
var tooltip = $ ( "<div>" )
. attr ( "role" , "tooltip" )
. addClass ( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
( this . options . tooltipClass || "" ) ) ,
id = tooltip . uniqueId ( ) . attr ( "id" ) ;
$ ( "<div>" )
. addClass ( "ui-tooltip-content" )
. appendTo ( tooltip ) ;
tooltip . appendTo ( this . document [ 0 ] . body ) ;
return this . tooltips [ id ] = {
element : element ,
tooltip : tooltip
} ;
} ,
_find : function ( target ) {
var id = target . data ( "ui-tooltip-id" ) ;
return id ? this . tooltips [ id ] : null ;
} ,
_removeTooltip : function ( tooltip ) {
tooltip . remove ( ) ;
delete this . tooltips [ tooltip . attr ( "id" ) ] ;
} ,
_destroy : function ( ) {
var that = this ;
// close open tooltips
$ . each ( this . tooltips , function ( id , tooltipData ) {
// Delegate to close method to handle common cleanup
var event = $ . Event ( "blur" ) ,
element = tooltipData . element ;
event . target = event . currentTarget = element [ 0 ] ;
that . close ( event , true ) ;
// Remove immediately; destroying an open tooltip doesn't use the
// hide animation
$ ( "#" + id ) . remove ( ) ;
// 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 ( ) ;
}
} ) ;
/ * !
* 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" ,
// 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
} ;
} ) ;
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 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 ( ) ;
} ;
2018-01-16 11:34:37 +01:00
} ) ) ;