diff options
-rw-r--r-- | src/manipulation.js | 9 | ||||
-rw-r--r-- | test/unit/core.js | 12 | ||||
-rw-r--r-- | test/unit/manipulation.js | 115 |
3 files changed, 85 insertions, 51 deletions
diff --git a/src/manipulation.js b/src/manipulation.js index 4f2cd1b1c..564620368 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -217,6 +217,10 @@ function fixCloneNodeIssues( src, dest ) { } jQuery.extend({ + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1></$2>" ); + }, + clone: function( elem, dataAndEvents, deepDataAndEvents ) { var destElements, node, clone, i, srcElements, inPage = jQuery.contains( elem.ownerDocument, elem ); @@ -304,8 +308,7 @@ jQuery.extend({ // Deserialize a standard representation tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; - - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2]; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[0]; @@ -549,7 +552,7 @@ jQuery.fn.extend({ ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { - value = value.replace( rxhtmlTag, "<$1></$2>" ); + value = jQuery.htmlPrefilter( value ); try { for (; i < l; i++ ) { diff --git a/test/unit/core.js b/test/unit/core.js index cccb2df98..7d6ebb767 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -19,8 +19,7 @@ test("jQuery()", function() { img = jQuery("<img/>"), div = jQuery("<div/><hr/><code/><b/>"), exec = false, - lng = "", - expected = 22, + expected = 23, attrObj = { "text": "test", "class": "test2", @@ -141,12 +140,9 @@ test("jQuery()", function() { } equal( elem[0].defaultValue, "TEST", "Ensure cached nodes are cloned properly (Bug #6655)" ); - // manually clean up detached elements - elem.remove(); - - for ( i = 0; i < 128; i++ ) { - lng += "12345678"; - } + elem = jQuery( "<input type='hidden'>", {} ); + strictEqual( elem[ 0 ].ownerDocument, document, + "Empty attributes object is not interpreted as a document (trac-8950)" ); }); test("jQuery(selector, context)", function() { diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 12ea6194b..5edbe294b 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -2137,7 +2137,7 @@ test( "jQuery.cleanData", function() { } }); -test( "jQuery.buildFragment - no plain-text caching (Bug #6779)", function() { +test( "domManip plain-text caching (trac-6779)", function() { expect( 1 ); @@ -2156,42 +2156,43 @@ test( "jQuery.buildFragment - no plain-text caching (Bug #6779)", function() { $f.remove(); }); -test( "jQuery.html - execute scripts escaped with html comment or CDATA (#9221)", function() { +test( "domManip executes scripts containing html comments or CDATA (trac-9221)", function() { expect( 3 ); - jQuery([ - "<script type='text/javascript'>", - "<!--", - "ok( true, '<!-- handled' );", - "//-->", - "</script>" - ].join("\n")).appendTo("#qunit-fixture"); - jQuery([ - "<script type='text/javascript'>", - "<![CDATA[", - "ok( true, '<![CDATA[ handled' );", - "//]]>", - "</script>" - ].join("\n")).appendTo("#qunit-fixture"); - jQuery([ - "<script type='text/javascript'>", - "<!--//--><![CDATA[//><!--", - "ok( true, '<!--//--><![CDATA[//><!-- (Drupal case) handled' );", - "//--><!]]>", - "</script>" - ].join("\n")).appendTo("#qunit-fixture"); -}); - -test( "jQuery.buildFragment - plain objects are not a document #8950", function() { - - expect( 1 ); - - try { - jQuery( "<input type='hidden'>", {} ); - ok( true, "Does not allow attribute object to be treated like a doc object" ); - } catch ( e ) {} -}); + jQuery( [ + "<script type='text/javascript'>", + "<!--", + "ok( true, '<!-- handled' );", + "//-->", + "</script>" + ].join( "\n" ) ).appendTo( "#qunit-fixture" ); + + jQuery( [ + "<script type='text/javascript'>", + "<![CDATA[", + "ok( true, '<![CDATA[ handled' );", + "//]]>", + "</script>" + ].join( "\n" ) ).appendTo( "#qunit-fixture" ); + + jQuery( [ + "<script type='text/javascript'>", + "<!--//--><![CDATA[//><!--", + "ok( true, '<!--//--><![CDATA[//><!-- (Drupal case) handled' );", + "//--><!]]>", + "</script>" + ].join( "\n" ) ).appendTo( "#qunit-fixture" ); +}); + +testIframeWithCallback( + "domManip tolerates window-valued document[0] in IE9/10 (trac-12266)", + "manipulation/iframe-denied.html", + function( test ) { + expect( 1 ); + ok( test.status, test.description ); + } +); test( "jQuery.clone - no exceptions for object elements #9587", function() { @@ -2360,12 +2361,6 @@ test( "manipulate mixed jQuery and text (#12384, #12346)", function() { equal( div.find("*").length, 3, "added 2 paragraphs after inner div" ); }); -testIframeWithCallback( "buildFragment works even if document[0] is iframe's window object in IE9/10 (#12266)", "manipulation/iframe-denied.html", function( test ) { - expect( 1 ); - - ok( test.status, test.description ); -}); - test( "script evaluation (#11795)", function() { expect( 13 ); @@ -2449,6 +2444,46 @@ test( "jQuery._evalUrl (#12838)", function() { jQuery._evalUrl = evalUrl; }); +test( "jQuery.htmlPrefilter (gh-1747)", function( assert ) { + + assert.expect( 5 ); + + var expectedArgument, + invocations = 0, + htmlPrefilter = jQuery.htmlPrefilter, + fixture = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ), + poison = "<script>jQuery.htmlPrefilter.assert.ok( false, 'script not executed' );</script>", + done = assert.async(); + + jQuery.htmlPrefilter = function( html ) { + invocations++; + assert.equal( html, expectedArgument, "Expected input" ); + + // Remove <script> and <del> elements + return htmlPrefilter.apply( this, arguments ) + .replace( /<(script|del)(?=[\s>])[\w\W]*?<\/\1\s*>/ig, "" ); + }; + jQuery.htmlPrefilter.assert = assert; + + expectedArgument = "A-" + poison + "B-" + poison + poison + "C-"; + fixture.html( expectedArgument ); + + expectedArgument = "D-" + poison + "E-" + "<del/><div>" + poison + poison + "</div>" + "F-"; + fixture.append( expectedArgument ); + + expectedArgument = poison; + fixture.find( "div" ).replaceWith( expectedArgument ); + + assert.equal( invocations, 3, "htmlPrefilter invoked for all DOM manipulations" ); + assert.equal( fixture.html(), "A-B-C-D-E-F-", "htmlPrefilter modified HTML" ); + + // Allow asynchronous script execution to generate assertions + setTimeout( function() { + jQuery.htmlPrefilter = htmlPrefilter; + done(); + }, 100 ); +}); + test( "insertAfter, insertBefore, etc do not work when destination is original element. Element is removed (#4087)", function() { expect( 10 ); |