Skip to content

Commit ad32c94

Browse files
committed
Manipulation: Make an HTML interception point
Fixes gh-1747
1 parent 597c192 commit ad32c94

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/manipulation.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ function fixInput( src, dest ) {
159159
}
160160

161161
jQuery.extend({
162+
htmlPrefilter: function( html ) {
163+
return html.replace( rxhtmlTag, "<$1></$2>" );
164+
},
165+
162166
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
163167
var i, l, srcElements, destElements,
164168
clone = elem.cloneNode( true ),
@@ -230,7 +234,7 @@ jQuery.extend({
230234
// Deserialize a standard representation
231235
tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
232236
wrap = wrapMap[ tag ] || wrapMap._default;
233-
tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
237+
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
234238

235239
// Descend through wrappers to the right content
236240
j = wrap[ 0 ];
@@ -420,7 +424,7 @@ jQuery.fn.extend({
420424
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
421425
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
422426

423-
value = value.replace( rxhtmlTag, "<$1></$2>" );
427+
value = jQuery.htmlPrefilter( value );
424428

425429
try {
426430
for ( ; i < l; i++ ) {

test/unit/manipulation.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2364,6 +2364,46 @@ test( "jQuery._evalUrl (#12838)", function() {
23642364
jQuery._evalUrl = evalUrl;
23652365
});
23662366

2367+
test( "jQuery.htmlPrefilter (gh-1747)", function( assert ) {
2368+
2369+
assert.expect( 5 );
2370+
2371+
var expectedArgument,
2372+
invocations = 0,
2373+
htmlPrefilter = jQuery.htmlPrefilter,
2374+
fixture = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ),
2375+
poison = "<script>jQuery.htmlPrefilter.assert.ok( false, 'script not executed' );</script>",
2376+
done = assert.async();
2377+
2378+
jQuery.htmlPrefilter = function( html ) {
2379+
invocations++;
2380+
assert.equal( html, expectedArgument, "Expected input" );
2381+
2382+
// Remove <script> and <del> elements
2383+
return htmlPrefilter.apply( this, arguments )
2384+
.replace( /<(script|del)(?=[\s\n>])[\w\W]*?<\/\1[\s\n]*>/ig, "" );
2385+
};
2386+
jQuery.htmlPrefilter.assert = assert;
2387+
2388+
expectedArgument = "A-" + poison + "B-" + poison + poison + "C-";
2389+
fixture.html( expectedArgument );
2390+
2391+
expectedArgument = "D-" + poison + "E-" + "<del/><div>" + poison + poison + "</div>" + "F-";
2392+
fixture.append( expectedArgument );
2393+
2394+
expectedArgument = poison;
2395+
fixture.find( "div" ).replaceWith( expectedArgument );
2396+
2397+
assert.equal( invocations, 3, "htmlPrefilter invoked for all DOM manipulations" );
2398+
assert.equal( fixture.html(), "A-B-C-D-E-F-", "htmlPrefilter modified HTML" );
2399+
2400+
// Allow asynchronous script execution to generate assertions
2401+
setTimeout( function() {
2402+
jQuery.htmlPrefilter = htmlPrefilter;
2403+
done();
2404+
}, 100 );
2405+
});
2406+
23672407
test( "insertAfter, insertBefore, etc do not work when destination is original element. Element is removed (#4087)", function() {
23682408

23692409
expect( 10 );

0 commit comments

Comments
 (0)