Fixed wrapping of elements that hold text nodes. Thanks to David Flanagan for the...
[jquery.git] / src / manipulation.js
index c2c0ff2..b5ace4d 100644 (file)
@@ -1,8 +1,3 @@
-// exclude the following css properties to add px
-var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
-       // cache defaultView
-       defaultView = document.defaultView || {};
-
 jQuery.fn.extend({
        text: function( text ) {
                if ( typeof text !== "object" && text != null )
@@ -23,6 +18,10 @@ jQuery.fn.extend({
        },
 
        wrapAll: function( html ) {
+               if(jQuery.isFunction(html)) {
+                       return this.each(function() { jQuery(this).wrapAll(html.call(this)); });
+               }
+               
                if ( this[0] ) {
                        // The elements to wrap the target around
                        var wrap = jQuery( html, this[0].ownerDocument ).clone();
@@ -33,7 +32,7 @@ jQuery.fn.extend({
                        wrap.map(function(){
                                var elem = this;
 
-                               while ( elem.firstChild )
+                               while ( elem.firstChild && elem.firstChild.nodeType === 1 )
                                        elem = elem.firstChild;
 
                                return elem;
@@ -142,24 +141,63 @@ jQuery.fn.extend({
        },
 
        domManip: function( args, table, callback ) {
+               var fragment, scripts, cacheable, cached, cacheresults, first;
+               var value = args[0];
+
+               if ( jQuery.isFunction(value) ) {
+                       return this.each(function() {
+                               args[0] = value.call(this);
+                               return jQuery(this).domManip( args, table, callback );
+                       });
+               };
+
                if ( this[0] ) {
-                       var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
-                               scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
-                               first = fragment.firstChild;
-
-                       if ( first )
-                               for ( var i = 0, l = this.length; i < l; i++ )
-                                       callback.call( root(this[i], first), this.length > 1 || i > 0 ?
-                                                       fragment.cloneNode(true) : fragment );
-               
-                       if ( scripts )
+                       if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 ) {
+                               cacheable = true;
+                               cacheresults = jQuery.fragments[ args[0] ];
+                               if ( cacheresults ) {
+                                       if ( cacheresults !== 1 ) {
+                                               fragment = cacheresults;
+                                       }
+                                       cached = true;
+                               }
+                       }
+                       
+                       if ( !fragment ) {
+                               fragment = (this[0].ownerDocument || this[0]).createDocumentFragment();
+                               scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment );
+                       }
+
+                       first = fragment.firstChild;
+
+                       if ( first ) {
+                               table = table && jQuery.nodeName( first, "tr" );
+
+                               for ( var i = 0, l = this.length; i < l; i++ ) {
+                                       callback.call(
+                                               table ?
+                                                       root(this[i], first) :
+                                                       this[i],
+                                               cacheable || this.length > 1 || i > 0 ?
+                                                       fragment.cloneNode(true) :
+                                                       fragment
+                                       );
+                               }
+                       }
+
+                       if ( scripts ) {
                                jQuery.each( scripts, evalScript );
+                       }
+
+                       if ( cacheable ) {
+                               jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+                       }
                }
 
                return this;
-               
+
                function root( elem, cur ) {
-                       return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
+                       return jQuery.nodeName(elem, "table") ?
                                (elem.getElementsByTagName("tbody")[0] ||
                                elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
                                elem;
@@ -167,6 +205,8 @@ jQuery.fn.extend({
        }
 });
 
+jQuery.fragments = {};
+
 jQuery.each({
        appendTo: "append",
        prependTo: "prepend",
@@ -191,8 +231,7 @@ jQuery.each({
        remove: function( selector ) {
                if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) {
                        if ( this.nodeType === 1 ) {
-                               cleanData( this.getElementsByTagName("*") );
-                               cleanData( [this] );
+                               cleanData( jQuery("*", this).add(this) );
                        }
 
                        if ( this.parentNode ) {
@@ -204,7 +243,7 @@ jQuery.each({
        empty: function() {
                // Remove element nodes and prevent memory leaks
                if ( this.nodeType === 1 ) {
-                       cleanData( this.getElementsByTagName("*") );
+                       cleanData( jQuery("*", this) );
                }
 
                // Remove any remaining nodes
@@ -311,7 +350,7 @@ jQuery.extend({
                                // IE completely kills leading whitespace when innerHTML is used
                                if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
                                        div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
-                               
+
                                elem = jQuery.makeArray( div.childNodes );
                        }
 
@@ -332,7 +371,7 @@ jQuery.extend({
                                        fragment.appendChild( ret[i] );
                                }
                        }
-                       
+
                        return scripts;
                }