Broke the logic for .clean() wrap out into a separate, static, data structure. Also...
authorJohn Resig <jeresig@gmail.com>
Mon, 7 Sep 2009 20:55:36 +0000 (20:55 +0000)
committerJohn Resig <jeresig@gmail.com>
Mon, 7 Sep 2009 20:55:36 +0000 (20:55 +0000)
Makefile
build.xml
src/manipulation.js
test/unit/manipulation.js

index c236120..95e3769 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,12 +10,12 @@ PLUG_DIR = ../plugins
 
 BASE_FILES = ${SRC_DIR}/core.js\
        ${SRC_DIR}/data.js\
+       ${SRC_DIR}/event.js\
+       ${SRC_DIR}/support.js\
        ${SRC_DIR}/selector.js\
        ${SRC_DIR}/traversing.js\
        ${SRC_DIR}/attributes.js\
        ${SRC_DIR}/manipulation.js\
-       ${SRC_DIR}/event.js\
-       ${SRC_DIR}/support.js\
        ${SRC_DIR}/css.js\
        ${SRC_DIR}/ajax.js\
        ${SRC_DIR}/fx.js\
index 095c52e..d0ab83c 100644 (file)
--- a/build.xml
+++ b/build.xml
             <fileset dir="${SRC_DIR}" includes="intro.js" />
             <fileset dir="${SRC_DIR}" includes="core.js" />
             <fileset dir="${SRC_DIR}" includes="data.js" />
+            <fileset dir="${SRC_DIR}" includes="event.js" />
+            <fileset dir="${SRC_DIR}" includes="support.js" />
             <fileset dir="${SRC_DIR}" includes="selector.js" />
             <fileset dir="${SRC_DIR}" includes="traversing.js" />
             <fileset dir="${SRC_DIR}" includes="attributes.js" />
             <fileset dir="${SRC_DIR}" includes="manipulation.js" />
-            <fileset dir="${SRC_DIR}" includes="event.js" />
-            <fileset dir="${SRC_DIR}" includes="support.js" />
             <fileset dir="${SRC_DIR}" includes="css.js" />
             <fileset dir="${SRC_DIR}" includes="ajax.js" />
             <fileset dir="${SRC_DIR}" includes="fx.js" />
index 30ba5ab..95e2f7a 100644 (file)
@@ -2,14 +2,32 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
        rleadingWhitespace = /^\s+/,
        rxhtmlTag = /(<(\w+)[^>]*?)\/>/g,
        rselfClosing = /^(?:abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i,
-       rinsideTable = /^<(thead|tbody|tfoot|colg|cap)/,
+       rtagName = /<(\w+)/,
        rtbody = /<tbody/i,
        fcloseTag = function(all, front, tag){
                return rselfClosing.test(tag) ?
                        all :
                        front + "></" + tag + ">";
+       },
+       wrapMap = {
+               option: [ 1, "<select multiple='multiple'>", "</select>" ],
+               legend: [ 1, "<fieldset>", "</fieldset>" ],
+               thead: [ 1, "<table>", "</table>" ],
+               tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+               td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+               col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+               _default: [ 0, "", "" ]
        };
 
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+       wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
 jQuery.fn.extend({
        text: function( text ) {
                if ( typeof text !== "object" && text !== undefined )
@@ -149,11 +167,29 @@ jQuery.fn.extend({
        },
 
        html: function( value ) {
-               return value === undefined ?
-                       (this[0] ?
+               if ( value === undefined ) {
+                       return this[0] ?
                                this[0].innerHTML.replace(rinlinejQuery, "") :
-                               null) :
+                               null;
+
+               // See if we can take a shortcut and just use innerHTML
+               } else if ( typeof value === "string" && !/<script/i.test( value ) &&
+                       !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               // Remove element nodes and prevent memory leaks
+                               if ( this[i].nodeType === 1 ) {
+                                       cleanData( this[i].getElementsByTagName("*") );
+                               }
+
+                               this[i].innerHTML = value;
+                       }
+
+               } else {
                        this.empty().append( value );
+               }
+
+               return this;
        },
 
        replaceWith: function( value ) {
@@ -269,7 +305,8 @@ jQuery.each({
        remove: function( selector, keepData ) {
                if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) {
                        if ( !keepData && this.nodeType === 1 ) {
-                               cleanData( jQuery("*", this).add(this) );
+                               cleanData( this.getElementsByTagName("*") );
+                               cleanData( [ this ] );
                        }
 
                        if ( this.parentNode ) {
@@ -281,7 +318,7 @@ jQuery.each({
        empty: function() {
                // Remove element nodes and prevent memory leaks
                if ( this.nodeType === 1 ) {
-                       cleanData( jQuery("*", this) );
+                       cleanData( this.getElementsByTagName("*") );
                }
 
                // Remove any remaining nodes
@@ -319,41 +356,15 @@ jQuery.extend({
                                elem = elem.replace(rxhtmlTag, fcloseTag);
 
                                // Trim whitespace, otherwise indexOf won't work as expected
-                               var tags = elem.replace(rleadingWhitespace, "")
-                                       .substring(0, 10).toLowerCase();
-
-                               var wrap =
-                                       // option or optgroup
-                                       !tags.indexOf("<opt") &&
-                                       [ 1, "<select multiple='multiple'>", "</select>" ] ||
-
-                                       !tags.indexOf("<leg") &&
-                                       [ 1, "<fieldset>", "</fieldset>" ] ||
-
-                                       rinsideTable.test(tags) &&
-                                       [ 1, "<table>", "</table>" ] ||
-
-                                       !tags.indexOf("<tr") &&
-                                       [ 2, "<table><tbody>", "</tbody></table>" ] ||
-
-                                       // <thead> matched above
-                                       (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
-                                       [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
-
-                                       !tags.indexOf("<col") &&
-                                       [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
-
-                                       // IE can't serialize <link> and <script> tags normally
-                                       !jQuery.support.htmlSerialize &&
-                                       [ 1, "div<div>", "</div>" ] ||
-
-                                       [ 0, "", "" ];
+                               var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+                                       wrap = wrapMap[ tag ] || wrapMap._default,
+                                       depth = wrap[0];
 
                                // Go to html and back, then peel off extra wrappers
                                div.innerHTML = wrap[1] + elem + wrap[2];
 
                                // Move to the right depth
-                               while ( wrap[0]-- ) {
+                               while ( depth-- ) {
                                        div = div.lastChild;
                                }
 
@@ -362,7 +373,7 @@ jQuery.extend({
 
                                        // String was a <table>, *may* have spurious <tbody>
                                        var hasBody = rtbody.test(elem),
-                                               tbody = !tags.indexOf("<table") && !hasBody ?
+                                               tbody = tag === "table" && !hasBody ?
                                                        div.firstChild && div.firstChild.childNodes :
 
                                                        // String was a bare <thead> or <tfoot>
index 8a61ba6..c942bfd 100644 (file)
@@ -639,9 +639,9 @@ var testHtml = function(valueObj) {
 
        stop();
 
-       jQuery("#main").html(valueObj('<script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script>'));
+       jQuery("#main").html(valueObj('<script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975 (1)" );</script>'));
 
-       jQuery("#main").html(valueObj('foo <form><script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975" );</script></form>'));
+       jQuery("#main").html(valueObj('foo <form><script type="text/javascript">ok( true, "jQuery().html().evalScripts() Evals Scripts Twice in Firefox, see #975 (2)" );</script></form>'));
 
        // it was decided that waiting to execute ALL scripts makes sense since nested ones have to wait anyway so this test case is changed, see #1959
        jQuery("#main").html(valueObj("<script>equals(jQuery.scriptorder++, 0, 'Script is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html (even though appears before)')<\/script><span id='scriptorder'><script>equals(jQuery.scriptorder++, 1, 'Script (nested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script></span><script>equals(jQuery.scriptorder++, 2, 'Script (unnested) is executed in order');equals(jQuery('#scriptorder').length, 1,'Execute after html')<\/script>"));