// HANDLE: $(function)
// Shortcut for document ready
- // Safari reports typeof on DOM NodeLists as a function
- if ( jQuery.isFunction(a) && !a.nodeType && a[0] == undefined )
+ if ( jQuery.isFunction(a) )
return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );
// Handle HTML strings
if ( typeof a == "string" ) {
- var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
-
- a = m ?
- // HANDLE: $(html) -> $(array)
- jQuery.clean( [ m[1] ] ) :
+ // HANDLE: $(html) -> $(array)
+ var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);
+ if ( m )
+ a = jQuery.clean( [ m[1] ] );
- // HANDLE: $(expr)
- jQuery.find( a, c );
+ // HANDLE: $(expr)
+ else
+ return new jQuery( c ).find( a );
}
return this.setArray(
* This function also accepts XML Documents and Window objects
* as valid arguments (even though they are not DOM Elements).
*
- * @example $(document).find("div > p")
- * @before <p>one</p> <div><p>two</p></div> <p>three</p>
- * @result [ <p>two</p> ]
- * @desc Same as $("div > p") because the document
- *
* @example $(document.body).background( "black" );
* @desc Sets the background color of the page to black.
*
* @cat Core
*/
pushStack: function( a ) {
- var ret = jQuery(this);
+ var ret = jQuery(a);
ret.prevObject = this;
- return ret.setArray( a );
+ return ret;
},
/**
* @result <img src="test.jpg" title="test.jpg" />
* @desc Sets title attribute from src attribute.
*
+ * @example $("img").attr("title", function(index) { return this.title + (i + 1); });
+ * @before <img title="pic" /><img title="pic" /><img title="pic" />
+ * @result <img title="pic1" /><img title="pic2" /><img title="pic3" />
+ * @desc Enumerate title attribute.
+ *
* @name attr
* @type jQuery
* @param String key The name of the property to set.
* @param Function value A function returning the value to set.
+ * Scope: Current element, argument: Index of current element
* @cat DOM/Attributes
*/
attr: function( key, value, type ) {
// Look for the case where we're accessing a style value
if ( key.constructor == String )
if ( value == undefined )
- return jQuery[ type || "attr" ]( this[0], key );
+ return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
else {
obj = {};
obj[ key ] = value;
}
// Check to see if we're setting style values
- return this.each(function(){
+ return this.each(function(index){
// Set all the styles
for ( var prop in obj )
jQuery.attr(
type ? this.style : this,
- prop, jQuery.prop(this, obj[prop], type)
+ prop, jQuery.prop(this, obj[prop], type, index, prop)
);
});
},
find: function(t) {
return this.pushStack( jQuery.map( this, function(a){
return jQuery.find(t,a);
- }) );
+ }), t );
},
/**
*/
clone: function(deep) {
return this.pushStack( jQuery.map( this, function(a){
- return a.cloneNode( deep != undefined ? deep : true );
+ var a = a.cloneNode( deep != undefined ? deep : true );
+ a.$events = null; // drop $events expando to avoid firing incorrect events
+ return a;
}) );
},
not: function(t) {
return this.pushStack(
t.constructor == String &&
- jQuery.multiFilter(t,this,true) ||
-
- jQuery.grep(this,function(a){
- if ( t.constructor == Array || t.jquery )
- return jQuery.inArray( t, a ) < 0;
- else
- return a != t;
- }) );
+ jQuery.multiFilter(t, this, true) ||
+
+ jQuery.grep(this, function(a) {
+ return ( t.constructor == Array || t.jquery )
+ ? jQuery.inArray( a, t ) < 0
+ : a != t;
+ })
+ );
},
/**
add: function(t) {
return this.pushStack( jQuery.merge(
this.get(),
- typeof t == "string" ? jQuery(t).get() : t )
+ t.constructor == String ?
+ jQuery(t).get() :
+ t.length != undefined && (!t.nodeName || t.nodeName == "FORM") ?
+ t : [t] )
);
},
return this.each(function(){
var obj = this;
- if ( table && this.nodeName.toUpperCase() == "TABLE" && a[0].nodeName.toUpperCase() == "TR" )
+ if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
jQuery.each( a, function(){
noConflict: function() {
if ( 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
isFunction: function( fn ) {
- return fn && typeof fn == "function";
+ return !!fn && typeof fn != "string" &&
+ typeof fn[0] == "undefined" && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a XML document
+ isXMLDoc: function(elem) {
+ return elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
},
/**
return obj;
},
- prop: function(elem, value, type){
+ prop: function(elem, value, type, index, prop){
// Handle executable functions
if ( jQuery.isFunction( value ) )
- return value.call( elem );
+ value = value.call( elem, [index] );
+
+ // 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
- if ( value.constructor == Number && type == "curCSS" )
- return value + "px";
-
- return value;
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ value + "px" :
+ value;
},
className: {
tb = div.childNodes;
for ( var n = tb.length-1; n >= 0 ; --n )
- if ( tb[n].nodeName.toUpperCase() == "TBODY" && !tb[n].childNodes.length )
+ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
tb[n].parentNode.removeChild(tb[n]);
}
},
attr: function(elem, name, value){
- var fix = {
+ var fix = jQuery.isXMLDoc(elem) ? {} : {
"for": "htmlFor",
"class": "className",
"float": jQuery.browser.msie ? "styleFloat" : "cssFloat",
// Mozilla doesn't play well with opacity 1
if ( name == "opacity" && jQuery.browser.mozilla && value == 1 )
value = 0.9999;
+
// 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]];
- } else if ( value == undefined && jQuery.browser.msie && elem.nodeName && elem.nodeName.toUpperCase() == "FORM" && (name == "action" || name == "method") )
+ } 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 ) elem.setAttribute( name, value );
+ if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
+ return elem.getAttribute( name, 2 );
return elem.getAttribute( name );
+ // elem is actually elem.style ... set the style
} else {
name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
if ( value != undefined ) elem[name] = value;
/**
* Merge two arrays together, removing all duplicates.
*
- * The new array is: All the results from the first array, followed
- * by the unique results from the second array.
+ * The result is the altered first argument with
+ * the unique elements from the second array added.
*
* @example $.merge( [0,1,2], [2,3,4] )
* @result [0,1,2,3,4]
* @desc Merges two arrays, removing the duplicate 2
*
- * @example $.merge( [3,2,1], [4,3,2] )
- * @result [3,2,1,4]
+ * @example var array = [3,2,1];
+ * $.merge( array, [4,3,2] )
+ * @result array == [3,2,1,4]
* @desc Merges two arrays, removing the duplicates 3 and 2
*
* @name $.merge
* @type Array
- * @param Array first The first array to merge.
- * @param Array second The second array to merge.
+ * @param Array first The first array to merge, the unique elements of second added.
+ * @param Array second The second array to merge into the first, unaltered.
* @cat JavaScript
*/
merge: function(first, second) {