(function(){
/*
- * jQuery 1.2.1 - New Wave Javascript
+ * jQuery 1.2.2 - New Wave Javascript
*
* Copyright (c) 2007 John Resig (jquery.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
- * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
- * $Rev: 3353 $
+ * $Date: 2008-01-14 17:56:07 -0500 (Mon, 14 Jan 2008) $
+ * $Rev: 4454 $
*/
// Map over jQuery in case of overwrite
-if ( typeof jQuery != "undefined" )
- var _jQuery = jQuery;
-
-var jQuery = window.jQuery = function(selector, context) {
- // If the context is a namespace object, return a new object
- return this instanceof jQuery ?
- this.init(selector, context) :
- new jQuery(selector, context);
+if ( window.jQuery )
+ var _jQuery = window.jQuery;
+
+var jQuery = window.jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.prototype.init( selector, context );
};
// Map over the $ in case of overwrite
-if ( typeof $ != "undefined" )
- var _$ = $;
+if ( window.$ )
+ var _$ = window.$;
// Map the jQuery namespace to the '$' one
window.$ = jQuery;
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+// Is it a simple selector
+var isSimple = /^.[^:#\[\.]*$/;
+
jQuery.fn = jQuery.prototype = {
- init: function(selector, context) {
+ init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ return this;
+
// Handle HTML strings
- if ( typeof selector == "string" ) {
- var m = quickExpr.exec(selector);
- if ( m && (m[1] || !context) ) {
+ } else if ( typeof selector == "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
// HANDLE: $(html) -> $(array)
- if ( m[1] )
- selector = jQuery.clean( [ m[1] ], context );
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
// HANDLE: $("#id")
else {
- var tmp = document.getElementById( m[3] );
- if ( tmp )
+ var elem = document.getElementById( match[3] );
+
+ // Make sure an element was located
+ if ( elem )
// Handle the case where IE and Opera return items
// by name instead of ID
- if ( tmp.id != m[3] )
+ if ( elem.id != match[3] )
return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
else {
- this[0] = tmp;
+ this[0] = elem;
this.length = 1;
return this;
}
+
else
selector = [];
}
- // HANDLE: $(expr)
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
} else
return new jQuery( context ).find( selector );
// HANDLE: $(function)
// Shortcut for document ready
- } else if ( jQuery.isFunction(selector) )
- return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+ } else if ( jQuery.isFunction( selector ) )
+ return new jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
return this.setArray(
// HANDLE: $(array)
selector.constructor == Array && selector ||
// HANDLE: $(arraylike)
- // Watch for when an array-like object is passed as the selector
+ // Watch for when an array-like object, contains DOM nodes, is passed in as the selector
(selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
// HANDLE: $(*)
[ selector ] );
},
- jquery: "1.2.1",
+ // The current version of jQuery being used
+ jquery: "1.2.2",
+ // The number of elements contained in the matched element set
size: function() {
return this.length;
},
+ // The number of elements contained in the matched element set
length: 0,
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
get: function( num ) {
return num == undefined ?
jQuery.makeArray( this ) :
// Return just the object
- this[num];
+ this[ num ];
},
- pushStack: function( a ) {
- var ret = jQuery(a);
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
ret.prevObject = this;
+
+ // Return the newly-formed element set
return ret;
},
- setArray: function( a ) {
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
this.length = 0;
- Array.prototype.push.apply( this, a );
+ Array.prototype.push.apply( this, elems );
+
return this;
},
- each: function( fn, args ) {
- return jQuery.each( this, fn, args );
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
},
- index: function( obj ) {
- var pos = -1;
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ var ret = -1;
+
+ // Locate the position of the desired element
this.each(function(i){
- if ( this == obj ) pos = i;
+ if ( this == elem )
+ ret = i;
});
- return pos;
+
+ return ret;
},
- attr: function( key, value, type ) {
- var obj = key;
+ attr: function( name, value, type ) {
+ var options = name;
// Look for the case where we're accessing a style value
- if ( key.constructor == String )
+ if ( name.constructor == String )
if ( value == undefined )
- return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+ return this.length && jQuery[ type || "attr" ]( this[0], name ) || undefined;
+
else {
- obj = {};
- obj[ key ] = value;
+ options = {};
+ options[ name ] = value;
}
// Check to see if we're setting style values
- return this.each(function(index){
+ return this.each(function(i){
// Set all the styles
- for ( var prop in obj )
+ for ( name in options )
jQuery.attr(
- type ? this.style : this,
- prop, jQuery.prop(this, obj[prop], type, index, prop)
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
);
});
},
css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
return this.attr( key, value, "curCSS" );
},
- text: function(e) {
- if ( typeof e != "object" && e != null )
- return this.empty().append( document.createTextNode( e ) );
+ text: function( text ) {
+ if ( typeof text != "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
- var t = "";
- jQuery.each( e || this, function(){
+ jQuery.each( text || this, function(){
jQuery.each( this.childNodes, function(){
if ( this.nodeType != 8 )
- t += this.nodeType != 1 ?
- this.nodeValue : jQuery.fn.text([ this ]);
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
});
});
- return t;
+
+ return ret;
},
- wrapAll: function(html) {
+ wrapAll: function( html ) {
if ( this[0] )
// The elements to wrap the target around
- jQuery(html, this[0].ownerDocument)
+ jQuery( html, this[0].ownerDocument )
.clone()
- .insertBefore(this[0])
+ .insertBefore( this[0] )
.map(function(){
var elem = this;
+
while ( elem.firstChild )
elem = elem.firstChild;
+
return elem;
})
.append(this);
return this;
},
- wrapInner: function(html) {
+ wrapInner: function( html ) {
return this.each(function(){
- jQuery(this).contents().wrapAll(html);
+ jQuery( this ).contents().wrapAll( html );
});
},
- wrap: function(html) {
+ wrap: function( html ) {
return this.each(function(){
- jQuery(this).wrapAll(html);
+ jQuery( this ).wrapAll( html );
});
},
append: function() {
- return this.domManip(arguments, true, 1, function(a){
- this.appendChild( a );
+ return this.domManip(arguments, true, false, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
});
},
prepend: function() {
- return this.domManip(arguments, true, -1, function(a){
- this.insertBefore( a, this.firstChild );
+ return this.domManip(arguments, true, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
});
},
before: function() {
- return this.domManip(arguments, false, 1, function(a){
- this.parentNode.insertBefore( a, this );
+ return this.domManip(arguments, false, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
});
},
after: function() {
- return this.domManip(arguments, false, -1, function(a){
- this.parentNode.insertBefore( a, this.nextSibling );
+ return this.domManip(arguments, false, true, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
});
},
end: function() {
- return this.prevObject || jQuery([]);
+ return this.prevObject || jQuery( [] );
},
- find: function(t) {
- var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
- return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
- jQuery.unique( data ) : data );
+ find: function( selector ) {
+ var elems = jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ });
+
+ return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+ jQuery.unique( elems ) :
+ elems );
},
- clone: function(events) {
+ clone: function( events ) {
// Do the clone
var ret = this.map(function(){
- return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var clone = this.cloneNode(true),
+ container = document.createElement("div"),
+ container2 = document.createElement("div");
+ container.appendChild(clone);
+ container2.innerHTML = container.innerHTML;
+ return container2.firstChild;
+ } else
+ return this.cloneNode(true);
});
// Need to set the expando to null on the cloned set if it exists
});
// Copy the events from the original to the clone
- if (events === true)
- this.find("*").andSelf().each(function(i) {
- var events = jQuery.data(this, "events");
+ if ( events === true )
+ this.find("*").andSelf().each(function(i){
+ if (this.nodeType == 3)
+ return;
+ var events = jQuery.data( this, "events" );
+
for ( var type in events )
- for ( var handler in events[type] )
- jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+ for ( var handler in events[ type ] )
+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
});
// Return the cloned set
return ret;
},
- filter: function(t) {
+ filter: function( selector ) {
return this.pushStack(
- jQuery.isFunction( t ) &&
- jQuery.grep(this, function(el, index){
- return t.apply(el, [index]);
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
}) ||
- jQuery.multiFilter(t,this) );
+ jQuery.multiFilter( selector, this ) );
},
- not: function(t) {
- return this.pushStack(
- t.constructor == String &&
- jQuery.multiFilter(t, this, true) ||
+ not: function( selector ) {
+ if ( selector.constructor == String )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+ else
+ selector = jQuery.multiFilter( selector, this );
- jQuery.grep(this, function(a) {
- return ( t.constructor == Array || t.jquery )
- ? jQuery.inArray( a, t ) < 0
- : a != t;
- })
- );
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
},
- add: function(t) {
- return this.pushStack( jQuery.merge(
+ add: function( selector ) {
+ return !selector ? this : this.pushStack( jQuery.merge(
this.get(),
- t.constructor == String ?
- jQuery(t).get() :
- t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
- t : [t] )
- );
+ selector.constructor == String ?
+ jQuery( selector ).get() :
+ selector.length != undefined && (!selector.nodeName || jQuery.nodeName(selector, "form")) ?
+ selector : [selector] ) );
},
- is: function(expr) {
- return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+ is: function( selector ) {
+ return selector ?
+ jQuery.multiFilter( selector, this ).length > 0 :
+ false;
},
- hasClass: function(expr) {
- return this.is("." + expr);
+ hasClass: function( selector ) {
+ return this.is( "." + selector );
},
- val: function( val ) {
- if ( val == undefined ) {
+ val: function( value ) {
+ if ( value == undefined ) {
+
if ( this.length ) {
var elem = this[0];
-
+
// We need to handle select boxes special
- if ( jQuery.nodeName(elem, "select") ) {
+ if ( jQuery.nodeName( elem, "select" ) ) {
var index = elem.selectedIndex,
- a = [],
+ values = [],
options = elem.options,
one = elem.type == "select-one";
// Loop through all the selected options
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[i];
+ var option = options[ i ];
+
if ( option.selected ) {
// Get the specifc value for the option
- var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+ value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
// We don't need an array for one selects
if ( one )
- return val;
+ return value;
// Multi-Selects return an array
- a.push(val);
+ values.push( value );
}
}
- return a;
+ return values;
// Everything else, we just grab the value
} else
- return this[0].value.replace(/\r/g, "");
+ return (this[0].value || "").replace(/\r/g, "");
+
}
- } else
- return this.each(function(){
- if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
- this.checked = (jQuery.inArray(this.value, val) >= 0 ||
- jQuery.inArray(this.name, val) >= 0);
- else if ( jQuery.nodeName(this, "select") ) {
- var tmp = val.constructor == Array ? val : [val];
-
- jQuery("option", this).each(function(){
- this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
- jQuery.inArray(this.text, tmp) >= 0);
- });
- if ( !tmp.length )
- this.selectedIndex = -1;
- } else
- this.value = val;
- });
+ return undefined;
+ }
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = value.constructor == Array ?
+ value :
+ [ value ];
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
},
- html: function( val ) {
- return val == undefined ?
- ( this.length ? this[0].innerHTML : null ) :
- this.empty().append( val );
+ html: function( value ) {
+ return value == undefined ?
+ (this.length ?
+ this[0].innerHTML :
+ null) :
+ this.empty().append( value );
},
- replaceWith: function( val ) {
- return this.after( val ).remove();
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
},
- eq: function(i){
- return this.slice(i, i+1);
+ eq: function( i ) {
+ return this.slice( i, i + 1 );
},
slice: function() {
return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
},
- map: function(fn) {
- return this.pushStack(jQuery.map( this, function(elem,i){
- return fn.call( elem, i, elem );
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
}));
},
return this.add( this.prevObject );
},
- domManip: function(args, table, dir, fn) {
- var clone = this.length > 1, a;
+ domManip: function( args, table, reverse, callback ) {
+ var clone = this.length > 1, elems;
return this.each(function(){
- if ( !a ) {
- a = jQuery.clean(args, this.ownerDocument);
- if ( dir < 0 )
- a.reverse();
+ if ( !elems ) {
+ elems = jQuery.clean( args, this.ownerDocument );
+
+ if ( reverse )
+ elems.reverse();
}
var obj = this;
- if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
- obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+ if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
- jQuery.each( a, function(){
- var elem = clone ? this.cloneNode(true) : this;
- if ( !evalScript(0, elem) )
- fn.call( obj, elem );
+ var scripts = jQuery( [] );
+
+ jQuery.each(elems, function(){
+ var elem = clone ?
+ jQuery( this ).clone( true )[0] :
+ this;
+
+ // execute all scripts after the elements have been injected
+ if ( jQuery.nodeName( elem, "script" ) ) {
+ scripts = scripts.add( elem );
+ } else {
+ // Remove any inner scripts for later evaluation
+ if ( elem.nodeType == 1 )
+ scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+ // Inject the elements into the document
+ callback.call( obj, elem );
+ }
});
+
+ scripts.each( evalScript );
});
}
};
-function evalScript(i, elem){
- var script = jQuery.nodeName(elem, "script");
+// Give the init function the jQuery prototype for later instantiation
+jQuery.prototype.init.prototype = jQuery.prototype;
- if ( script ) {
- if ( elem.src )
- jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
- else
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
- if ( elem.parentNode )
- elem.parentNode.removeChild(elem);
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
- } else if ( elem.nodeType == 1 )
- jQuery("script", elem).each(evalScript);
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
- return script;
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
}
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
- var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
// Handle a deep copy situation
if ( target.constructor == Boolean ) {
deep = target;
target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
}
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target != "object" && typeof target != "function" )
+ target = {};
+
// extend jQuery itself if only one argument is passed
- if ( al == 1 ) {
+ if ( length == 1 ) {
target = this;
- a = 0;
+ i = 0;
}
- var prop;
-
- for ( ; a < al; a++ )
+ for ( ; i < length; i++ )
// Only deal with non-null/undefined values
- if ( (prop = arguments[a]) != null )
+ if ( (options = arguments[ i ]) != null )
// Extend the base object
- for ( var i in prop ) {
+ for ( var name in options ) {
// Prevent never-ending loop
- if ( target == prop[i] )
+ if ( target === options[ name ] )
continue;
// Recurse if we're merging object values
- if ( deep && typeof prop[i] == 'object' && target[i] )
- jQuery.extend( target[i], prop[i] );
+ if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
+ target[ name ] = jQuery.extend( target[ name ], options[ name ] );
// Don't bring in undefined values
- else if ( prop[i] != undefined )
- target[i] = prop[i];
+ else if ( options[ name ] != undefined )
+ target[ name ] = options[ name ];
+
}
// Return the modified object
return target;
};
-var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, windowData = {};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
jQuery.extend({
- noConflict: function(deep) {
+ noConflict: function( deep ) {
window.$ = _$;
+
if ( deep )
window.jQuery = _jQuery;
+
return jQuery;
},
- // This may seem like some crazy code, but trust me when I say that this
- // is the only cross-browser way to do this. --John
+ // See test/unit/core.js for details concerning this function.
isFunction: function( fn ) {
return !!fn && typeof fn != "string" && !fn.nodeName &&
fn.constructor != Array && /function/i.test( fn + "" );
},
- // check if an element is in a XML document
- isXMLDoc: function(elem) {
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
return elem.documentElement && !elem.body ||
elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
},
// Evalulates a script in a global context
- // Evaluates Async. in Safari 2 :-(
globalEval: function( data ) {
data = jQuery.trim( data );
+
if ( data ) {
- if ( window.execScript )
- window.execScript( data );
- else if ( jQuery.browser.safari )
- // safari doesn't provide a synchronous global eval
- window.setTimeout( data, 0 );
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.browser.msie )
+ script.text = data;
else
- eval.call( window, data );
+ script.appendChild( document.createTextNode( data ) );
+
+ head.appendChild( script );
+ head.removeChild( script );
}
},
cache: {},
data: function( elem, name, data ) {
- elem = elem == window ? win : elem;
+ elem = elem == window ?
+ windowData :
+ elem;
var id = elem[ expando ];
jQuery.cache[ id ][ name ] = data;
// Return the named cache data, or the ID for the element
- return name ? jQuery.cache[ id ][ name ] : id;
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
},
removeData: function( elem, name ) {
- elem = elem == window ? win : elem;
+ elem = elem == window ?
+ windowData :
+ elem;
var id = elem[ expando ];
// If we've removed all the data, remove the element's cache
name = "";
- for ( name in jQuery.cache[ id ] ) break;
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
if ( !name )
jQuery.removeData( elem );
}
},
// args is for internal usage only
- each: function( obj, fn, args ) {
+ each: function( object, callback, args ) {
if ( args ) {
- if ( obj.length == undefined )
- for ( var i in obj )
- fn.apply( obj[i], args );
- else
- for ( var i = 0, ol = obj.length; i < ol; i++ )
- if ( fn.apply( obj[i], args ) === false ) break;
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length; i < length; i++ )
+ if ( callback.apply( object[ i ], args ) === false )
+ break;
// A special, fast, case for the most common use of each
} else {
- if ( obj.length == undefined )
- for ( var i in obj )
- fn.call( obj[i], i, obj[i] );
- else
- for ( var i = 0, ol = obj.length, val = obj[0];
- i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ if ( object.length == undefined ) {
+ for ( var name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var i = 0, length = object.length, value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
}
- return obj;
+ return object;
},
- prop: function(elem, value, type, index, prop){
+ prop: function( elem, value, type, i, name ) {
// Handle executable functions
if ( jQuery.isFunction( value ) )
- value = value.call( elem, [index] );
+ value = value.call( elem, i );
- // exclude the following css properties to add px
- var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
-
// Handle passing in a number to a CSS property
- return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
value + "px" :
value;
},
className: {
// internal only, use addClass("class")
- add: function( elem, c ){
- jQuery.each( (c || "").split(/\s+/), function(i, cur){
- if ( !jQuery.className.has( elem.className, cur ) )
- elem.className += ( elem.className ? " " : "" ) + cur;
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
});
},
// internal only, use removeClass("class")
- remove: function( elem, c ){
- elem.className = c != undefined ?
- jQuery.grep( elem.className.split(/\s+/), function(cur){
- return !jQuery.className.has( c, cur );
- }).join(" ") : "";
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames != undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
},
// internal only, use is(".class")
- has: function( t, c ) {
- return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+ has: function( elem, className ) {
+ return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
}
},
- swap: function(e,o,f) {
- for ( var i in o ) {
- e.style["old"+i] = e.style[i];
- e.style[i] = o[i];
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
}
- f.apply( e, [] );
- for ( var i in o )
- e.style[i] = e.style["old"+i];
- },
-
- css: function(e,p) {
- if ( p == "height" || p == "width" ) {
- var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
-
- jQuery.each( d, function(){
- old["padding" + this] = 0;
- old["border" + this + "Width"] = 0;
- });
-
- jQuery.swap( e, old, function() {
- if ( jQuery(e).is(':visible') ) {
- oHeight = e.offsetHeight;
- oWidth = e.offsetWidth;
- } else {
- e = jQuery(e.cloneNode(true))
- .find(":radio").removeAttr("checked").end()
- .css({
- visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
- }).appendTo(e.parentNode)[0];
- var parPos = jQuery.css(e.parentNode,"position") || "static";
- if ( parPos == "static" )
- e.parentNode.style.position = "relative";
+ callback.call( elem );
- oHeight = e.clientHeight;
- oWidth = e.clientWidth;
-
- if ( parPos == "static" )
- e.parentNode.style.position = "static";
-
- e.parentNode.removeChild(e);
- }
- });
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
- return p == "height" ? oHeight : oWidth;
+ css: function( elem, name, force ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+ var padding = 0, border = 0;
+ jQuery.each( which, function() {
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ val -= Math.round(padding + border);
+ }
+
+ if ( jQuery(elem).is(":visible") )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, val);
}
-
- return jQuery.curCSS( e, p );
+
+ return jQuery.curCSS( elem, name, force );
},
- curCSS: function(elem, prop, force) {
- var ret, stack = [], swap = [];
+ curCSS: function( elem, name, force ) {
+ var ret;
// A helper method for determining if an element's values are broken
- function color(a){
+ function color( elem ) {
if ( !jQuery.browser.safari )
return false;
- var ret = document.defaultView.getComputedStyle(a,null);
+ var ret = document.defaultView.getComputedStyle( elem, null );
return !ret || ret.getPropertyValue("color") == "";
}
- if (prop == "opacity" && jQuery.browser.msie) {
- ret = jQuery.attr(elem.style, "opacity");
- return ret == "" ? "1" : ret;
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ ret = jQuery.attr( elem.style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037
+ if ( jQuery.browser.opera && name == "display" ) {
+ var save = elem.style.display;
+ elem.style.display = "block";
+ elem.style.display = save;
}
- if (prop.match(/float/i))
- prop = styleFloat;
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && elem.style && elem.style[ name ] )
+ ret = elem.style[ name ];
- if (!force && elem.style[prop])
- ret = elem.style[prop];
+ else if ( document.defaultView && document.defaultView.getComputedStyle ) {
- else if (document.defaultView && document.defaultView.getComputedStyle) {
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
- if (prop.match(/float/i))
- prop = "float";
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
- prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
- var cur = document.defaultView.getComputedStyle(elem, null);
+ var getComputedStyle = document.defaultView.getComputedStyle( elem, null );
- if ( cur && !color(elem) )
- ret = cur.getPropertyValue(prop);
+ if ( getComputedStyle && !color( elem ) )
+ ret = getComputedStyle.getPropertyValue( name );
// If the element isn't reporting its values properly in Safari
// then some display: none elements are involved
else {
+ var swap = [], stack = [];
+
// Locate all of the parent display: none elements
for ( var a = elem; a && color(a); a = a.parentNode )
stack.unshift(a);
// Go through and make them visible, but in reverse
// (It would be better if we knew the exact display type that they had)
- for ( a = 0; a < stack.length; a++ )
- if ( color(stack[a]) ) {
- swap[a] = stack[a].style.display;
- stack[a].style.display = "block";
+ for ( var i = 0; i < stack.length; i++ )
+ if ( color( stack[ i ] ) ) {
+ swap[ i ] = stack[ i ].style.display;
+ stack[ i ].style.display = "block";
}
// Since we flip the display style, we have to handle that
// one special, otherwise get the value
- ret = prop == "display" && swap[stack.length-1] != null ?
+ ret = name == "display" && swap[ stack.length - 1 ] != null ?
"none" :
- document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+ ( getComputedStyle && getComputedStyle.getPropertyValue( name ) ) || "";
// Finally, revert the display styles back
- for ( a = 0; a < swap.length; a++ )
- if ( swap[a] != null )
- stack[a].style.display = swap[a];
+ for ( var i = 0; i < swap.length; i++ )
+ if ( swap[ i ] != null )
+ stack[ i ].style.display = swap[ i ];
}
- if ( prop == "opacity" && ret == "" )
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
ret = "1";
- } else if (elem.currentStyle) {
- var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
- ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
// From the awesome hack by Dean Edwards
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
// If we're not dealing with a regular pixel number
// but a number that has a weird ending, we need to convert it to pixels
- if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
- var style = elem.style.left;
- var runtimeStyle = elem.runtimeStyle.left;
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var style = elem.style.left, runtimeStyle = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
elem.runtimeStyle.left = elem.currentStyle.left;
elem.style.left = ret || 0;
ret = elem.style.pixelLeft + "px";
+
+ // Revert the changed values
elem.style.left = style;
elem.runtimeStyle.left = runtimeStyle;
}
return ret;
},
- clean: function(a, doc) {
- var r = [];
- doc = doc || document;
+ clean: function( elems, context ) {
+ var ret = [];
+ context = context || document;
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if (typeof context.createElement == 'undefined')
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
- jQuery.each( a, function(i,arg){
- if ( !arg ) return;
+ jQuery.each(elems, function(i, elem){
+ if ( !elem )
+ return;
- if ( arg.constructor == Number )
- arg = arg.toString();
+ if ( elem.constructor == Number )
+ elem = elem.toString();
// Convert html string into DOM nodes
- if ( typeof arg == "string" ) {
+ if ( typeof elem == "string" ) {
// Fix "XHTML"-style tags in all browsers
- arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">";
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
});
// Trim whitespace, otherwise indexOf won't work as expected
- var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+ var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
var wrap =
// option or optgroup
- !s.indexOf("<opt") &&
- [1, "<select>", "</select>"] ||
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
- !s.indexOf("<leg") &&
- [1, "<fieldset>", "</fieldset>"] ||
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
- s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
- [1, "<table>", "</table>"] ||
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
- !s.indexOf("<tr") &&
- [2, "<table><tbody>", "</tbody></table>"] ||
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
// <thead> matched above
- (!s.indexOf("<td") || !s.indexOf("<th")) &&
- [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
- !s.indexOf("<col") &&
- [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
// IE can't serialize <link> and <script> tags normally
jQuery.browser.msie &&
- [1, "div<div>", "</div>"] ||
+ [ 1, "div<div>", "</div>" ] ||
- [0,"",""];
+ [ 0, "", "" ];
// Go to html and back, then peel off extra wrappers
- div.innerHTML = wrap[1] + arg + wrap[2];
+ div.innerHTML = wrap[1] + elem + wrap[2];
// Move to the right depth
while ( wrap[0]-- )
if ( jQuery.browser.msie ) {
// String was a <table>, *may* have spurious <tbody>
- if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
- tb = div.firstChild && div.firstChild.childNodes;
+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+ div.firstChild && div.firstChild.childNodes :
- // String was a bare <thead> or <tfoot>
- else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
- tb = div.childNodes;
-
- for ( var n = tb.length-1; n >= 0 ; --n )
- if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
- tb[n].parentNode.removeChild(tb[n]);
-
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
// IE completely kills leading whitespace when innerHTML is used
- if ( /^\s/.test(arg) )
- div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
-
+ if ( /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
}
- arg = jQuery.makeArray( div.childNodes );
+ elem = jQuery.makeArray( div.childNodes );
}
- if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
+ if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
return;
- if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
- r.push( arg );
+ if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
+ ret.push( elem );
+
else
- r = jQuery.merge( r, arg );
+ ret = jQuery.merge( ret, elem );
});
- return r;
+ return ret;
},
- attr: function(elem, name, value){
- var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var fix = jQuery.isXMLDoc( elem ) ?
+ {} :
+ jQuery.props;
// Safari mis-reports the default selected property of a hidden option
// Accessing the parent's selectedIndex property fixes it
elem.parentNode.selectedIndex;
// Certain attributes only work when accessed via the old DOM 0 way
- if ( fix[name] ) {
- if ( value != undefined ) elem[fix[name]] = value;
- return elem[fix[name]];
+ if ( fix[ name ] ) {
+ if ( value != undefined )
+ elem[ fix[ name ] ] = value;
+
+ return elem[ fix[ name ] ];
+
} else if ( jQuery.browser.msie && name == "style" )
return jQuery.attr( elem.style, "cssText", value );
- else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
- return elem.getAttributeNode(name).nodeValue;
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName( elem, "form" ) && (name == "action" || name == "method") )
+ return elem.getAttributeNode( name ).nodeValue;
// IE elem.getAttribute passes even for style
else if ( elem.tagName ) {
if ( value != undefined ) {
- if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode )
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
throw "type property can't be changed";
- elem.setAttribute( name, value );
+
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
}
- if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
+ if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) )
return elem.getAttribute( name, 2 );
return elem.getAttribute( name );
elem.zoom = 1;
// Set the alpha filter to set the opacity
- elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
- (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
}
- return elem.filter ?
- (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :
+ "";
}
- name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
- if ( value != undefined ) elem[name] = value;
- return elem[name];
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( value != undefined )
+ elem[ name ] = value;
+
+ return elem[ name ];
}
},
- trim: function(t){
- return (t||"").replace(/^\s+|\s+$/g, "");
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
},
- makeArray: function( a ) {
- var r = [];
+ makeArray: function( array ) {
+ var ret = [];
// Need to use typeof to fight Safari childNodes crashes
- if ( typeof a != "array" )
- for ( var i = 0, al = a.length; i < al; i++ )
- r.push( a[i] );
+ if ( typeof array != "array" )
+ for ( var i = 0, length = array.length; i < length; i++ )
+ ret.push( array[ i ] );
else
- r = a.slice( 0 );
+ ret = array.slice( 0 );
- return r;
+ return ret;
},
- inArray: function( b, a ) {
- for ( var i = 0, al = a.length; i < al; i++ )
- if ( a[i] == b )
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ if ( array[ i ] == elem )
return i;
+
return -1;
},
- merge: function(first, second) {
+ merge: function( first, second ) {
// We have to loop this way because IE & Opera overwrite the length
// expando of getElementsByTagName
// Also, we need to make sure that the correct elements are being returned
// (IE returns comment nodes in a '*' query)
if ( jQuery.browser.msie ) {
- for ( var i = 0; second[i]; i++ )
- if ( second[i].nodeType != 8 )
- first.push(second[i]);
+ for ( var i = 0; second[ i ]; i++ )
+ if ( second[ i ].nodeType != 8 )
+ first.push( second[ i ] );
+
} else
- for ( var i = 0; second[i]; i++ )
- first.push(second[i]);
+ for ( var i = 0; second[ i ]; i++ )
+ first.push( second[ i ] );
return first;
},
- unique: function(first) {
- var r = [], done = {};
+ unique: function( array ) {
+ var ret = [], done = {};
try {
- for ( var i = 0, fl = first.length; i < fl; i++ ) {
- var id = jQuery.data(first[i]);
- if ( !done[id] ) {
- done[id] = true;
- r.push(first[i]);
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
}
}
- } catch(e) {
- r = first;
+
+ } catch( e ) {
+ ret = array;
}
- return r;
+ return ret;
},
- grep: function(elems, fn, inv) {
+ grep: function( elems, callback, inv ) {
// If a string is passed in for the function, make a function
// for it (a handy shortcut)
- if ( typeof fn == "string" )
- fn = eval("false||function(a,i){return " + fn + "}");
+ if ( typeof callback == "string" )
+ callback = eval("false||function(a,i){return " + callback + "}");
- var result = [];
+ var ret = [];
// Go through the array, only saving the items
// that pass the validator function
- for ( var i = 0, el = elems.length; i < el; i++ )
- if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
- result.push( elems[i] );
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv && callback( elems[ i ], i ) || inv && !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
- return result;
+ return ret;
},
- map: function(elems, fn) {
- // If a string is passed in for the function, make a function
- // for it (a handy shortcut)
- if ( typeof fn == "string" )
- fn = eval("false||function(a){return " + fn + "}");
-
- var result = [];
+ map: function( elems, callback ) {
+ var ret = [];
// Go through the array, translating each of the items to their
// new value (or values).
- for ( var i = 0, el = elems.length; i < el; i++ ) {
- var val = fn(elems[i],i);
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value !== null && value != undefined ) {
+ if ( value.constructor != Array )
+ value = [ value ];
- if ( val !== null && val != undefined ) {
- if ( val.constructor != Array ) val = [val];
- result = result.concat( val );
+ ret = ret.concat( value );
}
}
- return result;
+ return ret;
}
});
// Figure out what browser is being used
jQuery.browser = {
- version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
- safari: /webkit/.test(userAgent),
- opera: /opera/.test(userAgent),
- msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
- mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};
-var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+var styleFloat = jQuery.browser.msie ?
+ "styleFloat" :
+ "cssFloat";
jQuery.extend({
// Check to see if the W3C box model is being used
boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
- styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
-
props: {
"for": "htmlFor",
"class": "className",
checked: "checked",
readonly: "readOnly",
selected: "selected",
- maxlength: "maxLength"
+ maxlength: "maxLength",
+ selectedIndex: "selectedIndex",
+ defaultValue: "defaultValue",
+ tagName: "tagName",
+ nodeName: "nodeName"
}
});
jQuery.each({
- parent: "a.parentNode",
- parents: "jQuery.dir(a,'parentNode')",
- next: "jQuery.nth(a,2,'nextSibling')",
- prev: "jQuery.nth(a,2,'previousSibling')",
- nextAll: "jQuery.dir(a,'nextSibling')",
- prevAll: "jQuery.dir(a,'previousSibling')",
- siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
- children: "jQuery.sibling(a.firstChild)",
- contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
-}, function(i,n){
- jQuery.fn[ i ] = function(a) {
- var ret = jQuery.map(this,n);
- if ( a && typeof a == "string" )
- ret = jQuery.multiFilter(a,ret);
- return this.pushStack( jQuery.unique(ret) );
+ parent: "elem.parentNode",
+ parents: "jQuery.dir(elem,'parentNode')",
+ next: "jQuery.nth(elem,2,'nextSibling')",
+ prev: "jQuery.nth(elem,2,'previousSibling')",
+ nextAll: "jQuery.dir(elem,'nextSibling')",
+ prevAll: "jQuery.dir(elem,'previousSibling')",
+ siblings: "jQuery.sibling(elem.parentNode.firstChild,elem)",
+ children: "jQuery.sibling(elem.firstChild)",
+ contents: "jQuery.nodeName(elem,'iframe')?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes)"
+}, function(name, fn){
+ fn = eval("false||function(elem){return " + fn + "}");
+
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ) );
};
});
insertBefore: "before",
insertAfter: "after",
replaceAll: "replaceWith"
-}, function(i,n){
- jQuery.fn[ i ] = function(){
- var a = arguments;
+}, function(name, original){
+ jQuery.fn[ name ] = function() {
+ var args = arguments;
+
return this.each(function(){
- for ( var j = 0, al = a.length; j < al; j++ )
- jQuery(a[j])[n]( this );
+ for ( var i = 0, length = args.length; i < length; i++ )
+ jQuery( args[ i ] )[ original ]( this );
});
};
});
-jQuery.each( {
- removeAttr: function( key ) {
- jQuery.attr( this, key, "" );
- this.removeAttribute( key );
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
},
- addClass: function(c){
- jQuery.className.add(this,c);
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
},
- removeClass: function(c){
- jQuery.className.remove(this,c);
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
},
- toggleClass: function( c ){
- jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
+
+ toggleClass: function( classNames ) {
+ jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
},
- remove: function(a){
- if ( !a || jQuery.filter( a, [this] ).r.length ) {
- jQuery.removeData( this );
- this.parentNode.removeChild( this );
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add(this).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
}
},
- empty: function() {
- // Clean up the cache
- jQuery("*", this).each(function(){ jQuery.removeData(this); });
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery( ">*", this ).remove();
+
+ // Remove any remaining nodes
while ( this.firstChild )
this.removeChild( this.firstChild );
}
-}, function(i,n){
- jQuery.fn[ i ] = function() {
- return this.each( n, arguments );
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
};
});
-jQuery.each( [ "Height", "Width" ], function(i,name){
- var n = name.toLowerCase();
+jQuery.each([ "Height", "Width" ], function(i, name){
+ var type = name.toLowerCase();
- jQuery.fn[ n ] = function(h) {
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
return this[0] == window ?
- jQuery.browser.safari && self["inner" + name] ||
- jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
- document.body["client" + name] :
+ // Opera reports document.body.client[Width/Height] properly in both quirks and standards
+ jQuery.browser.opera && document.body[ "client" + name ] ||
+
+ // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
+ jQuery.browser.safari && window[ "inner" + name ] ||
+
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
+ // Get document width or height
this[0] == document ?
- Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
-
- h == undefined ?
- ( this.length ? jQuery.css( this[0], n ) : null ) :
- this.css( n, h.constructor == String ? h : h + "px" );
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
+ Math.max(document.body["offset" + name], document.documentElement["offset" + name])
+ ) :
+
+ // Get or set width or height on the element
+ size == undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, size.constructor == String ? size : size + "px" );
};
});
if ( typeof t != "string" )
return [ t ];
- // Make sure that the context is a DOM Element
- if ( context && !context.nodeType )
- context = null;
+ // check to make sure context is a DOM element or a document
+ if ( context && context.nodeType != 1 && context.nodeType != 9)
+ return [ ];
// Set the correct context (if none is provided)
context = context || document;
// Initialize the search
- var ret = [context], done = [], last;
+ var ret = [context], done = [], last, nodeName;
// Continue while a selector expression exists, and while
// we're no longer looping upon ourselves
var m = re.exec(t);
if ( m ) {
- var nodeName = m[1].toUpperCase();
+ nodeName = m[1].toUpperCase();
// Perform our own iteration and filter
for ( var i = 0; ret[i]; i++ )
for ( var c = ret[i].firstChild; c; c = c.nextSibling )
- if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
r.push( c );
ret = r;
if ( (m = re.exec(t)) != null ) {
r = [];
- var nodeName = m[2], merge = {};
+ var merge = {};
+ nodeName = m[2].toUpperCase();
m = m[1];
for ( var j = 0, rl = ret.length; j < rl; j++ ) {
if ( m == "~" && merge[id] ) break;
- if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
if ( m == "~" ) merge[id] = true;
r.push( n );
}
// Re-organize the results, so that they're consistent
if ( m ) {
- m = [ 0, m[2], m[3], m[1] ];
+ m = [ 0, m[2], m[3], m[1] ];
} else {
// Otherwise, do a traditional filter check for
var last;
// Look for common filter expressions
- while ( t && t != last ) {
+ while ( t && t != last ) {
last = t;
var p = jQuery.parse, m;
// :not() is a special case that can be optimized by
// keeping it out of the expression list
if ( m[1] == ":" && m[2] == "not" )
- r = jQuery.filter(m[3], r, true).r;
+ // optimize if only one selector found (most common case)
+ r = isSimple.test( m[3] ) ?
+ jQuery.filter(m[3], r, true).r :
+ jQuery( r ).not( m[3] );
// We can get a big speed boost by filtering by class here
else if ( m[1] == "." )
// We can get a speed boost by handling nth-child here
} else if ( m[1] == ":" && m[2] == "nth-child" ) {
var merge = {}, tmp = [],
- test = /(\d*)n\+?(\d*)/.exec(
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
- !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
- first = (test[1] || 1) - 0, last = test[2] - 0;
-
+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+ // calculate the numbers (first)n+(last) including if they are negative
+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+ // loop through all the elements left in the jQuery object
for ( var i = 0, rl = r.length; i < rl; i++ ) {
var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
var add = false;
- if ( first == 1 ) {
- if ( last == 0 || node.nodeIndex == last )
+ if ( first == 0 ) {
+ if ( node.nodeIndex == last )
add = true;
- } else if ( (node.nodeIndex + last) % first == 0 )
+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
add = true;
if ( add ^ not )
return r;
}
});
+
/*
* A number of helper functions used for managing events.
* Many of the ideas behind this code orignated from
// Bind an event to an element
// Original by Dean Edwards
- add: function(element, type, handler, data) {
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
// For whatever reason, IE has trouble passing the window object
// around, causing it to be cloned in the process
- if ( jQuery.browser.msie && element.setInterval != undefined )
- element = window;
+ if ( jQuery.browser.msie && elem.setInterval != undefined )
+ elem = window;
// Make sure that the function being executed has a unique ID
if ( !handler.guid )
// if data is passed, bind to handler
if( data != undefined ) {
- // Create temporary function pointer to original handler
+ // Create temporary function pointer to original handler
var fn = handler;
// Create unique handler function, wrapped around original handler
handler.guid = fn.guid;
}
- // Namespaced event handlers
- var parts = type.split(".");
- type = parts[0];
- handler.type = parts[1];
-
// Init the element's event structure
- var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(arguments.callee.elem, arguments);
- var handle = jQuery.data(element, "handle", function(){
- // returned undefined or false
- var val;
-
- // Handle the second event of a trigger and when
- // an event is called after a page has unloaded
- if ( typeof jQuery == "undefined" || jQuery.event.triggered )
return val;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
- val = jQuery.event.handle.apply(element, arguments);
-
- return val;
- });
-
- // Get the current list of functions bound to this event
- var handlers = events[type];
-
- // Init the event handler queue
- if (!handlers) {
- handlers = events[type] = {};
-
- // And bind the global event handler to the element
- if (element.addEventListener)
- element.addEventListener(type, handle, false);
- else
- element.attachEvent("on" + type, handle);
- }
+ // Handle multiple events seperated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
- // Add the function to the element's handler list
- handlers[handler.guid] = handler;
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
- // Keep track of which events have been used, for global triggering
- this.global[type] = true;
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
},
guid: 1,
global: {},
// Detach an event or set of events from an element
- remove: function(element, type, handler) {
- var events = jQuery.data(element, "events"), ret, index;
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
- // Namespaced event handlers
- if ( typeof type == "string" ) {
- var parts = type.split(".");
- type = parts[0];
- }
+ var events = jQuery.data(elem, "events"), ret, index;
if ( events ) {
- // type is actually an event object here
- if ( type && type.type ) {
- handler = type.handler;
- type = type.type;
- }
-
- if ( !type ) {
- for ( type in events )
- this.remove( element, type );
-
- } else if ( events[type] ) {
- // remove the given handler for the given type
- if ( handler )
- delete events[type][handler.guid];
-
- // remove all handlers for the given type
- else
- for ( handler in events[type] )
- // Handle the removal of namespaced events
- if ( !parts[1] || events[type][handler].type == parts[1] )
- delete events[type][handler];
-
- // remove generic event handler if no more handlers exist
- for ( ret in events[type] ) break;
- if ( !ret ) {
- if (element.removeEventListener)
- element.removeEventListener(type, jQuery.data(element, "handle"), false);
- else
- element.detachEvent("on" + type, jQuery.data(element, "handle"));
- ret = null;
- delete events[type];
+ // Unbind all events for the element
+ if ( types == undefined )
+ for ( var type in events )
+ this.remove( elem, type );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
}
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
}
// Remove the expando if it's no longer used
for ( ret in events ) break;
if ( !ret ) {
- jQuery.removeData( element, "events" );
- jQuery.removeData( element, "handle" );
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
}
}
},
- trigger: function(type, data, element, donative, extra) {
+ trigger: function(type, data, elem, donative, extra) {
// Clone the incoming data, if any
data = jQuery.makeArray(data || []);
// Handle a global trigger
- if ( !element ) {
+ if ( !elem ) {
// Only trigger if we've ever bound an event for it
if ( this.global[type] )
jQuery("*").add([window, document]).trigger(type, data);
// Handle triggering a single element
} else {
- var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
// Check to see if we need to provide a fake event, or not
- evt = !data[0] || !data[0].preventDefault;
+ event = !data[0] || !data[0].preventDefault;
// Pass along a fake event
- if ( evt )
- data.unshift( this.fix({ type: type, target: element }) );
+ if ( event )
+ data.unshift( this.fix({ type: type, target: elem }) );
// Enforce the right trigger type
data[0].type = type;
// Trigger the event
- if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
- val = jQuery.data(element, "handle").apply( element, data );
+ if ( jQuery.isFunction( jQuery.data(elem, "handle") ) )
+ val = jQuery.data(elem, "handle").apply( elem, data );
// Handle triggering native .onfoo handlers
- if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
+ if ( !fn && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
val = false;
// Extra functions don't get the custom event object
- if ( evt )
+ if ( event )
data.shift();
// Handle triggering of extra function
- if ( extra && extra.apply( element, data ) === false )
- val = false;
+ if ( extra && jQuery.isFunction( extra ) ) {
+ // call the extra function and tack the current return value on the end for possible inspection
+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );
+ // if anything is returned, give it precedence and have it overwrite the previous value
+ if (ret !== undefined)
+ val = ret;
+ }
// Trigger the native events (except for clicks on links)
- if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
this.triggered = true;
- element[ type ]();
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
}
this.triggered = false;
var parts = event.type.split(".");
event.type = parts[0];
- var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
args.unshift( event );
- for ( var j in c ) {
+ for ( var j in handlers ) {
+ var handler = handlers[j];
// Pass in a reference to the handler function itself
// So that we can later remove it
- args[0].handler = c[j];
- args[0].data = c[j].data;
+ args[0].handler = handler;
+ args[0].data = handler.data;
// Filter the functions by class
- if ( !parts[1] || c[j].type == parts[1] ) {
- var tmp = c[j].apply( this, args );
+ if ( !parts[1] || handler.type == parts[1] ) {
+ var ret = handler.apply( this, args );
if ( val !== false )
- val = tmp;
+ val = ret;
- if ( tmp === false ) {
+ if ( ret === false ) {
event.preventDefault();
event.stopPropagation();
}
};
// Fix target property, if necessary
- if ( !event.target && event.srcElement )
- event.target = event.srcElement;
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
// check if target is a textnode (safari)
- if (jQuery.browser.safari && event.target.nodeType == 3)
+ if ( event.target.nodeType == 3 )
event.target = originalEvent.target.parentNode;
// Add relatedTarget, if necessary
// Calculate pageX/Y if missing and clientX/Y available
if ( event.pageX == null && event.clientX != null ) {
- var e = document.documentElement, b = document.body;
- event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
- event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
}
// Add which for key events
- if ( !event.which && (event.charCode || event.keyCode) )
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
event.which = event.charCode || event.keyCode;
// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
return event;
+ },
+
+ special: {
+ ready: {
+ setup: function() {
+ // Make sure the ready event is setup
+ bindReady();
+ return;
+ },
+
+ teardown: function() { return; }
+ },
+
+ mouseenter: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseenter
+ arguments[0].type = "mouseenter";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ },
+
+ mouseleave: {
+ setup: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ teardown: function() {
+ if ( jQuery.browser.msie ) return false;
+ jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
+ return true;
+ },
+
+ handler: function(event) {
+ // If we actually just moused on to a sub-element, ignore it
+ if ( withinElement(event, this) ) return true;
+ // Execute the right handlers by setting the event type to mouseleave
+ arguments[0].type = "mouseleave";
+ return jQuery.event.handle.apply(this, arguments);
+ }
+ }
}
};
triggerHandler: function( type, data, fn ) {
if ( this[0] )
return jQuery.event.trigger( type, data, this[0], false, fn );
+ return undefined;
},
toggle: function() {
// Save reference to arguments for access in closure
- var a = arguments;
+ var args = arguments;
- return this.click(function(e) {
+ return this.click(function(event) {
// Figure out which function to execute
this.lastToggle = 0 == this.lastToggle ? 1 : 0;
// Make sure that clicks stop
- e.preventDefault();
+ event.preventDefault();
// and execute the function
- return a[this.lastToggle].apply( this, [e] ) || false;
+ return args[this.lastToggle].apply( this, arguments ) || false;
});
},
- hover: function(f,g) {
-
- // A private function for handling mouse 'hovering'
- function handleHover(e) {
- // Check if mouse(over|out) are still within the same parent element
- var p = e.relatedTarget;
-
- // Traverse up the tree
- while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
-
- // If we actually just moused on to a sub-element, ignore it
- if ( p == this ) return false;
-
- // Execute the right function
- return (e.type == "mouseover" ? f : g).apply(this, [e]);
- }
-
- // Bind the function to the two event listeners
- return this.mouseover(handleHover).mouseout(handleHover);
+ hover: function(fnOver, fnOut) {
+ return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
},
- ready: function(f) {
+ ready: function(fn) {
// Attach the listeners
bindReady();
// If the DOM is already ready
if ( jQuery.isReady )
// Execute the function immediately
- f.apply( document, [jQuery] );
+ fn.call( document, jQuery );
// Otherwise, remember the function for later
else
// Add the function to the wait list
- jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
+ jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
return this;
}
});
jQuery.extend({
- /*
- * All the code that makes DOM Ready work nicely.
- */
isReady: false,
readyList: [],
-
// Handle when the DOM is ready
ready: function() {
// Make sure that the DOM is not already loaded
// Reset the list of functions
jQuery.readyList = null;
}
- // Remove event listener to avoid memory leak
- if ( jQuery.browser.mozilla || jQuery.browser.opera )
- document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
-
- // Remove script element used by IE hack
- if( !window.frames.length ) // don't remove if frames are present (#1187)
- jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
}
}
});
-jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
- "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
- "submit,keydown,keypress,keyup,error").split(","), function(i,o){
-
- // Handle event binding
- jQuery.fn[o] = function(f){
- return f ? this.bind(o, f) : this.trigger(o);
- };
-});
-
var readyBound = false;
function bindReady(){
if ( readyBound ) return;
readyBound = true;
- // If Mozilla is used
- if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
+ if ( document.addEventListener && !jQuery.browser.opera)
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
- // If IE is used, use the excellent hack by Matthias Miller
- // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
- else if ( jQuery.browser.msie ) {
-
- // Only works if you document.write() it
- document.write("<scr" + "ipt id=__ie_init defer=true " +
- "src=//:><\/script>");
-
- // Use the defer script hack
- var script = document.getElementById("__ie_init");
-
- // script does not exist if jQuery is loaded dynamically
- if ( script )
- script.onreadystatechange = function() {
- if ( this.readyState != "complete" ) return;
- jQuery.ready();
- };
-
- // Clear from memory
- script = null;
-
- // If Safari is used
- } else if ( jQuery.browser.safari )
- // Continually check to see if the document.readyState is valid
- jQuery.safariTimer = setInterval(function(){
- // loaded and complete are both valid states
- if ( document.readyState == "loaded" ||
- document.readyState == "complete" ) {
-
- // If either one are found, remove the timer
- clearInterval( jQuery.safariTimer );
- jQuery.safariTimer = null;
-
- // and execute any waiting functions
- jQuery.ready();
+ // If IE is used and is not in a frame
+ // Continually check to see if the document is ready
+ if ( jQuery.browser.msie && window == top ) (function(){
+ if (jQuery.isReady) return;
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+
+ if ( jQuery.browser.opera )
+ document.addEventListener( "DOMContentLoaded", function () {
+ if (jQuery.isReady) return;
+ for (var i = 0; i < document.styleSheets.length; i++)
+ if (document.styleSheets[i].disabled) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ }, false);
+
+ if ( jQuery.browser.safari ) {
+ var numStyles;
+ (function(){
+ if (jQuery.isReady) return;
+ if ( document.readyState != "loaded" && document.readyState != "complete" ) {
+ setTimeout( arguments.callee, 0 );
+ return;
}
- }, 10);
+ if ( numStyles === undefined )
+ numStyles = jQuery("style, link[rel=stylesheet]").length;
+ if ( document.styleSheets.length != numStyles ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
// A fallback to window.onload, that will always work
jQuery.event.add( window, "load", jQuery.ready );
}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event, elem) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
+ // Return true if we actually just moused on to a sub-element
+ return parent == elem;
+};
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery(window).bind("unload", function() {
+ jQuery("*").add(document).unbind();
+});
jQuery.fn.extend({
load: function( url, params, callback ) {
if ( jQuery.isFunction( url ) )
jQuery.ajax({
url: url,
type: type,
+ dataType: "html",
data: params,
complete: function(res, status){
// If successful, inject the HTML into all the matched elements
// If not, just inject the full result
res.responseText );
- // Add delay to account for Safari's delay in globalEval
- setTimeout(function(){
- self.each( callback, [res.responseText, status, res] );
- }, 13);
+ self.each( callback, [res.responseText, status, res] );
}
});
return this;
contentType: "application/x-www-form-urlencoded",
processData: true,
async: true,
- data: null
+ data: null,
+ username: null,
+ password: null,
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
},
// Last-Modified header cache for next request
lastModified: {},
ajax: function( s ) {
- var jsonp, jsre = /=(\?|%3F)/g, status, data;
+ var jsonp, jsre = /=\?(&|$)/g, status, data;
// Extend the settings, but re-extend 's' so that it can be
// checked again later (in the test suite, specifically)
- s = jQuery.extend(s, jQuery.extend({}, jQuery.ajaxSettings, s));
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
// convert data if not already a string
if ( s.data && s.processData && typeof s.data != "string" )
// Replace the =? sequence both in the query string and the data
if ( s.data )
- s.data = s.data.replace(jsre, "=" + jsonp);
- s.url = s.url.replace(jsre, "=" + jsonp);
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
// We need to make sure
// that a JSONP style response is executed properly
// Garbage collect
window[ jsonp ] = undefined;
try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
};
}
if ( s.dataType == "script" && s.cache == null )
s.cache = false;
- if ( s.cache === false && s.type.toLowerCase() == "get" )
- s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime();
+ if ( s.cache === false && s.type.toLowerCase() == "get" ) {
+ var ts = (new Date()).getTime();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
// If data is available, append data to url for get requests
if ( s.data && s.type.toLowerCase() == "get" ) {
jQuery.event.trigger( "ajaxStart" );
// If we're requesting a remote document
- // and trying to load JSON or Script
- if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+ // and trying to load JSON or Script with a GET
+ if ( (!s.url.indexOf("http") || !s.url.indexOf("//")) && ( s.dataType == "script" || s.dataType =="json" ) && s.type.toLowerCase() == "get" ) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
// Handle Script loading
- if ( !jsonp && (s.success || s.complete) ) {
+ if ( !jsonp ) {
var done = false;
// Attach handlers for all browsers
head.appendChild(script);
// We handle everything using the script element injection
- return;
+ return undefined;
}
var requestDone = false;
var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
// Open the socket
- xml.open(s.type, s.url, s.async);
+ xml.open(s.type, s.url, s.async, s.username, s.password);
- // Set the correct header, if data is being sent
- if ( s.data )
- xml.setRequestHeader("Content-Type", s.contentType);
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
- // Set the If-Modified-Since header, if ifModified mode.
- if ( s.ifModified )
- xml.setRequestHeader("If-Modified-Since",
- jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- // Set header so the called script knows that it's an XMLHttpRequest
- xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ // Set the Accepts header for the server, depending on the dataType
+ xml.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
// Allow custom headers/mimetypes
if ( s.beforeSend )
s.beforeSend(xml);
if ( s.global )
- jQuery.event.trigger("ajaxSend", [xml, s]);
+ jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var onreadystatechange = function(isTimeout){
// firefox 1.5 doesn't fire statechange for sync requests
if ( !s.async )
onreadystatechange();
-
- // return XMLHttpRequest to allow aborting the request etc.
- return xml;
function success(){
// If a local callback was specified, fire it and pass it the data
if ( s.global && ! --jQuery.active )
jQuery.event.trigger( "ajaxStop" );
}
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
},
handleError: function( s, xml, status, e ) {
// Determines if an XMLHttpRequest was successful or not
httpSuccess: function( r ) {
try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
return !r.status && location.protocol == "file:" ||
- ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 || r.status == 1223 ||
jQuery.browser.safari && r.status == undefined;
} catch(e){}
return false;
}, speed, callback) :
this.filter(":hidden").each(function(){
- this.style.display = this.oldblock ? this.oldblock : "";
- if ( jQuery.css(this,"display") == "none" )
- this.style.display = "block";
+ this.style.display = this.oldblock || "";
+ if ( jQuery.css(this,"display") == "none" ) {
+ var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+ this.style.display = elem.css("display");
+ // handle an edge condition where css is - div { display:none; } or similar
+ if (this.style.display == "none")
+ this.style.display = "block";
+ elem.remove();
+ }
}).end();
},
this.filter(":visible").each(function(){
this.oldblock = this.oldblock || jQuery.css(this,"display");
- if ( this.oldblock == "none" )
- this.oldblock = "block";
this.style.display = "none";
}).end();
},
},
animate: function( prop, speed, easing, callback ) {
- var opt = jQuery.speed(speed, easing, callback);
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+ if ( this.nodeType != 1)
+ return false;
- return this[ opt.queue === false ? "each" : "queue" ](function(){
- opt = jQuery.extend({}, opt);
+ var opt = jQuery.extend({}, optall);
var hidden = jQuery(this).is(":hidden"), self = this;
for ( var p in prop ) {
},
queue: function(type, fn){
- if ( jQuery.isFunction(type) ) {
+ if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
fn = type;
type = "fx";
}
});
},
- stop: function(){
+ stop: function(clearQueue, gotoEnd){
var timers = jQuery.timers;
- return this.each(function(){
- for ( var i = 0; i < timers.length; i++ )
- if ( timers[i].elem == this )
- timers.splice(i--, 1);
- }).dequeue();
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
}
});
var queue = function( elem, type, array ) {
if ( !elem )
- return;
+ return undefined;
+
+ type = type || "fx";
var q = jQuery.data( elem, type + "queue" );
// Queueing
opt.old = opt.complete;
opt.complete = function(){
- jQuery(this).dequeue();
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
if ( jQuery.isFunction( opt.old ) )
opt.old.apply( this );
};
},
timers: [],
+ timerId: null,
fx: function( elem, options, prop ){
this.options = options;
if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
return this.elem[ this.prop ];
- var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
- return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
},
// Start an animation from one number to another
this.update();
var self = this;
- function t(){
- return self.step();
+ function t(gotoEnd){
+ return self.step(gotoEnd);
}
t.elem = this.elem;
jQuery.timers.push(t);
- if ( jQuery.timers.length == 1 ) {
- var timer = setInterval(function(){
+ if ( jQuery.timerId == null ) {
+ jQuery.timerId = setInterval(function(){
var timers = jQuery.timers;
for ( var i = 0; i < timers.length; i++ )
if ( !timers[i]() )
timers.splice(i--, 1);
- if ( !timers.length )
- clearInterval( timer );
+ if ( !timers.length ) {
+ clearInterval( jQuery.timerId );
+ jQuery.timerId = null;
+ }
}, 13);
}
},
},
// Each step of an animation
- step: function(){
+ step: function(gotoEnd){
var t = (new Date()).getTime();
- if ( t > this.options.duration + this.startTime ) {
+ if ( gotoEnd || t > this.options.duration + this.startTime ) {
this.now = this.end;
this.pos = this.state = 1;
this.update();
var left = 0, top = 0, elem = this[0], results;
if ( elem ) with ( jQuery.browser ) {
- var absolute = jQuery.css(elem, "position") == "absolute",
- parent = elem.parentNode,
+ var parent = elem.parentNode,
+ offsetChild = elem,
offsetParent = elem.offsetParent,
doc = elem.ownerDocument,
- safari2 = safari && parseInt(version) < 522;
+ safari2 = safari && parseInt(version) < 522,
+ fixed = jQuery.css(elem, "position") == "fixed";
// Use getBoundingClientRect if available
if ( elem.getBoundingClientRect ) {
- box = elem.getBoundingClientRect();
+ var box = elem.getBoundingClientRect();
// Add the document scroll offsets
- add(
- box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
- box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)
- );
+ add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
// IE adds the HTML element's border, by default it is medium which is 2px
- // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
// IE 7 standards mode, the border is always 2px
- if ( msie ) {
- var border = jQuery("html").css("borderWidth");
- border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border;
- add( -border, -border );
- }
+ // This border/offset is typically represented by the clientLeft and clientTop properties
+ // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
+ // Therefore this method will be off by 2px in IE while in quirksmode
+ add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
// Otherwise loop through the offsetParents and parentNodes
} else {
// Initial element offsets
add( elem.offsetLeft, elem.offsetTop );
-
+
// Get parent offsets
while ( offsetParent ) {
// Add offsetParent offsets
add( offsetParent.offsetLeft, offsetParent.offsetTop );
// Mozilla and Safari > 2 does not include the border on offset parents
- // However Mozilla adds the border for table cells
- if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
+ // However Mozilla adds the border for table or table cells
+ if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
border( offsetParent );
-
- // Safari <= 2 doubles body offsets with an absolutely positioned element or parent
- if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" )
- absolute = true;
+
+ // Add the document scroll offsets if position is fixed on any offsetParent
+ if ( !fixed && jQuery.css(offsetParent, "position") == "fixed" )
+ fixed = true;
+ // Set offsetChild to previous offsetParent unless it is the body element
+ offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
// Get next offsetParent
offsetParent = offsetParent.offsetParent;
}
// Get parent scroll offsets
- while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
- // Work around opera inline/table scrollLeft/Top bug
- if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) )
+ while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table.*$/i.test(jQuery.css(parent, "display")) )
// Subtract parent scroll offsets
add( -parent.scrollLeft, -parent.scrollTop );
parent = parent.parentNode;
}
- // Safari doubles body offsets with an absolutely positioned element or parent
- if ( safari2 && absolute )
- add( -doc.body.offsetLeft, -doc.body.offsetTop );
+ // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
+ // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
+ if ( (safari2 && (fixed || jQuery.css(offsetChild, "position") == "absolute")) ||
+ (mozilla && jQuery.css(offsetChild, "position") != "absolute") )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+
+ // Add the document scroll offsets if position is fixed
+ if ( fixed )
+ add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
}
// Return an object with top and left properties
results = { top: top, left: left };
}
- return results;
-
function border(elem) {
- add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") );
+ add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
}
function add(l, t) {
left += parseInt(l) || 0;
top += parseInt(t) || 0;
}
+
+ return results;
};
})();