Fixed boxModel support - is now computed with feature detection, rather than sniffing.
[jquery.git] / src / core.js
index b5de145..78f2bcd 100644 (file)
@@ -1,33 +1,23 @@
-/*
- * jQuery @VERSION - New Wave Javascript
- *
- * Copyright (c) 2008 John Resig (jquery.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date$
- * $Rev$
- */
-
-// Map over jQuery in case of overwrite
-var _jQuery = window.jQuery,
-// Map over the $ in case of overwrite
-       _$ = window.$;
-
-var jQuery = window.jQuery = window.$ = function( selector, context ) {
-       // The jQuery object is actually just the init constructor 'enhanced'
-       return new jQuery.fn.init( selector, context );
-};
-
-// 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
-       isSimple = /^.[^:#\[\.]*$/,
+var 
+       // Will speed up references to window, and allows munging its name.
+       window = this,
+       // Will speed up references to undefined, and allows munging its name.
+       undefined,
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+       // Map over the $ in case of overwrite
+       _$ = window.$,
+
+       jQuery = window.jQuery = window.$ = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               return new jQuery.fn.init( selector, context );
+       },
 
-// Will speed up references to undefined, and allows munging its name.
-       undefined;
+       // A simple way to check for HTML strings or ID strings
+       // (both of which we optimize for)
+       quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+       // Is it a simple selector
+       isSimple = /^.[^:#\[\.,]*$/;
 
 jQuery.fn = jQuery.prototype = {
        init: function( selector, context ) {
@@ -83,6 +73,12 @@ jQuery.fn = jQuery.prototype = {
                } else if ( jQuery.isFunction( selector ) )
                        return jQuery( document ).ready( selector );
 
+               // Make sure that old selector state is passed along
+               if ( selector.selector && selector.context ) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
                return this.setArray(jQuery.makeArray(selector));
        },
 
@@ -270,14 +266,23 @@ jQuery.fn = jQuery.prototype = {
                return this.prevObject || jQuery( [] );
        },
 
+       push: [].push,
+
        find: function( selector ) {
-               var elems = jQuery.map(this, function(elem){
-                       return jQuery.find( selector, elem );
-               });
+               if ( this.length === 1 && !/,/.test(selector) ) {
+                       var ret = this.pushStack( [], "find", selector );
+                       ret.length = 0;
+                       jQuery.find( selector, this[0], ret );
+                       return ret;
+               } else {
+                       var elems = jQuery.map(this, function(elem){
+                               return jQuery.find( selector, elem );
+                       });
 
-               return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
-                       jQuery.unique( elems ) :
-                       elems, "find", selector );
+                       return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
+                               jQuery.unique( elems ) :
+                               elems, "find", selector );
+               }
        },
 
        clone: function( events ) {
@@ -337,10 +342,12 @@ jQuery.fn = jQuery.prototype = {
        },
 
        closest: function( selector ) {
+               var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
+
                return this.map(function(){
                        var cur = this;
                        while ( cur && cur.ownerDocument ) {
-                               if ( jQuery(cur).is(selector) )
+                               if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
                                        return cur;
                                cur = cur.parentNode;
                        }
@@ -485,11 +492,11 @@ jQuery.fn = jQuery.prototype = {
 
        domManip: function( args, table, callback ) {
                if ( this[0] ) {
-                       var fragment = this[0].ownerDocument.createDocumentFragment(),
-                               scripts = jQuery.clean( args, this[0].ownerDocument, fragment ),
+                       var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
+                               scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
                                first = fragment.firstChild,
                                extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
-                       
+
                        if ( first )
                                for ( var i = 0, l = this.length; i < l; i++ )
                                        callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
@@ -819,6 +826,14 @@ jQuery.extend({
                if ( typeof context.createElement === "undefined" )
                        context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
 
+               // If a single string is passed in and it's a single tag
+               // just do a createElement and skip the rest
+               if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
+                       var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
+                       if ( match )
+                               return [ context.createElement( match[1] ) ];
+               }
+
                var ret = [], scripts = [], div = context.createElement("div");
 
                jQuery.each(elems, function(i, elem){
@@ -896,15 +911,6 @@ jQuery.extend({
                                if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
                                        div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
                                
-                               if ( fragment ) {
-                                       var found = div.getElementsByTagName("script");
-                       
-                                       while ( found.length ) {
-                                               scripts.push( found[0] );
-                                               found[0].parentNode.removeChild( found[0] );
-                                       }
-                               }
-
                                elem = jQuery.makeArray( div.childNodes );
                        }
 
@@ -915,19 +921,14 @@ jQuery.extend({
 
                });
 
-               // Clean up
-               div.innerHTML = "";
-               
                if ( fragment ) {
                        for ( var i = 0; ret[i]; i++ ) {
-                               var node = ret[i];
-                               if ( jQuery.nodeName( node, "script" ) ) {
-                                       if( node.parentNode )
-                                               node.parentNode.removeChild( node );
+                               if ( jQuery.nodeName( ret[i], "script" ) ) {
+                                       scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
                                } else {
-                                       if ( node.nodeType === 1 )
-                                               ret = jQuery.merge( ret, node.getElementsByTagName("script"));
-                                       fragment.appendChild( node );
+                                       if ( ret[i].nodeType === 1 )
+                                               ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+                                       fragment.appendChild( ret[i] );
                                }
                        }
                        
@@ -975,6 +976,17 @@ jQuery.extend({
                                if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
                                        return elem.getAttributeNode( name ).nodeValue;
 
+                               // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+                               // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               if ( name == "tabIndex" ) {
+                                       var attributeNode = elem.getAttributeNode( "tabIndex" );
+                                       return attributeNode && attributeNode.specified
+                                               ? attributeNode.value
+                                               : elem.nodeName.match(/^(a|area|button|input|object|select|textarea)$/i)
+                                                       ? 0
+                                                       : undefined;
+                               }
+
                                return elem[ name ];
                        }
 
@@ -1134,9 +1146,6 @@ jQuery.browser = {
        mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
 };
 
-// Check to see if the W3C box model is being used
-jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
-
 jQuery.each({
        parent: function(elem){return elem.parentNode;},
        parents: function(elem){return jQuery.dir(elem,"parentNode");},