Make sure that injection of object elements continues to work in IE 6. Really hard...
[jquery.git] / src / manipulation.js
index ed049de..9ef41e0 100644 (file)
@@ -226,7 +226,7 @@ jQuery.fn.extend({
                                null;
 
                // See if we can take a shortcut and just use innerHTML
-               } else if ( typeof value === "string" && !/<script/i.test( value ) &&
+               } else if ( typeof value === "string" && !/<script|<object/i.test( value ) &&
                        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
                        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
 
@@ -296,7 +296,7 @@ jQuery.fn.extend({
        },
 
        domManip: function( args, table, callback ) {
-               var results, first, value = args[0], scripts = [];
+               var results, first, value = args[0], scripts = [], fragment;
 
                // We can't cloneNode fragments that contain checked, in WebKit
                if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
@@ -320,8 +320,14 @@ jQuery.fn.extend({
                        } else {
                                results = buildFragment( args, this, scripts );
                        }
-
-                       first = results.fragment.firstChild;
+                       
+                       fragment = results.fragment;
+                       
+                       if ( fragment.childNodes.length === 1 ) {
+                               first = fragment = fragment.firstChild;
+                       } else {
+                               first = fragment.firstChild;
+                       }
 
                        if ( first ) {
                                table = table && jQuery.nodeName( first, "tr" );
@@ -331,14 +337,14 @@ jQuery.fn.extend({
                                                table ?
                                                        root(this[i], first) :
                                                        this[i],
-                                               results.cacheable || this.length > 1 || i > 0 ?
-                                                       results.fragment.cloneNode(true) :
-                                                       results.fragment
+                                               i > 0 || results.cacheable || this.length > 1  ?
+                                                       fragment.cloneNode(true) :
+                                                       fragment
                                        );
                                }
                        }
 
-                       if ( scripts ) {
+                       if ( scripts.length ) {
                                jQuery.each( scripts, evalScript );
                        }
                }
@@ -378,10 +384,17 @@ function cloneCopyEvent(orig, ret) {
 }
 
 function buildFragment( args, nodes, scripts ) {
-       var fragment, cacheable, cacheresults, doc;
+       var fragment, cacheable, cacheresults,
+               doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+       // Only cache "small" (1/2 KB) strings that are associated with the main document
+       // Cloning options loses the selected state, so don't cache them
+       // IE 6 doesn't like it when you put <object> elements in a fragment
+       // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+               args[0].indexOf("<option") < 0 && args[0].indexOf("<object") < 0 &&
+               (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
 
-       // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
-       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
                cacheable = true;
                cacheresults = jQuery.fragments[ args[0] ];
                if ( cacheresults ) {
@@ -392,7 +405,6 @@ function buildFragment( args, nodes, scripts ) {
        }
 
        if ( !fragment ) {
-               doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
                fragment = doc.createDocumentFragment();
                jQuery.clean( args, doc, fragment, scripts );
        }
@@ -415,13 +427,20 @@ jQuery.each({
 }, function( name, original ) {
        jQuery.fn[ name ] = function( selector ) {
                var ret = [], insert = jQuery( selector );
-
-               for ( var i = 0, l = insert.length; i < l; i++ ) {
-                       var elems = (i > 0 ? this.clone(true) : this).get();
-                       jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
-                       ret = ret.concat( elems );
+               
+               if ( this.length === 1 && this[0].parentNode && this[0].parentNode.nodeType === 11 && insert.length === 1 ) {
+                       insert[ original ]( this[0] );
+                       return this;
+                       
+               } else {
+                       for ( var i = 0, l = insert.length; i < l; i++ ) {
+                               var elems = (i > 0 ? this.clone(true) : this).get();
+                               jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+                               ret = ret.concat( elems );
+                       }
+               
+                       return this.pushStack( ret, name, insert.selector );
                }
-               return this.pushStack( ret, name, insert.selector );
        };
 });
 
@@ -436,13 +455,13 @@ jQuery.extend({
 
                var ret = [];
 
-               jQuery.each(elems, function( i, elem ) {
+               for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
                        if ( typeof elem === "number" ) {
                                elem += "";
                        }
 
                        if ( !elem ) {
-                               return;
+                               continue;
                        }
 
                        // Convert html string into DOM nodes
@@ -493,7 +512,7 @@ jQuery.extend({
                                        div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
                                }
 
-                               elem = jQuery.makeArray( div.childNodes );
+                               elem = div.childNodes;
                        }
 
                        if ( elem.nodeType ) {
@@ -501,13 +520,13 @@ jQuery.extend({
                        } else {
                                ret = jQuery.merge( ret, elem );
                        }
-
-               });
+               }
 
                if ( fragment ) {
                        for ( var i = 0; ret[i]; i++ ) {
                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+                               
                                } else {
                                        if ( ret[i].nodeType === 1 ) {
                                                ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );