Skip to content

Commit

Permalink
Selector:Manipulation: Fix DOM manip within template contents
Browse files Browse the repository at this point in the history
The `<template/>` element `contents` property is a document fragment that may
have a `null` `documentElement`. In Safari 16 this happens in more cases due
to recent spec changes - in particular, even if that document fragment is
explicitly adopted into an outer document. We're testing both of those cases
now.

The crash used to happen in `jQuery.contains` which is an alias for
`Sizzle.contains` in jQuery 3.x.

The Sizzle fix is at jquery/sizzle#490, released in Sizzle `2.3.8`. This
version of Sizzle is included in the parent commit.

A fix similar to the one from gh-5158 has also been applied here to the
`selector-native` version.

Fixes gh-5147
Closes gh-5159
Ref jquery/sizzle#490
Ref gh-5158
  • Loading branch information
mgol committed Nov 16, 2022
1 parent a1b7ae3 commit 5318e31
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/selector-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ jQuery.extend( {
return ret;
},
contains: function( a, b ) {
var adown = a.nodeType === 9 ? a.documentElement : a,
bup = b && b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) );
var bup = b && b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && a.contains( bup ) );
},
isXMLDoc: function( elem ) {
var namespace = elem.namespaceURI,
Expand Down
43 changes: 43 additions & 0 deletions test/unit/manipulation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2837,6 +2837,49 @@ QUnit.test( "Make sure tr is not appended to the wrong tbody (gh-3439)", functio
assert.strictEqual( htmlOut, htmlExpected );
} );

[ true, false ].forEach( function( adoptedCase ) {
QUnit[
typeof HTMLTemplateElement === "function" ?
"test" :
"skip"
]( "Manip within <template /> content moved back & forth doesn't throw - " + (
adoptedCase ? "explicitly adopted" : "not explicitly adopted"
) + " (gh-5147)",
function( assert ) {
assert.expect( 1 );

var fragment, diva, divb,
div = jQuery( "" +
"<div>\n" +
" <div><div class='a'></div></div>\n" +
" <div><div class='b'></div></div>\n" +
"</div>" +
"" ),
template = jQuery( "<template></template>" );

jQuery( "#qunit-fixture" )
.append( div )
.append( template );

fragment = template[ 0 ].content;
diva = div.find( ".a" );
divb = div.find( ".b" );

if ( adoptedCase ) {
document.adoptNode( fragment );
}

fragment.appendChild( div.children()[ 0 ] );
fragment.appendChild( div.children()[ 0 ] );

diva.insertBefore( divb );

assert.strictEqual( diva.siblings( ".b" ).length, 1,
"Insertion worked" );
}
);
} );

QUnit.test( "Make sure tags with single-character names are found (gh-4124)", function( assert ) {
assert.expect( 1 );

Expand Down

0 comments on commit 5318e31

Please sign in to comment.