X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fcore.js;h=39ffdb58084fe1717bed933326ac83d4619b0832;hb=f97f77c034dc62001a687c728bdfdc71a23bf6b8;hp=d27dcb9fd19506ff07cedb2913aeba337b099bbd;hpb=32b3ac4f063571257b36477cc5dcb659cac2c357;p=jquery.git diff --git a/src/core.js b/src/core.js index d27dcb9..39ffdb5 100644 --- a/src/core.js +++ b/src/core.js @@ -14,10 +14,8 @@ if ( window.jQuery ) var _jQuery = window.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 ); + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.prototype.init( selector, context ); }; // Map over the $ in case of overwrite @@ -36,8 +34,14 @@ jQuery.fn = jQuery.prototype = { // 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" ) { + } else if ( typeof selector == "string" ) { // Are we dealing with HTML string or an ID? var match = quickExpr.exec( selector ); @@ -188,12 +192,15 @@ jQuery.fn = jQuery.prototype = { }, 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( text ) { if ( typeof text != "object" && text != null ) - return this.empty().append( document.createTextNode( text ) ); + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); var ret = ""; @@ -242,13 +249,15 @@ jQuery.fn = jQuery.prototype = { append: function() { return this.domManip(arguments, true, false, function(elem){ - this.appendChild( elem ); + if (this.nodeType == 1) + this.appendChild( elem ); }); }, prepend: function() { return this.domManip(arguments, true, true, function(elem){ - this.insertBefore( elem, this.firstChild ); + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); }); }, @@ -281,9 +290,23 @@ jQuery.fn = jQuery.prototype = { 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 ) { + // 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 @@ -331,7 +354,7 @@ jQuery.fn = jQuery.prototype = { }, add: function( selector ) { - return this.pushStack( jQuery.merge( + return !selector ? this : this.pushStack( jQuery.merge( this.get(), selector.constructor == String ? jQuery( selector ).get() : @@ -354,7 +377,7 @@ jQuery.fn = jQuery.prototype = { if ( this.length ) { var elem = this[0]; - + // We need to handle select boxes special if ( jQuery.nodeName( elem, "select" ) ) { var index = elem.selectedIndex, @@ -387,12 +410,15 @@ jQuery.fn = jQuery.prototype = { // 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 ( 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); @@ -459,7 +485,7 @@ jQuery.fn = jQuery.prototype = { var obj = this; if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) - obj = this.getElementsByTagName("tbody")[0] || this.appendChild( document.createElement("tbody") ); + obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") ); var scripts = jQuery( [] ); @@ -493,6 +519,9 @@ jQuery.fn = jQuery.prototype = { } }; +// Give the init function the jQuery prototype for later instantiation +jQuery.prototype.init.prototype = jQuery.prototype; + function evalScript( i, elem ) { if ( elem.src ) jQuery.ajax({ @@ -521,7 +550,7 @@ jQuery.extend = jQuery.fn.extend = function() { } // Handle case when target is a string or something (possible in deep copy) - if ( typeof target != "object" ) + if ( typeof target != "object" && typeof target != "function" ) target = {}; // extend jQuery itself if only one argument is passed @@ -540,7 +569,7 @@ jQuery.extend = jQuery.fn.extend = function() { continue; // Recurse if we're merging object values - if ( deep && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType ) + 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 @@ -582,7 +611,6 @@ jQuery.extend({ }, // Evalulates a script in a global context - // Evaluates Async. in Safari 2 :-( globalEval: function( data ) { data = jQuery.trim( data ); @@ -714,18 +742,19 @@ jQuery.extend({ // internal only, use addClass("class") add: function( elem, classNames ) { jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( !jQuery.className.has( elem.className, className ) ) + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) elem.className += (elem.className ? " " : "") + className; }); }, // internal only, use removeClass("class") remove: function( elem, classNames ) { - elem.className = classNames != undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; + 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") @@ -749,7 +778,7 @@ jQuery.extend({ elem.style[ name ] = elem.style[ "old" + name ]; }, - css: function( elem, name ) { + css: function( elem, name, force ) { if ( name == "height" || name == "width" ) { var old = {}, height, width; @@ -799,7 +828,7 @@ jQuery.extend({ width; } - return jQuery.curCSS( elem, name ); + return jQuery.curCSS( elem, name, force ); }, curCSS: function( elem, name, force ) { @@ -909,6 +938,9 @@ jQuery.extend({ 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(elems, function(i, elem){ if ( !elem ) @@ -932,7 +964,7 @@ jQuery.extend({ var wrap = // option or optgroup !tags.indexOf("", "" ] || + [ 1, "" ] || !tags.indexOf("", "" ] || @@ -1003,6 +1035,10 @@ jQuery.extend({ }, 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; @@ -1033,7 +1069,8 @@ jQuery.extend({ 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 ) ) @@ -1055,7 +1092,7 @@ jQuery.extend({ (parseFloat( value ).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")"); } - return elem.filter ? + return elem.filter && elem.filter.indexOf("opacity=") >= 0 ? (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : ""; } @@ -1206,7 +1243,9 @@ jQuery.extend({ selected: "selected", maxlength: "maxLength", selectedIndex: "selectedIndex", - defaultValue: "defaultValue" + defaultValue: "defaultValue", + tagName: "tagName", + nodeName: "nodeName" } }); @@ -1253,7 +1292,8 @@ jQuery.each({ jQuery.each({ removeAttr: function( name ) { jQuery.attr( this, name, "" ); - this.removeAttribute( name ); + if (this.nodeType == 1) + this.removeAttribute( name ); }, addClass: function( classNames ) { @@ -1313,7 +1353,7 @@ jQuery.each([ "Height", "Width" ], function(i, name){ this[0] == document ? // Either scroll[Width/Height] or offset[Width/Height], whichever is greater (Mozilla reports scrollWidth the same as offsetWidth) Math.max( document.body[ "scroll" + name ], document.body[ "offset" + name ] ) : - + // Get or set width or height on the element size == undefined ? // Get width or height on the element