From: timmywil Date: Thu, 21 Jun 2012 19:28:57 +0000 (-0400) Subject: Add parseHTML for explicitly parsing strings into html. Fixes #11617. X-Git-Tag: 1.8b1~4 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e2497c682f26b7916d76cb2896c6fe621b376d82;p=jquery.git Add parseHTML for explicitly parsing strings into html. Fixes #11617. --- diff --git a/src/core.js b/src/core.js index 13f686a15..2bd8c4b32 100644 --- a/src/core.js +++ b/src/core.js @@ -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(); diff --git a/test/unit/core.js b/test/unit/core.js index 71737a87e..f2f5f41c4 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -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( "
", 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 = ""; + 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 + "
"; + 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);