jquery-ui/ui/core.js

348 lines
9.1 KiB
JavaScript
Raw Normal View History

/*!
2012-07-04 13:08:08 +00:00
* jQuery UI Core @VERSION
* http://jqueryui.com
2008-06-04 02:34:33 +00:00
*
* Copyright jQuery Foundation and other contributors
2012-08-09 14:13:24 +00:00
* Released under the MIT license.
* http://jquery.org/license
2008-06-04 02:34:33 +00:00
*
*/
//>>label: Core
//>>group: UI Core
//>>description: The core of jQuery UI, required for all interactions and widgets.
//>>docs: http://api.jqueryui.com/category/ui-core/
//>>demos: http://jqueryui.com/
2015-03-14 11:22:28 +00:00
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "jquery" ], factory );
} else {
// Browser globals
factory( jQuery );
}
2015-03-14 11:22:28 +00:00
}( function( $ ) {
// $.ui might exist from components with no dependencies, e.g., $.ui.position
$.ui = $.ui || {};
2008-06-04 02:34:33 +00:00
2010-07-22 23:26:37 +00:00
$.extend( $.ui, {
version: "@VERSION",
keyCode: {
BACKSPACE: 8,
COMMA: 188,
DELETE: 46,
DOWN: 40,
END: 35,
ENTER: 13,
ESCAPE: 27,
HOME: 36,
LEFT: 37,
PAGE_DOWN: 34,
PAGE_UP: 33,
PERIOD: 190,
RIGHT: 39,
SPACE: 32,
TAB: 9,
UP: 38
},
// Internal use only
safeActiveElement: function( document ) {
var activeElement;
// Support: IE 9 only
// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
try {
activeElement = document.activeElement;
} catch ( error ) {
activeElement = document.body;
}
// Support: IE 9 - 11 only
// IE may return null instead of an element
// Interestingly, this only seems to occur when NOT in an iframe
if ( !activeElement ) {
activeElement = document.body;
}
// Support: IE 11 only
// IE11 returns a seemingly empty object in some cases when accessing
// document.activeElement from an <iframe>
if ( !activeElement.nodeName ) {
activeElement = document.body;
}
return activeElement;
},
// Internal use only
safeBlur: function( element ) {
// Support: IE9 - 10 only
// If the <body> is blurred, IE will switch windows, see #9420
if ( element && element.nodeName.toLowerCase() !== "body" ) {
$( element ).blur();
}
},
// Internal use only
escapeSelector: ( function() {
var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
return function( selector ) {
return selector.replace( selectorEscape, "\\$1" );
};
} )()
2015-03-14 11:22:28 +00:00
} );
// plugins
2015-03-14 11:22:28 +00:00
$.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" ) );
2015-03-14 11:22:28 +00:00
} ).eq( 0 );
2008-11-28 15:43:32 +00:00
return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
},
2015-03-14 11:22:28 +00:00
uniqueId: ( function() {
var uuid = 0;
return function() {
2015-03-14 11:22:28 +00:00
return this.each( function() {
if ( !this.id ) {
this.id = "ui-id-" + ( ++uuid );
}
2015-03-14 11:22:28 +00:00
} );
};
2015-03-14 11:22:28 +00:00
} )(),
removeUniqueId: function() {
2015-03-14 11:22:28 +00:00
return this.each( function() {
if ( /^ui-id-\d+$/.test( this.id ) ) {
$( this ).removeAttr( "id" );
}
2015-03-14 11:22:28 +00:00
} );
},
// Support: IE8 Only
// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
// with a string, so we need to find the proper form.
form: function() {
return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
},
labels: function() {
var ancestor, selector, id, labels, ancestors;
// Check control.labels first
if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
return this.pushStack( this[ 0 ].labels );
}
// Support: IE <= 11, FF <= 37, Android <= 2.3 only
// Above browsers do not support control.labels. Everything below is to support them
// as well as document fragments. control.labels does not work on document fragments
labels = this.eq( 0 ).parents( "label" );
// Look for the label based on the id
id = this.attr( "id" );
if ( id ) {
// We don't search against the document in case the element
// is disconnected from the DOM
ancestor = this.eq( 0 ).parents().last();
// Get a full set of top level ancestors
ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
// Create a selector for the label based on the id
selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
labels = labels.add( ancestors.find( selector ).addBack( selector ) );
}
// Return whatever we have found for labels
return this.pushStack( labels );
}
2015-03-14 11:22:28 +00:00
} );
// selectors
function focusable( element, hasTabindex ) {
2012-04-02 23:12:21 +00:00
var map, mapName, img,
nodeName = element.nodeName.toLowerCase();
if ( "area" === nodeName ) {
2012-04-02 23:12:21 +00:00
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 ) ?
2012-04-02 19:55:50 +00:00
!element.disabled :
2012-04-02 23:12:21 +00:00
"a" === nodeName ?
element.href || hasTabindex :
hasTabindex ) &&
// the element and all of its ancestors must be visible
2012-04-02 19:55:50 +00:00
visible( element );
}
function visible( element ) {
return $.expr.filters.visible( element ) &&
2015-03-14 11:22:28 +00:00
!$( element ).parents().addBack().filter( function() {
return $.css( this, "visibility" ) === "hidden";
2015-03-14 11:22:28 +00:00
} ).length;
}
2010-07-22 23:26:37 +00:00
$.extend( $.expr[ ":" ], {
data: $.expr.createPseudo ?
2015-03-14 11:22:28 +00:00
$.expr.createPseudo( function( dataName ) {
return function( elem ) {
return !!$.data( elem, dataName );
};
2015-03-14 11:22:28 +00:00
} ) :
// support: jQuery <1.8
function( elem, i, match ) {
return !!$.data( elem, match[ 3 ] );
},
2010-07-22 23:26:37 +00:00
focusable: function( element ) {
return focusable( element, $.attr( element, "tabindex" ) != null );
},
2010-07-22 23:26:37 +00:00
tabbable: function( element ) {
var tabIndex = $.attr( element, "tabindex" ),
hasTabindex = tabIndex != null;
return ( !hasTabindex || tabIndex >= 0 ) && focusable( element, hasTabindex );
}
2015-03-14 11:22:28 +00:00
} );
// support: jQuery 1.7 only
// Not a great way to check versions, but since we only support 1.7+ and only
// need to detect <1.8, this is a simple check that should suffice. Checking
// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
// 1.7 anymore). See #11197 for why we're not using feature detection.
if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
// Unlike jQuery Core 1.8+, these only support numeric values to set the
// dimensions in pixels
$.each( [ "Width", "Height" ], function( i, name ) {
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
type = name.toLowerCase(),
orig = {
innerWidth: $.fn.innerWidth,
innerHeight: $.fn.innerHeight,
outerWidth: $.fn.outerWidth,
outerHeight: $.fn.outerHeight
};
function reduce( elem, size, border, margin ) {
$.each( side, function() {
size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
if ( border ) {
size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
}
if ( margin ) {
size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
}
2015-03-14 11:22:28 +00:00
} );
return size;
}
$.fn[ "inner" + name ] = function( size ) {
if ( size === undefined ) {
return orig[ "inner" + name ].call( this );
}
2015-03-14 11:22:28 +00:00
return this.each( function() {
$( this ).css( type, reduce( this, size ) + "px" );
2015-03-14 11:22:28 +00:00
} );
};
2015-03-14 11:22:28 +00:00
$.fn[ "outer" + name ] = function( size, margin ) {
if ( typeof size !== "number" ) {
return orig[ "outer" + name ].call( this, size );
}
2015-03-14 11:22:28 +00:00
return this.each( function() {
$( this ).css( type, reduce( this, size, true, margin ) + "px" );
} );
};
2015-03-14 11:22:28 +00:00
} );
$.fn.addBack = function( selector ) {
return this.add( selector == null ?
this.prevObject : this.prevObject.filter( selector )
);
};
}
// deprecated
$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
2015-03-14 11:22:28 +00:00
$.fn.extend( {
disableSelection: ( function() {
var eventType = "onselectstart" in document.createElement( "div" ) ?
"selectstart" :
"mousedown";
return function() {
return this.bind( eventType + ".ui-disableSelection", function( event ) {
event.preventDefault();
2015-03-14 11:22:28 +00:00
} );
};
2015-03-14 11:22:28 +00:00
} )(),
enableSelection: function() {
return this.unbind( ".ui-disableSelection" );
}
2015-03-14 11:22:28 +00:00
} );
// $.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 ] ] );
2010-08-27 15:52:03 +00:00
}
},
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;
2010-08-27 15:52:03 +00:00
}
2012-08-23 11:35:40 +00:00
for ( i = 0; i < set.length; i++ ) {
if ( instance.options[ set[ i ][ 0 ] ] ) {
set[ i ][ 1 ].apply( instance.element, args );
}
2010-08-27 15:52:03 +00:00
}
}
};
2010-08-27 15:52:03 +00:00
2015-03-14 11:22:28 +00:00
} ) );