]> source.dussan.org Git - jquery.git/commitdiff
Add parseHTML for explicitly parsing strings into html. Fixes #11617.
authortimmywil <timmywillisn@gmail.com>
Thu, 21 Jun 2012 19:28:57 +0000 (15:28 -0400)
committertimmywil <timmywillisn@gmail.com>
Thu, 21 Jun 2012 19:39:04 +0000 (15:39 -0400)
src/core.js
test/unit/core.js

index 13f686a15d91536f003ef866dc6e0815b9dd79c3..2bd8c4b32366585539db9595a212344edbb14292 100644 (file)
@@ -104,7 +104,6 @@ jQuery.fn = jQuery.prototype = {
 
                // Handle HTML strings
                if ( typeof selector === "string" ) {
-                       // Are we dealing with HTML string or an ID?
                        if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
                                // Assume that strings that start and end with <> are HTML and skip the regex check
                                match = [ null, selector, null ];
@@ -118,19 +117,10 @@ jQuery.fn = jQuery.prototype = {
                                context = context instanceof jQuery ? context[0] : context;
                                doc = ( context && context.nodeType ? context.ownerDocument || context : document );
 
-                               // If a single string is passed in and it's a single tag
-                               // just do a createElement and skip the rest
-                               ret = rsingleTag.exec( selector );
-
-                               if ( ret ) {
-                                       selector = [ doc.createElement( ret[1] ) ];
-                                       if ( jQuery.isPlainObject( context ) ) {
-                                               this.attr.call( selector, context, true );
-                                       }
-
-                               } else {
-                                       ret = jQuery.buildFragment( [ match[1] ], doc );
-                                       selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
+                               // scripts is true for back-compat
+                               selector = jQuery.parseHTML( match[1], doc, true );
+                               if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+                                       this.attr.call( selector, context, true );
                                }
 
                                return jQuery.merge( this, selector );
@@ -459,8 +449,32 @@ jQuery.extend({
                throw new Error( msg );
        },
 
+       // data: string of html
+       // context (optional): If specified, the fragment will be created in this context, defaults to document
+       // scripts (optional): If true, will include scripts passed in the html string
+       parseHTML: function( data, context, scripts ) {
+               var parsed;
+               if ( !data || typeof data !== "string" ) {
+                       return null;
+               }
+               if ( typeof context === "boolean" ) {
+                       scripts = context;
+                       context = 0;
+               }
+               context = context || document;
+
+               // Single tag
+               if ( (parsed = rsingleTag.exec( data )) ) {
+                       return [ context.createElement( parsed[1] ) ];
+               }
+
+               parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
+               return jQuery.merge( [],
+                       (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
+       },
+
        parseJSON: function( data ) {
-               if ( typeof data !== "string" || !data ) {
+               if ( !data || typeof data !== "string") {
                        return null;
                }
 
@@ -486,10 +500,10 @@ jQuery.extend({
 
        // Cross-browser xml parsing
        parseXML: function( data ) {
-               if ( typeof data !== "string" || !data ) {
+               var xml, tmp;
+               if ( !data || typeof data !== "string" ) {
                        return null;
                }
-               var xml, tmp;
                try {
                        if ( window.DOMParser ) { // Standard
                                tmp = new DOMParser();
index 71737a87e6d0a9835afcedeff52e6e8a1c1a11f2..f2f5f41c4e306ff242d7f356130854ad33e21692 100644 (file)
@@ -1120,6 +1120,35 @@ test("jQuery.proxy", function(){
        jQuery.proxy( test4, "meth" )( "boom" );
 });
 
+test("jQuery.parseHTML", function() {
+       expect( 11 );
+
+       equal( jQuery.parseHTML(), null, "Nothing in, null out." );
+       equal( jQuery.parseHTML( null ), null, "Nothing in, null out." );
+       equal( jQuery.parseHTML( "" ), null, "Nothing in, null out." );
+       raises(function() {
+               jQuery.parseHTML( "<div>", document.getElementById("form") );
+       }, "Passing an element as the context raises an exception (context should be a document)");
+
+       var elems = jQuery.parseHTML( jQuery("body").html() );
+       ok( elems.length > 10, "Parse a large html string" );
+       equal( jQuery.type( elems ), "array", "parseHTML returns an array rather than a nodelist" );
+
+       var script = "<script>undefined()</script>";
+       equal( jQuery.parseHTML( script ).length, 0, "Passing a script is not allowed by default" );
+       raises(function() {
+               jQuery(jQuery.parseHTML( script, true )).appendTo("#qunit-fixture");
+       }, "Passing a script is allowed if allowScripts is true");
+
+       var html = script + "<div></div>";
+       equal( jQuery.parseHTML( html )[0].nodeName.toLowerCase(), "div", "Ignore scripts by default" );
+       raises(function() {
+               jQuery(jQuery.parseHTML( html, true )).appendTo("#qunit-fixture");
+       }, "Passing a script is allowed if allowScripts is true");
+
+       equal( jQuery.parseHTML("text")[0].nodeType, 3, "Parsing text returns a text node" );
+});
+
 test("jQuery.parseJSON", function(){
        expect(8);