var _jQuery = window.jQuery;\r
\r
var jQuery = window.jQuery = function( selector, context ) {\r
- // If the context is a namespace object, return a new object\r
- return this instanceof jQuery ?\r
- this.init( selector, context ) :\r
- new jQuery( selector, context );\r
+ // The jQuery object is actually just the init constructor 'enhanced'\r
+ return new jQuery.prototype.init( selector, context );\r
};\r
\r
// Map over the $ in case of overwrite\r
// (both of which we optimize for)\r
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;\r
\r
+// Is it a simple selector\r
+var isSimple = /^.[^:#\[\.]*$/;\r
+\r
jQuery.fn = jQuery.prototype = {\r
init: function( selector, context ) {\r
// Make sure that a selection was provided\r
selector = selector || document;\r
\r
+ // Handle $(DOMElement)\r
+ if ( selector.nodeType ) {\r
+ this[0] = selector;\r
+ this.length = 1;\r
+ return this;\r
+\r
// Handle HTML strings\r
- if ( typeof selector == "string" ) {\r
+ } else if ( typeof selector == "string" ) {\r
// Are we dealing with HTML string or an ID?\r
var match = quickExpr.exec( selector );\r
\r
},\r
\r
css: function( key, value ) {\r
+ // ignore negative width and height values\r
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )\r
+ value = undefined;\r
return this.attr( key, value, "curCSS" );\r
},\r
\r
text: function( text ) {\r
if ( typeof text != "object" && text != null )\r
- return this.empty().append( document.createTextNode( text ) );\r
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );\r
\r
var ret = "";\r
\r
\r
append: function() {\r
return this.domManip(arguments, true, false, function(elem){\r
- this.appendChild( elem );\r
+ if (this.nodeType == 1)\r
+ this.appendChild( elem );\r
});\r
},\r
\r
prepend: function() {\r
return this.domManip(arguments, true, true, function(elem){\r
- this.insertBefore( elem, this.firstChild );\r
+ if (this.nodeType == 1)\r
+ this.insertBefore( elem, this.firstChild );\r
});\r
},\r
\r
clone: function( events ) {\r
// Do the clone\r
var ret = this.map(function(){\r
- return this.outerHTML ?\r
- jQuery( this.outerHTML )[0] :\r
- this.cloneNode( true );\r
+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {\r
+ // IE copies events bound via attachEvent when\r
+ // using cloneNode. Calling detachEvent on the\r
+ // clone will also remove the events from the orignal\r
+ // In order to get around this, we use innerHTML.\r
+ // Unfortunately, this means some modifications to \r
+ // attributes in IE that are actually only stored \r
+ // as properties will not be copied (such as the\r
+ // the name attribute on an input).\r
+ var clone = this.cloneNode(true),\r
+ container = document.createElement("div"),\r
+ container2 = document.createElement("div");\r
+ container.appendChild(clone);\r
+ container2.innerHTML = container.innerHTML;\r
+ return container2.firstChild;\r
+ } else\r
+ return this.cloneNode(true);\r
});\r
\r
// Need to set the expando to null on the cloned set if it exists\r
// Copy the events from the original to the clone\r
if ( events === true )\r
this.find("*").andSelf().each(function(i){\r
+ if (this.nodeType == 3)\r
+ return;\r
var events = jQuery.data( this, "events" );\r
\r
for ( var type in events )\r
},\r
\r
not: function( selector ) {\r
- return this.pushStack(\r
- selector.constructor == String &&\r
- jQuery.multiFilter( selector, this, true ) ||\r
-\r
- jQuery.grep(this, function(elem) {\r
- return selector.constructor == Array || selector.jquery ?\r
- jQuery.inArray( elem, selector ) < 0 :\r
- elem != selector;\r
- }) );\r
+ if ( selector.constructor == String )\r
+ // test special case where just one selector is passed in\r
+ if ( isSimple.test( selector ) )\r
+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );\r
+ else\r
+ selector = jQuery.multiFilter( selector, this );\r
+\r
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;\r
+ return this.filter(function() {\r
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;\r
+ });\r
},\r
\r
add: function( selector ) {\r
- return this.pushStack( jQuery.merge( \r
+ return !selector ? this : this.pushStack( jQuery.merge( \r
this.get(),\r
selector.constructor == String ? \r
jQuery( selector ).get() :\r
\r
if ( this.length ) {\r
var elem = this[0];\r
- \r
+\r
// We need to handle select boxes special\r
if ( jQuery.nodeName( elem, "select" ) ) {\r
var index = elem.selectedIndex,\r
\r
// Everything else, we just grab the value\r
} else\r
- return this[0].value.replace(/\r/g, "");\r
+ return (this[0].value || "").replace(/\r/g, "");\r
\r
}\r
\r
- } else\r
- return this.each(function(){\r
- if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )\r
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||\r
- jQuery.inArray(this.name, value) >= 0);\r
+ return undefined;\r
+ }\r
\r
- else if ( jQuery.nodeName( this, "select" ) ) {\r
- var values = value.constructor == Array ?\r
- value :\r
- [ value ];\r
+ return this.each(function(){\r
+ if ( this.nodeType != 1 )\r
+ return;\r
\r
- jQuery( "option", this ).each(function(){\r
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||\r
- jQuery.inArray( this.text, values ) >= 0);\r
- });\r
+ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )\r
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||\r
+ jQuery.inArray(this.name, value) >= 0);\r
\r
- if ( !values.length )\r
- this.selectedIndex = -1;\r
+ else if ( jQuery.nodeName( this, "select" ) ) {\r
+ var values = value.constructor == Array ?\r
+ value :\r
+ [ value ];\r
\r
- } else\r
- this.value = value;\r
- });\r
+ jQuery( "option", this ).each(function(){\r
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||\r
+ jQuery.inArray( this.text, values ) >= 0);\r
+ });\r
+\r
+ if ( !values.length )\r
+ this.selectedIndex = -1;\r
+\r
+ } else\r
+ this.value = value;\r
+ });\r
},\r
\r
html: function( value ) {\r
var obj = this;\r
\r
if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )\r
- obj = this.getElementsByTagName("tbody")[0] || this.appendChild( document.createElement("tbody") );\r
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );\r
\r
var scripts = jQuery( [] );\r
\r
jQuery.each(elems, function(){\r
var elem = clone ?\r
- this.cloneNode( true ) :\r
+ jQuery( this ).clone( true )[0] :\r
this;\r
\r
+ // execute all scripts after the elements have been injected\r
if ( jQuery.nodeName( elem, "script" ) ) {\r
-\r
- // If scripts are waiting to be executed, wait on this script as well\r
- if ( scripts.length )\r
- scripts = scripts.add( elem );\r
-\r
- // If nothing is waiting to be executed, run immediately\r
- else\r
- evalScript( 0, elem );\r
-\r
+ scripts = scripts.add( elem );\r
} else {\r
// Remove any inner scripts for later evaluation\r
if ( elem.nodeType == 1 )\r
}\r
};\r
\r
+// Give the init function the jQuery prototype for later instantiation\r
+jQuery.prototype.init.prototype = jQuery.prototype;\r
+\r
function evalScript( i, elem ) {\r
if ( elem.src )\r
jQuery.ajax({\r
if ( target.constructor == Boolean ) {\r
deep = target;\r
target = arguments[1] || {};\r
+ // skip the boolean and the target\r
+ i = 2;\r
}\r
\r
+ // Handle case when target is a string or something (possible in deep copy)\r
+ if ( typeof target != "object" && typeof target != "function" )\r
+ target = {};\r
+\r
// extend jQuery itself if only one argument is passed\r
if ( length == 1 ) {\r
target = this;\r
// Extend the base object\r
for ( var name in options ) {\r
// Prevent never-ending loop\r
- if ( target == options[ name ] )\r
+ if ( target === options[ name ] )\r
continue;\r
\r
// Recurse if we're merging object values\r
- if ( deep && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )\r
- jQuery.extend( target[ name ], options[ name ] );\r
+ if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )\r
+ target[ name ] = jQuery.extend( target[ name ], options[ name ] );\r
\r
// Don't bring in undefined values\r
else if ( options[ name ] != undefined )\r
return jQuery;\r
},\r
\r
- // This may seem like some crazy code, but trust me when I say that this\r
- // is the only cross-browser way to do this. --John\r
+ // See test/unit/core.js for details concerning this function.\r
isFunction: function( fn ) {\r
return !!fn && typeof fn != "string" && !fn.nodeName && \r
fn.constructor != Array && /function/i.test( fn + "" );\r
},\r
\r
// Evalulates a script in a global context\r
- // Evaluates Async. in Safari 2 :-(\r
globalEval: function( data ) {\r
data = jQuery.trim( data );\r
\r
// args is for internal usage only\r
each: function( object, callback, args ) {\r
if ( args ) {\r
- if ( object.length == undefined )\r
+ if ( object.length == undefined ) {\r
for ( var name in object )\r
- callback.apply( object[ name ], args );\r
- else\r
+ if ( callback.apply( object[ name ], args ) === false )\r
+ break;\r
+ } else\r
for ( var i = 0, length = object.length; i < length; i++ )\r
if ( callback.apply( object[ i ], args ) === false )\r
break;\r
\r
// A special, fast, case for the most common use of each\r
} else {\r
- if ( object.length == undefined )\r
+ if ( object.length == undefined ) {\r
for ( var name in object )\r
- callback.call( object[ name ], name, object[ name ] );\r
- else\r
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )\r
+ break;\r
+ } else\r
for ( var i = 0, length = object.length, value = object[0]; \r
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}\r
}\r
// internal only, use addClass("class")\r
add: function( elem, classNames ) {\r
jQuery.each((classNames || "").split(/\s+/), function(i, className){\r
- if ( !jQuery.className.has( elem.className, className ) )\r
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )\r
elem.className += (elem.className ? " " : "") + className;\r
});\r
},\r
\r
// internal only, use removeClass("class")\r
remove: function( elem, classNames ) {\r
- elem.className = classNames != undefined ?\r
- jQuery.grep(elem.className.split(/\s+/), function(className){\r
- return !jQuery.className.has( classNames, className ); \r
- }).join(" ") :\r
- "";\r
+ if (elem.nodeType == 1)\r
+ elem.className = classNames != undefined ?\r
+ jQuery.grep(elem.className.split(/\s+/), function(className){\r
+ return !jQuery.className.has( classNames, className ); \r
+ }).join(" ") :\r
+ "";\r
},\r
\r
// internal only, use is(".class")\r
\r
// A method for quickly swapping in/out CSS properties to get correct calculations\r
swap: function( elem, options, callback ) {\r
+ var old = {};\r
// Remember the old values, and insert the new ones\r
for ( var name in options ) {\r
- elem.style[ "old" + name ] = elem.style[ name ];\r
+ old[ name ] = elem.style[ name ];\r
elem.style[ name ] = options[ name ];\r
}\r
\r
\r
// Revert the old values\r
for ( var name in options )\r
- elem.style[ name ] = elem.style[ "old" + name ];\r
+ elem.style[ name ] = old[ name ];\r
},\r
\r
- css: function( elem, name ) {\r
- if ( name == "height" || name == "width" ) {\r
- var old = {}, height, width;\r
-\r
- // Revert the padding and border widths to get the\r
- // correct height/width values\r
- jQuery.each([ "Top", "Bottom", "Right", "Left" ], function(){\r
- old[ "padding" + this ] = 0;\r
- old[ "border" + this + "Width" ] = 0;\r
- });\r
-\r
- // Swap out the padding/border values temporarily\r
- jQuery.swap( elem, old, function() {\r
-\r
- // If the element is visible, then the calculation is easy\r
- if ( jQuery( elem ).is(":visible") ) {\r
- height = elem.offsetHeight;\r
- width = elem.offsetWidth;\r
-\r
- // Otherwise, we need to flip out more values\r
- } else {\r
- elem = jQuery( elem.cloneNode(true) )\r
- .find(":radio").removeAttr("checked").end()\r
- .css({\r
- visibility: "hidden",\r
- position: "absolute",\r
- display: "block",\r
- right: "0",\r
- left: "0"\r
- }).appendTo( elem.parentNode )[0];\r
-\r
- var position = jQuery.css( elem.parentNode, "position" ) || "static";\r
- if ( position == "static" )\r
- elem.parentNode.style.position = "relative";\r
-\r
- height = elem.clientHeight;\r
- width = elem.clientWidth;\r
-\r
- if ( position == "static" )\r
- elem.parentNode.style.position = "static";\r
-\r
- elem.parentNode.removeChild( elem );\r
- }\r
- });\r
-\r
- return name == "height" ?\r
- height :\r
- width;\r
+ css: function( elem, name, force ) {\r
+ if ( name == "width" || name == "height" ) {\r
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];\r
+ \r
+ function getWH() {\r
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;\r
+ var padding = 0, border = 0;\r
+ jQuery.each( which, function() {\r
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;\r
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;\r
+ });\r
+ val -= Math.round(padding + border);\r
+ }\r
+ \r
+ if ( jQuery(elem).is(":visible") )\r
+ getWH();\r
+ else\r
+ jQuery.swap( elem, props, getWH );\r
+ \r
+ return Math.max(0, val);\r
}\r
-\r
- return jQuery.curCSS( elem, name );\r
+ \r
+ return jQuery.curCSS( elem, name, force );\r
},\r
\r
curCSS: function( elem, name, force ) {\r
"1" :\r
ret;\r
}\r
+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037\r
+ if ( jQuery.browser.opera && name == "display" ) {\r
+ var save = elem.style.display;\r
+ elem.style.display = "block";\r
+ elem.style.display = save;\r
+ }\r
\r
// Make sure we're using the right name for getting the float value\r
if ( name.match( /float/i ) )\r
name = styleFloat;\r
\r
- if ( !force && elem.style[ name ] )\r
+ if ( !force && elem.style && elem.style[ name ] )\r
ret = elem.style[ name ];\r
\r
else if ( document.defaultView && document.defaultView.getComputedStyle ) {\r
clean: function( elems, context ) {\r
var ret = [];\r
context = context || document;\r
+ // !context.createElement fails in IE with an error but returns typeof 'object'\r
+ if (typeof context.createElement == 'undefined') \r
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;\r
\r
jQuery.each(elems, function(i, elem){\r
if ( !elem )\r
if ( typeof elem == "string" ) {\r
// Fix "XHTML"-style tags in all browsers\r
elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){\r
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i) ?\r
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?\r
all :\r
front + "></" + tag + ">";\r
});\r
var wrap =\r
// option or optgroup\r
!tags.indexOf("<opt") &&\r
- [ 1, "<select>", "</select>" ] ||\r
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||\r
\r
!tags.indexOf("<leg") &&\r
[ 1, "<fieldset>", "</fieldset>" ] ||\r
div.childNodes :\r
[];\r
\r
- for ( var i = tbody.length - 1; i >= 0 ; --i )\r
- if ( jQuery.nodeName( tbody[ i ], "tbody" ) && !tbody[ i ].childNodes.length )\r
- tbody[ i ].parentNode.removeChild( tbody[ i ] );\r
+ for ( var j = tbody.length - 1; j >= 0 ; --j )\r
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )\r
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );\r
\r
// IE completely kills leading whitespace when innerHTML is used \r
if ( /^\s/.test( elem ) ) \r
},\r
\r
attr: function( elem, name, value ) {\r
+ // don't set attributes on text and comment nodes\r
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)\r
+ return undefined;\r
+\r
var fix = jQuery.isXMLDoc( elem ) ?\r
{} :\r
jQuery.props;\r
if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )\r
throw "type property can't be changed";\r
\r
- elem.setAttribute( name, value );\r
+ // convert the value to a string (all browsers do this but IE) see #1070\r
+ elem.setAttribute( name, "" + value );\r
}\r
\r
if ( jQuery.browser.msie && /href|src/.test( name ) && !jQuery.isXMLDoc( elem ) ) \r
(parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");\r
}\r
\r
- return elem.filter ? \r
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?\r
(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() :\r
"";\r
}\r
readonly: "readOnly",\r
selected: "selected",\r
maxlength: "maxLength",\r
- selectedIndex: "selectedIndex"\r
+ selectedIndex: "selectedIndex",\r
+ defaultValue: "defaultValue",\r
+ tagName: "tagName",\r
+ nodeName: "nodeName"\r
}\r
});\r
\r
jQuery.each({\r
removeAttr: function( name ) {\r
jQuery.attr( this, name, "" );\r
- this.removeAttribute( name );\r
+ if (this.nodeType == 1) \r
+ this.removeAttribute( name );\r
},\r
\r
addClass: function( classNames ) {\r
\r
// Get document width or height\r
this[0] == document ?\r
- // Either scroll[Width/Height] or offset[Width/Height], whichever is greater (Mozilla reports scrollWidth the same as offsetWidth)\r
- Math.max( document.body[ "scroll" + name ], document.body[ "offset" + name ] ) :\r
- \r
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater\r
+ Math.max( \r
+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]), \r
+ Math.max(document.body["offset" + name], document.documentElement["offset" + name]) \r
+ ) :\r
+\r
// Get or set width or height on the element\r
size == undefined ?\r
// Get width or height on the element\r