1362 lines
36 KiB
JavaScript
1362 lines
36 KiB
JavaScript
/*!
|
|
* jQuery UI 1.8.5
|
|
*
|
|
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://docs.jquery.com/UI
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
// prevent duplicate loading
|
|
// this is only a problem because we proxy existing functions
|
|
// and we don't want to double proxy them
|
|
$.ui = $.ui || {};
|
|
if ( $.ui.version ) {
|
|
return;
|
|
}
|
|
|
|
$.extend( $.ui, {
|
|
version: "1.8.5",
|
|
|
|
keyCode: {
|
|
ALT: 18,
|
|
BACKSPACE: 8,
|
|
CAPS_LOCK: 20,
|
|
COMMA: 188,
|
|
COMMAND: 91,
|
|
COMMAND_LEFT: 91, // COMMAND
|
|
COMMAND_RIGHT: 93,
|
|
CONTROL: 17,
|
|
DELETE: 46,
|
|
DOWN: 40,
|
|
END: 35,
|
|
ENTER: 13,
|
|
ESCAPE: 27,
|
|
HOME: 36,
|
|
INSERT: 45,
|
|
LEFT: 37,
|
|
MENU: 93, // COMMAND_RIGHT
|
|
NUMPAD_ADD: 107,
|
|
NUMPAD_DECIMAL: 110,
|
|
NUMPAD_DIVIDE: 111,
|
|
NUMPAD_ENTER: 108,
|
|
NUMPAD_MULTIPLY: 106,
|
|
NUMPAD_SUBTRACT: 109,
|
|
PAGE_DOWN: 34,
|
|
PAGE_UP: 33,
|
|
PERIOD: 190,
|
|
RIGHT: 39,
|
|
SHIFT: 16,
|
|
SPACE: 32,
|
|
TAB: 9,
|
|
UP: 38,
|
|
WINDOWS: 91 // COMMAND
|
|
}
|
|
});
|
|
|
|
// plugins
|
|
$.fn.extend({
|
|
_focus: $.fn.focus,
|
|
focus: function( delay, fn ) {
|
|
return typeof delay === "number" ?
|
|
this.each(function() {
|
|
var elem = this;
|
|
setTimeout(function() {
|
|
$( elem ).focus();
|
|
if ( fn ) {
|
|
fn.call( elem );
|
|
}
|
|
}, delay );
|
|
}) :
|
|
this._focus.apply( this, arguments );
|
|
},
|
|
|
|
scrollParent: function() {
|
|
var scrollParent;
|
|
if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
|
|
scrollParent = this.parents().filter(function() {
|
|
return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
|
}).eq(0);
|
|
} else {
|
|
scrollParent = this.parents().filter(function() {
|
|
return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
|
}).eq(0);
|
|
}
|
|
|
|
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
|
|
},
|
|
|
|
zIndex: function( zIndex ) {
|
|
if ( zIndex !== undefined ) {
|
|
return this.css( "zIndex", zIndex );
|
|
}
|
|
|
|
if ( this.length ) {
|
|
var elem = $( this[ 0 ] ), position, value;
|
|
while ( elem.length && elem[ 0 ] !== document ) {
|
|
// Ignore z-index if position is set to a value where z-index is ignored by the browser
|
|
// This makes behavior of this function consistent across browsers
|
|
// WebKit always returns auto if the element is positioned
|
|
position = elem.css( "position" );
|
|
if ( position === "absolute" || position === "relative" || position === "fixed" ) {
|
|
// IE returns 0 when zIndex is not specified
|
|
// other browsers return a string
|
|
// we ignore the case of nested elements with an explicit value of 0
|
|
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
|
|
value = parseInt( elem.css( "zIndex" ) );
|
|
if ( !isNaN( value ) && value != 0 ) {
|
|
return value;
|
|
}
|
|
}
|
|
elem = elem.parent();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
},
|
|
|
|
disableSelection: function() {
|
|
return this.bind(
|
|
"mousedown.ui-disableSelection selectstart.ui-disableSelection",
|
|
function( event ) {
|
|
event.preventDefault();
|
|
});
|
|
},
|
|
|
|
enableSelection: function() {
|
|
return this.unbind( ".ui-disableSelection" );
|
|
}
|
|
});
|
|
|
|
$.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( $.curCSS( elem, "padding" + this, true) ) || 0;
|
|
if ( border ) {
|
|
size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
|
|
}
|
|
if ( margin ) {
|
|
size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
|
|
}
|
|
});
|
|
return size;
|
|
}
|
|
|
|
$.fn[ "inner" + name ] = function( size ) {
|
|
if ( size === undefined ) {
|
|
return orig[ "inner" + name ].call( this );
|
|
}
|
|
|
|
return this.each(function() {
|
|
$.style( this, 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() {
|
|
$.style( this, type, reduce( this, size, true, margin ) + "px" );
|
|
});
|
|
};
|
|
});
|
|
|
|
// selectors
|
|
function visible( element ) {
|
|
return !$( element ).parents().andSelf().filter(function() {
|
|
return $.curCSS( this, "visibility" ) === "hidden" ||
|
|
$.expr.filters.hidden( this );
|
|
}).length;
|
|
}
|
|
|
|
$.extend( $.expr[ ":" ], {
|
|
data: function( elem, i, match ) {
|
|
return !!$.data( elem, match[ 3 ] );
|
|
},
|
|
|
|
focusable: function( element ) {
|
|
var nodeName = element.nodeName.toLowerCase(),
|
|
tabIndex = $.attr( element, "tabindex" );
|
|
if ( "area" === nodeName ) {
|
|
var map = element.parentNode,
|
|
mapName = map.name,
|
|
img;
|
|
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 || !isNaN( tabIndex )
|
|
: !isNaN( tabIndex ))
|
|
// the element and all of its ancestors must be visible
|
|
&& visible( element );
|
|
},
|
|
|
|
tabbable: function( element ) {
|
|
var tabIndex = $.attr( element, "tabindex" );
|
|
return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
|
|
}
|
|
});
|
|
|
|
// support
|
|
$(function() {
|
|
var div = document.createElement( "div" ),
|
|
body = document.body;
|
|
|
|
$.extend( div.style, {
|
|
minHeight: "100px",
|
|
height: "auto",
|
|
padding: 0,
|
|
borderWidth: 0
|
|
});
|
|
|
|
$.support.minHeight = body.appendChild( div ).offsetHeight === 100;
|
|
// set display to none to avoid a layout bug in IE
|
|
// http://dev.jquery.com/ticket/4014
|
|
body.removeChild( div ).style.display = "none";
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// deprecated
|
|
$.extend( $.ui, {
|
|
// $.ui.plugin is deprecated. Use the proxy pattern instead.
|
|
plugin: {
|
|
add: function( module, option, set ) {
|
|
var proto = $.ui[ module ].prototype;
|
|
for ( var i in set ) {
|
|
proto.plugins[ i ] = proto.plugins[ i ] || [];
|
|
proto.plugins[ i ].push( [ option, set[ i ] ] );
|
|
}
|
|
},
|
|
call: function( instance, name, args ) {
|
|
var set = instance.plugins[ name ];
|
|
if ( !set || !instance.element[ 0 ].parentNode ) {
|
|
return;
|
|
}
|
|
|
|
for ( var i = 0; i < set.length; i++ ) {
|
|
if ( instance.options[ set[ i ][ 0 ] ] ) {
|
|
set[ i ][ 1 ].apply( instance.element, args );
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
|
|
contains: function( a, b ) {
|
|
return document.compareDocumentPosition ?
|
|
a.compareDocumentPosition( b ) & 16 :
|
|
a !== b && a.contains( b );
|
|
},
|
|
|
|
// only used by resizable
|
|
hasScroll: function( el, a ) {
|
|
|
|
//If overflow is hidden, the element might have extra content, but the user wants to hide it
|
|
if ( $( el ).css( "overflow" ) === "hidden") {
|
|
return false;
|
|
}
|
|
|
|
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
|
has = false;
|
|
|
|
if ( el[ scroll ] > 0 ) {
|
|
return true;
|
|
}
|
|
|
|
// TODO: determine which cases actually cause this to happen
|
|
// if the element doesn't have the scroll set, see if it's possible to
|
|
// set the scroll
|
|
el[ scroll ] = 1;
|
|
has = ( el[ scroll ] > 0 );
|
|
el[ scroll ] = 0;
|
|
return has;
|
|
},
|
|
|
|
// these are odd functions, fix the API or move into individual plugins
|
|
isOverAxis: function( x, reference, size ) {
|
|
//Determines when x coordinate is over "b" element axis
|
|
return ( x > reference ) && ( x < ( reference + size ) );
|
|
},
|
|
isOver: function( y, x, top, left, height, width ) {
|
|
//Determines when x, y coordinates is over "b" element
|
|
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
|
|
}
|
|
});
|
|
|
|
})( jQuery );
|
|
/*!
|
|
* jQuery UI Widget 1.8.5
|
|
*
|
|
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://docs.jquery.com/UI/Widget
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
// jQuery 1.4+
|
|
if ( $.cleanData ) {
|
|
var _cleanData = $.cleanData;
|
|
$.cleanData = function( elems ) {
|
|
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
|
|
$( elem ).triggerHandler( "remove" );
|
|
}
|
|
_cleanData( elems );
|
|
};
|
|
} else {
|
|
var _remove = $.fn.remove;
|
|
$.fn.remove = function( selector, keepData ) {
|
|
return this.each(function() {
|
|
if ( !keepData ) {
|
|
if ( !selector || $.filter( selector, [ this ] ).length ) {
|
|
$( "*", this ).add( [ this ] ).each(function() {
|
|
$( this ).triggerHandler( "remove" );
|
|
});
|
|
}
|
|
}
|
|
return _remove.call( $(this), selector, keepData );
|
|
});
|
|
};
|
|
}
|
|
|
|
$.widget = function( name, base, prototype ) {
|
|
var namespace = name.split( "." )[ 0 ],
|
|
fullName;
|
|
name = name.split( "." )[ 1 ];
|
|
fullName = namespace + "-" + name;
|
|
|
|
if ( !prototype ) {
|
|
prototype = base;
|
|
base = $.Widget;
|
|
}
|
|
|
|
// create selector for plugin
|
|
$.expr[ ":" ][ fullName ] = function( elem ) {
|
|
return !!$.data( elem, name );
|
|
};
|
|
|
|
$[ namespace ] = $[ namespace ] || {};
|
|
$[ namespace ][ name ] = function( options, element ) {
|
|
// allow instantiation without initializing for simple inheritance
|
|
if ( arguments.length ) {
|
|
this._createWidget( options, element );
|
|
}
|
|
};
|
|
|
|
var basePrototype = new base();
|
|
// we need to make the options hash a property directly on the new instance
|
|
// otherwise we'll modify the options hash on the prototype that we're
|
|
// inheriting from
|
|
// $.each( basePrototype, function( key, val ) {
|
|
// if ( $.isPlainObject(val) ) {
|
|
// basePrototype[ key ] = $.extend( {}, val );
|
|
// }
|
|
// });
|
|
basePrototype.options = $.extend( true, {}, basePrototype.options );
|
|
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
|
|
namespace: namespace,
|
|
widgetName: name,
|
|
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
|
|
widgetBaseClass: fullName
|
|
}, prototype );
|
|
|
|
$.widget.bridge( name, $[ namespace ][ name ] );
|
|
};
|
|
|
|
$.widget.bridge = function( name, object ) {
|
|
$.fn[ name ] = function( options ) {
|
|
var isMethodCall = typeof options === "string",
|
|
args = Array.prototype.slice.call( arguments, 1 ),
|
|
returnValue = this;
|
|
|
|
// allow multiple hashes to be passed on init
|
|
options = !isMethodCall && args.length ?
|
|
$.extend.apply( null, [ true, options ].concat(args) ) :
|
|
options;
|
|
|
|
// prevent calls to internal methods
|
|
if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {
|
|
return returnValue;
|
|
}
|
|
|
|
if ( isMethodCall ) {
|
|
this.each(function() {
|
|
var instance = $.data( this, name );
|
|
if ( !instance ) {
|
|
throw "cannot call methods on " + name + " prior to initialization; " +
|
|
"attempted to call method '" + options + "'";
|
|
}
|
|
if ( !$.isFunction( instance[options] ) ) {
|
|
throw "no such method '" + options + "' for " + name + " widget instance";
|
|
}
|
|
var methodValue = instance[ options ].apply( instance, args );
|
|
if ( methodValue !== instance && methodValue !== undefined ) {
|
|
returnValue = methodValue;
|
|
return false;
|
|
}
|
|
});
|
|
} else {
|
|
this.each(function() {
|
|
var instance = $.data( this, name );
|
|
if ( instance ) {
|
|
instance.option( options || {} )._init();
|
|
} else {
|
|
$.data( this, name, new object( options, this ) );
|
|
}
|
|
});
|
|
}
|
|
|
|
return returnValue;
|
|
};
|
|
};
|
|
|
|
$.Widget = function( options, element ) {
|
|
// allow instantiation without initializing for simple inheritance
|
|
if ( arguments.length ) {
|
|
this._createWidget( options, element );
|
|
}
|
|
};
|
|
|
|
$.Widget.prototype = {
|
|
widgetName: "widget",
|
|
widgetEventPrefix: "",
|
|
options: {
|
|
disabled: false
|
|
},
|
|
_createWidget: function( options, element ) {
|
|
// $.widget.bridge stores the plugin instance, but we do it anyway
|
|
// so that it's stored even before the _create function runs
|
|
$.data( element, this.widgetName, this );
|
|
this.element = $( element );
|
|
this.options = $.extend( true, {},
|
|
this.options,
|
|
$.metadata && $.metadata.get( element )[ this.widgetName ],
|
|
options );
|
|
|
|
var self = this;
|
|
this.element.bind( "remove." + this.widgetName, function() {
|
|
self.destroy();
|
|
});
|
|
|
|
this._create();
|
|
this._init();
|
|
},
|
|
_create: function() {},
|
|
_init: function() {},
|
|
|
|
destroy: function() {
|
|
this.element
|
|
.unbind( "." + this.widgetName )
|
|
.removeData( this.widgetName );
|
|
this.widget()
|
|
.unbind( "." + this.widgetName )
|
|
.removeAttr( "aria-disabled" )
|
|
.removeClass(
|
|
this.widgetBaseClass + "-disabled " +
|
|
"ui-state-disabled" );
|
|
},
|
|
|
|
widget: function() {
|
|
return this.element;
|
|
},
|
|
|
|
option: function( key, value ) {
|
|
var options = key,
|
|
self = this;
|
|
|
|
if ( arguments.length === 0 ) {
|
|
// don't return a reference to the internal hash
|
|
return $.extend( {}, self.options );
|
|
}
|
|
|
|
if (typeof key === "string" ) {
|
|
if ( value === undefined ) {
|
|
return this.options[ key ];
|
|
}
|
|
options = {};
|
|
options[ key ] = value;
|
|
}
|
|
|
|
$.each( options, function( key, value ) {
|
|
self._setOption( key, value );
|
|
});
|
|
|
|
return self;
|
|
},
|
|
_setOption: function( key, value ) {
|
|
this.options[ key ] = value;
|
|
|
|
if ( key === "disabled" ) {
|
|
this.widget()
|
|
[ value ? "addClass" : "removeClass"](
|
|
this.widgetBaseClass + "-disabled" + " " +
|
|
"ui-state-disabled" )
|
|
.attr( "aria-disabled", value );
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
enable: function() {
|
|
return this._setOption( "disabled", false );
|
|
},
|
|
disable: function() {
|
|
return this._setOption( "disabled", true );
|
|
},
|
|
|
|
_trigger: function( type, event, data ) {
|
|
var callback = this.options[ type ];
|
|
|
|
event = $.Event( event );
|
|
event.type = ( type === this.widgetEventPrefix ?
|
|
type :
|
|
this.widgetEventPrefix + type ).toLowerCase();
|
|
data = data || {};
|
|
|
|
// copy original event properties over to the new event
|
|
// this would happen if we could call $.event.fix instead of $.Event
|
|
// but we don't have a way to force an event to be fixed multiple times
|
|
if ( event.originalEvent ) {
|
|
for ( var i = $.event.props.length, prop; i; ) {
|
|
prop = $.event.props[ --i ];
|
|
event[ prop ] = event.originalEvent[ prop ];
|
|
}
|
|
}
|
|
|
|
this.element.trigger( event, data );
|
|
|
|
return !( $.isFunction(callback) &&
|
|
callback.call( this.element[0], event, data ) === false ||
|
|
event.isDefaultPrevented() );
|
|
}
|
|
};
|
|
|
|
})( jQuery );
|
|
/*
|
|
* jQuery UI Position 1.8.5
|
|
*
|
|
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://docs.jquery.com/UI/Position
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
$.ui = $.ui || {};
|
|
|
|
var horizontalPositions = /left|center|right/,
|
|
verticalPositions = /top|center|bottom/,
|
|
center = "center",
|
|
_position = $.fn.position,
|
|
_offset = $.fn.offset;
|
|
|
|
$.fn.position = function( options ) {
|
|
if ( !options || !options.of ) {
|
|
return _position.apply( this, arguments );
|
|
}
|
|
|
|
// make a copy, we don't want to modify arguments
|
|
options = $.extend( {}, options );
|
|
|
|
var target = $( options.of ),
|
|
targetElem = target[0],
|
|
collision = ( options.collision || "flip" ).split( " " ),
|
|
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
|
|
targetWidth,
|
|
targetHeight,
|
|
basePosition;
|
|
|
|
if ( targetElem.nodeType === 9 ) {
|
|
targetWidth = target.width();
|
|
targetHeight = target.height();
|
|
basePosition = { top: 0, left: 0 };
|
|
} else if ( targetElem.scrollTo && targetElem.document ) {
|
|
targetWidth = target.width();
|
|
targetHeight = target.height();
|
|
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
|
|
} else if ( targetElem.preventDefault ) {
|
|
// force left top to allow flipping
|
|
options.at = "left top";
|
|
targetWidth = targetHeight = 0;
|
|
basePosition = { top: options.of.pageY, left: options.of.pageX };
|
|
} else {
|
|
targetWidth = target.outerWidth();
|
|
targetHeight = target.outerHeight();
|
|
basePosition = target.offset();
|
|
}
|
|
|
|
// force my and at to have valid horizontal and veritcal positions
|
|
// if a value is missing or invalid, it will be converted to center
|
|
$.each( [ "my", "at" ], function() {
|
|
var pos = ( options[this] || "" ).split( " " );
|
|
if ( pos.length === 1) {
|
|
pos = horizontalPositions.test( pos[0] ) ?
|
|
pos.concat( [center] ) :
|
|
verticalPositions.test( pos[0] ) ?
|
|
[ center ].concat( pos ) :
|
|
[ center, center ];
|
|
}
|
|
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
|
|
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
|
|
options[ this ] = pos;
|
|
});
|
|
|
|
// normalize collision option
|
|
if ( collision.length === 1 ) {
|
|
collision[ 1 ] = collision[ 0 ];
|
|
}
|
|
|
|
// normalize offset option
|
|
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
|
|
if ( offset.length === 1 ) {
|
|
offset[ 1 ] = offset[ 0 ];
|
|
}
|
|
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
|
|
|
|
if ( options.at[0] === "right" ) {
|
|
basePosition.left += targetWidth;
|
|
} else if (options.at[0] === center ) {
|
|
basePosition.left += targetWidth / 2;
|
|
}
|
|
|
|
if ( options.at[1] === "bottom" ) {
|
|
basePosition.top += targetHeight;
|
|
} else if ( options.at[1] === center ) {
|
|
basePosition.top += targetHeight / 2;
|
|
}
|
|
|
|
basePosition.left += offset[ 0 ];
|
|
basePosition.top += offset[ 1 ];
|
|
|
|
return this.each(function() {
|
|
var elem = $( this ),
|
|
elemWidth = elem.outerWidth(),
|
|
elemHeight = elem.outerHeight(),
|
|
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
|
|
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
|
|
collisionWidth = elemWidth + marginLeft +
|
|
parseInt( $.curCSS( this, "marginRight", true ) ) || 0,
|
|
collisionHeight = elemHeight + marginTop +
|
|
parseInt( $.curCSS( this, "marginBottom", true ) ) || 0,
|
|
position = $.extend( {}, basePosition ),
|
|
collisionPosition;
|
|
|
|
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;
|
|
}
|
|
|
|
// prevent fractions (see #5280)
|
|
position.left = parseInt( position.left );
|
|
position.top = parseInt( position.top );
|
|
|
|
collisionPosition = {
|
|
left: position.left - marginLeft,
|
|
top: position.top - 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: offset,
|
|
my: options.my,
|
|
at: options.at
|
|
});
|
|
}
|
|
});
|
|
|
|
if ( $.fn.bgiframe ) {
|
|
elem.bgiframe();
|
|
}
|
|
elem.offset( $.extend( position, { using: options.using } ) );
|
|
});
|
|
};
|
|
|
|
$.ui.position = {
|
|
fit: {
|
|
left: function( position, data ) {
|
|
var win = $( window ),
|
|
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
|
|
position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
|
|
},
|
|
top: function( position, data ) {
|
|
var win = $( window ),
|
|
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
|
|
position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
|
|
}
|
|
},
|
|
|
|
flip: {
|
|
left: function( position, data ) {
|
|
if ( data.at[0] === center ) {
|
|
return;
|
|
}
|
|
var win = $( window ),
|
|
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
|
|
myOffset = data.my[ 0 ] === "left" ?
|
|
-data.elemWidth :
|
|
data.my[ 0 ] === "right" ?
|
|
data.elemWidth :
|
|
0,
|
|
atOffset = data.at[ 0 ] === "left" ?
|
|
data.targetWidth :
|
|
-data.targetWidth,
|
|
offset = -2 * data.offset[ 0 ];
|
|
position.left += data.collisionPosition.left < 0 ?
|
|
myOffset + atOffset + offset :
|
|
over > 0 ?
|
|
myOffset + atOffset + offset :
|
|
0;
|
|
},
|
|
top: function( position, data ) {
|
|
if ( data.at[1] === center ) {
|
|
return;
|
|
}
|
|
var win = $( window ),
|
|
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
|
|
myOffset = data.my[ 1 ] === "top" ?
|
|
-data.elemHeight :
|
|
data.my[ 1 ] === "bottom" ?
|
|
data.elemHeight :
|
|
0,
|
|
atOffset = data.at[ 1 ] === "top" ?
|
|
data.targetHeight :
|
|
-data.targetHeight,
|
|
offset = -2 * data.offset[ 1 ];
|
|
position.top += data.collisionPosition.top < 0 ?
|
|
myOffset + atOffset + offset :
|
|
over > 0 ?
|
|
myOffset + atOffset + offset :
|
|
0;
|
|
}
|
|
}
|
|
};
|
|
|
|
// offset setter from jQuery 1.4
|
|
if ( !$.offset.setOffset ) {
|
|
$.offset.setOffset = function( elem, options ) {
|
|
// set position first, in-case top/left are set even on static elem
|
|
if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
|
|
elem.style.position = "relative";
|
|
}
|
|
var curElem = $( elem ),
|
|
curOffset = curElem.offset(),
|
|
curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
|
|
curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
|
|
props = {
|
|
top: (options.top - curOffset.top) + curTop,
|
|
left: (options.left - curOffset.left) + curLeft
|
|
};
|
|
|
|
if ( 'using' in options ) {
|
|
options.using.call( elem, props );
|
|
} else {
|
|
curElem.css( props );
|
|
}
|
|
};
|
|
|
|
$.fn.offset = function( options ) {
|
|
var elem = this[ 0 ];
|
|
if ( !elem || !elem.ownerDocument ) { return null; }
|
|
if ( options ) {
|
|
return this.each(function() {
|
|
$.offset.setOffset( this, options );
|
|
});
|
|
}
|
|
return _offset.call( this );
|
|
};
|
|
}
|
|
|
|
}( jQuery ));
|
|
/*
|
|
* jQuery UI Autocomplete 1.8.5
|
|
*
|
|
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://docs.jquery.com/UI/Autocomplete
|
|
*
|
|
* Depends:
|
|
* jquery.ui.core.js
|
|
* jquery.ui.widget.js
|
|
* jquery.ui.position.js
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
$.widget( "ui.autocomplete", {
|
|
options: {
|
|
appendTo: "body",
|
|
delay: 300,
|
|
minLength: 1,
|
|
position: {
|
|
my: "left top",
|
|
at: "left bottom",
|
|
collision: "none"
|
|
},
|
|
source: null
|
|
},
|
|
_create: function() {
|
|
var self = this,
|
|
doc = this.element[ 0 ].ownerDocument;
|
|
this.element
|
|
.addClass( "ui-autocomplete-input" )
|
|
.attr( "autocomplete", "off" )
|
|
// TODO verify these actually work as intended
|
|
.attr({
|
|
role: "textbox",
|
|
"aria-autocomplete": "list",
|
|
"aria-haspopup": "true"
|
|
})
|
|
.bind( "keydown.autocomplete", function( event ) {
|
|
if ( self.options.disabled ) {
|
|
return;
|
|
}
|
|
|
|
var keyCode = $.ui.keyCode;
|
|
switch( event.keyCode ) {
|
|
case keyCode.PAGE_UP:
|
|
self._move( "previousPage", event );
|
|
break;
|
|
case keyCode.PAGE_DOWN:
|
|
self._move( "nextPage", event );
|
|
break;
|
|
case keyCode.UP:
|
|
self._move( "previous", event );
|
|
// prevent moving cursor to beginning of text field in some browsers
|
|
event.preventDefault();
|
|
break;
|
|
case keyCode.DOWN:
|
|
self._move( "next", event );
|
|
// prevent moving cursor to end of text field in some browsers
|
|
event.preventDefault();
|
|
break;
|
|
case keyCode.ENTER:
|
|
case keyCode.NUMPAD_ENTER:
|
|
// when menu is open or has focus
|
|
if ( self.menu.element.is( ":visible" ) ) {
|
|
event.preventDefault();
|
|
}
|
|
//passthrough - ENTER and TAB both select the current element
|
|
case keyCode.TAB:
|
|
if ( !self.menu.active ) {
|
|
return;
|
|
}
|
|
self.menu.select( event );
|
|
break;
|
|
case keyCode.ESCAPE:
|
|
self.element.val( self.term );
|
|
self.close( event );
|
|
break;
|
|
default:
|
|
// keypress is triggered before the input value is changed
|
|
clearTimeout( self.searching );
|
|
self.searching = setTimeout(function() {
|
|
// only search if the value has changed
|
|
if ( self.term != self.element.val() ) {
|
|
self.selectedItem = null;
|
|
self.search( null, event );
|
|
}
|
|
}, self.options.delay );
|
|
break;
|
|
}
|
|
})
|
|
.bind( "focus.autocomplete", function() {
|
|
if ( self.options.disabled ) {
|
|
return;
|
|
}
|
|
|
|
self.selectedItem = null;
|
|
self.previous = self.element.val();
|
|
})
|
|
.bind( "blur.autocomplete", function( event ) {
|
|
if ( self.options.disabled ) {
|
|
return;
|
|
}
|
|
|
|
clearTimeout( self.searching );
|
|
// clicks on the menu (or a button to trigger a search) will cause a blur event
|
|
self.closing = setTimeout(function() {
|
|
self.close( event );
|
|
self._change( event );
|
|
}, 150 );
|
|
});
|
|
this._initSource();
|
|
this.response = function() {
|
|
return self._response.apply( self, arguments );
|
|
};
|
|
this.menu = $( "<ul></ul>" )
|
|
.addClass( "ui-autocomplete" )
|
|
.appendTo( $( this.options.appendTo || "body", doc )[0] )
|
|
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
|
|
.mousedown(function( event ) {
|
|
// 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 = self.menu.element[ 0 ];
|
|
if ( event.target === menuElement ) {
|
|
setTimeout(function() {
|
|
$( document ).one( 'mousedown', function( event ) {
|
|
if ( event.target !== self.element[ 0 ] &&
|
|
event.target !== menuElement &&
|
|
!$.ui.contains( menuElement, event.target ) ) {
|
|
self.close();
|
|
}
|
|
});
|
|
}, 1 );
|
|
}
|
|
|
|
// use another timeout to make sure the blur-event-handler on the input was already triggered
|
|
setTimeout(function() {
|
|
clearTimeout( self.closing );
|
|
}, 13);
|
|
})
|
|
.menu({
|
|
focus: function( event, ui ) {
|
|
var item = ui.item.data( "item.autocomplete" );
|
|
if ( false !== self._trigger( "focus", null, { item: item } ) ) {
|
|
// use value to match what will end up in the input, if it was a key event
|
|
if ( /^key/.test(event.originalEvent.type) ) {
|
|
self.element.val( item.value );
|
|
}
|
|
}
|
|
},
|
|
selected: function( event, ui ) {
|
|
var item = ui.item.data( "item.autocomplete" ),
|
|
previous = self.previous;
|
|
|
|
// only trigger when focus was lost (click on menu)
|
|
if ( self.element[0] !== doc.activeElement ) {
|
|
self.element.focus();
|
|
self.previous = previous;
|
|
}
|
|
|
|
if ( false !== self._trigger( "select", event, { item: item } ) ) {
|
|
self.term = item.value;
|
|
self.element.val( item.value );
|
|
}
|
|
|
|
self.close( event );
|
|
self.selectedItem = item;
|
|
},
|
|
blur: function( event, ui ) {
|
|
// don't set the value of the text field if it's already correct
|
|
// this prevents moving the cursor unnecessarily
|
|
if ( self.menu.element.is(":visible") &&
|
|
( self.element.val() !== self.term ) ) {
|
|
self.element.val( self.term );
|
|
}
|
|
}
|
|
})
|
|
.zIndex( this.element.zIndex() + 1 )
|
|
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
|
|
.css({ top: 0, left: 0 })
|
|
.hide()
|
|
.data( "menu" );
|
|
if ( $.fn.bgiframe ) {
|
|
this.menu.element.bgiframe();
|
|
}
|
|
},
|
|
|
|
destroy: function() {
|
|
this.element
|
|
.removeClass( "ui-autocomplete-input" )
|
|
.removeAttr( "autocomplete" )
|
|
.removeAttr( "role" )
|
|
.removeAttr( "aria-autocomplete" )
|
|
.removeAttr( "aria-haspopup" );
|
|
this.menu.element.remove();
|
|
$.Widget.prototype.destroy.call( this );
|
|
},
|
|
|
|
_setOption: function( key, value ) {
|
|
$.Widget.prototype._setOption.apply( this, arguments );
|
|
if ( key === "source" ) {
|
|
this._initSource();
|
|
}
|
|
if ( key === "appendTo" ) {
|
|
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
|
|
}
|
|
},
|
|
|
|
_initSource: function() {
|
|
var self = this,
|
|
array,
|
|
url;
|
|
if ( $.isArray(this.options.source) ) {
|
|
array = this.options.source;
|
|
this.source = function( request, response ) {
|
|
response( $.ui.autocomplete.filter(array, request.term) );
|
|
};
|
|
} else if ( typeof this.options.source === "string" ) {
|
|
url = this.options.source;
|
|
this.source = function( request, response ) {
|
|
if (self.xhr) {
|
|
self.xhr.abort();
|
|
}
|
|
self.xhr = $.getJSON( url, request, function( data, status, xhr ) {
|
|
if ( xhr === self.xhr ) {
|
|
response( data );
|
|
}
|
|
self.xhr = null;
|
|
});
|
|
};
|
|
} else {
|
|
this.source = this.options.source;
|
|
}
|
|
},
|
|
|
|
search: function( value, event ) {
|
|
value = value != null ? value : this.element.val();
|
|
|
|
// always save the actual value, not the one passed as an argument
|
|
this.term = this.element.val();
|
|
|
|
if ( value.length < this.options.minLength ) {
|
|
return this.close( event );
|
|
}
|
|
|
|
clearTimeout( this.closing );
|
|
if ( this._trigger("search") === false ) {
|
|
return;
|
|
}
|
|
|
|
return this._search( value );
|
|
},
|
|
|
|
_search: function( value ) {
|
|
this.element.addClass( "ui-autocomplete-loading" );
|
|
|
|
this.source( { term: value }, this.response );
|
|
},
|
|
|
|
_response: function( content ) {
|
|
if ( content.length ) {
|
|
content = this._normalize( content );
|
|
this._suggest( content );
|
|
this._trigger( "open" );
|
|
} else {
|
|
this.close();
|
|
}
|
|
this.element.removeClass( "ui-autocomplete-loading" );
|
|
},
|
|
|
|
close: function( event ) {
|
|
clearTimeout( this.closing );
|
|
if ( this.menu.element.is(":visible") ) {
|
|
this._trigger( "close", event );
|
|
this.menu.element.hide();
|
|
this.menu.deactivate();
|
|
}
|
|
},
|
|
|
|
_change: function( event ) {
|
|
if ( this.previous !== this.element.val() ) {
|
|
this._trigger( "change", event, { item: this.selectedItem } );
|
|
}
|
|
},
|
|
|
|
_normalize: function( items ) {
|
|
// assume all items have the right format when the first item is complete
|
|
if ( items.length && items[0].label && items[0].value ) {
|
|
return items;
|
|
}
|
|
return $.map( items, function(item) {
|
|
if ( typeof item === "string" ) {
|
|
return {
|
|
label: item,
|
|
value: item
|
|
};
|
|
}
|
|
return $.extend({
|
|
label: item.label || item.value,
|
|
value: item.value || item.label
|
|
}, item );
|
|
});
|
|
},
|
|
|
|
_suggest: function( items ) {
|
|
var ul = this.menu.element
|
|
.empty()
|
|
.zIndex( this.element.zIndex() + 1 ),
|
|
menuWidth,
|
|
textWidth;
|
|
this._renderMenu( ul, items );
|
|
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
|
|
this.menu.deactivate();
|
|
this.menu.refresh();
|
|
this.menu.element.show().position( $.extend({
|
|
of: this.element
|
|
}, this.options.position ));
|
|
|
|
menuWidth = ul.width( "" ).outerWidth();
|
|
textWidth = this.element.outerWidth();
|
|
ul.outerWidth( Math.max( menuWidth, textWidth ) );
|
|
},
|
|
|
|
_renderMenu: function( ul, items ) {
|
|
var self = this;
|
|
$.each( items, function( index, item ) {
|
|
self._renderItem( ul, item );
|
|
});
|
|
},
|
|
|
|
_renderItem: function( ul, item) {
|
|
return $( "<li></li>" )
|
|
.data( "item.autocomplete", item )
|
|
.append( $( "<a></a>" ).text( item.label ) )
|
|
.appendTo( ul );
|
|
},
|
|
|
|
_move: function( direction, event ) {
|
|
if ( !this.menu.element.is(":visible") ) {
|
|
this.search( null, event );
|
|
return;
|
|
}
|
|
if ( this.menu.first() && /^previous/.test(direction) ||
|
|
this.menu.last() && /^next/.test(direction) ) {
|
|
this.element.val( this.term );
|
|
this.menu.deactivate();
|
|
return;
|
|
}
|
|
this.menu[ direction ]( event );
|
|
},
|
|
|
|
widget: function() {
|
|
return this.menu.element;
|
|
}
|
|
});
|
|
|
|
$.extend( $.ui.autocomplete, {
|
|
escapeRegex: function( value ) {
|
|
return value.replace(/[-[\]{}()*+?.,\\^$|#\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 );
|
|
});
|
|
}
|
|
});
|
|
|
|
}( jQuery ));
|
|
|
|
/*
|
|
* jQuery UI Menu (not officially released)
|
|
*
|
|
* This widget isn't yet finished and the API is subject to change. We plan to finish
|
|
* it for the next release. You're welcome to give it a try anyway and give us feedback,
|
|
* as long as you're okay with migrating your code later on. We can help with that, too.
|
|
*
|
|
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://docs.jquery.com/UI/Menu
|
|
*
|
|
* Depends:
|
|
* jquery.ui.core.js
|
|
* jquery.ui.widget.js
|
|
*/
|
|
(function($) {
|
|
|
|
$.widget("ui.menu", {
|
|
_create: function() {
|
|
var self = this;
|
|
this.element
|
|
.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
|
|
.attr({
|
|
role: "listbox",
|
|
"aria-activedescendant": "ui-active-menuitem"
|
|
})
|
|
.click(function( event ) {
|
|
if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
|
|
return;
|
|
}
|
|
// temporary
|
|
event.preventDefault();
|
|
self.select( event );
|
|
});
|
|
this.refresh();
|
|
},
|
|
|
|
refresh: function() {
|
|
var self = this;
|
|
|
|
// don't refresh list items that are already adapted
|
|
var items = this.element.children("li:not(.ui-menu-item):has(a)")
|
|
.addClass("ui-menu-item")
|
|
.attr("role", "menuitem");
|
|
|
|
items.children("a")
|
|
.addClass("ui-corner-all")
|
|
.attr("tabindex", -1)
|
|
// mouseenter doesn't work with event delegation
|
|
.mouseenter(function( event ) {
|
|
self.activate( event, $(this).parent() );
|
|
})
|
|
.mouseleave(function() {
|
|
self.deactivate();
|
|
});
|
|
},
|
|
|
|
activate: function( event, item ) {
|
|
this.deactivate();
|
|
if (this.hasScroll()) {
|
|
var offset = item.offset().top - this.element.offset().top,
|
|
scroll = this.element.attr("scrollTop"),
|
|
elementHeight = this.element.height();
|
|
if (offset < 0) {
|
|
this.element.attr("scrollTop", scroll + offset);
|
|
} else if (offset >= elementHeight) {
|
|
this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
|
|
}
|
|
}
|
|
this.active = item.eq(0)
|
|
.children("a")
|
|
.addClass("ui-state-hover")
|
|
.attr("id", "ui-active-menuitem")
|
|
.end();
|
|
this._trigger("focus", event, { item: item });
|
|
},
|
|
|
|
deactivate: function() {
|
|
if (!this.active) { return; }
|
|
|
|
this.active.children("a")
|
|
.removeClass("ui-state-hover")
|
|
.removeAttr("id");
|
|
this._trigger("blur");
|
|
this.active = null;
|
|
},
|
|
|
|
next: function(event) {
|
|
this.move("next", ".ui-menu-item:first", event);
|
|
},
|
|
|
|
previous: function(event) {
|
|
this.move("prev", ".ui-menu-item:last", event);
|
|
},
|
|
|
|
first: function() {
|
|
return this.active && !this.active.prevAll(".ui-menu-item").length;
|
|
},
|
|
|
|
last: function() {
|
|
return this.active && !this.active.nextAll(".ui-menu-item").length;
|
|
},
|
|
|
|
move: function(direction, edge, event) {
|
|
if (!this.active) {
|
|
this.activate(event, this.element.children(edge));
|
|
return;
|
|
}
|
|
var next = this.active[direction + "All"](".ui-menu-item").eq(0);
|
|
if (next.length) {
|
|
this.activate(event, next);
|
|
} else {
|
|
this.activate(event, this.element.children(edge));
|
|
}
|
|
},
|
|
|
|
// TODO merge with previousPage
|
|
nextPage: function(event) {
|
|
if (this.hasScroll()) {
|
|
// TODO merge with no-scroll-else
|
|
if (!this.active || this.last()) {
|
|
this.activate(event, this.element.children(":first"));
|
|
return;
|
|
}
|
|
var base = this.active.offset().top,
|
|
height = this.element.height(),
|
|
result = this.element.children("li").filter(function() {
|
|
var close = $(this).offset().top - base - height + $(this).height();
|
|
// TODO improve approximation
|
|
return close < 10 && close > -10;
|
|
});
|
|
|
|
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
|
if (!result.length) {
|
|
result = this.element.children(":last");
|
|
}
|
|
this.activate(event, result);
|
|
} else {
|
|
this.activate(event, this.element.children(!this.active || this.last() ? ":first" : ":last"));
|
|
}
|
|
},
|
|
|
|
// TODO merge with nextPage
|
|
previousPage: function(event) {
|
|
if (this.hasScroll()) {
|
|
// TODO merge with no-scroll-else
|
|
if (!this.active || this.first()) {
|
|
this.activate(event, this.element.children(":last"));
|
|
return;
|
|
}
|
|
|
|
var base = this.active.offset().top,
|
|
height = this.element.height();
|
|
result = this.element.children("li").filter(function() {
|
|
var close = $(this).offset().top - base + height - $(this).height();
|
|
// TODO improve approximation
|
|
return close < 10 && close > -10;
|
|
});
|
|
|
|
// TODO try to catch this earlier when scrollTop indicates the last page anyway
|
|
if (!result.length) {
|
|
result = this.element.children(":first");
|
|
}
|
|
this.activate(event, result);
|
|
} else {
|
|
this.activate(event, this.element.children(!this.active || this.first() ? ":last" : ":first"));
|
|
}
|
|
},
|
|
|
|
hasScroll: function() {
|
|
return this.element.height() < this.element.attr("scrollHeight");
|
|
},
|
|
|
|
select: function( event ) {
|
|
this._trigger("selected", event, { item: this.active });
|
|
}
|
|
});
|
|
|
|
}(jQuery));
|