]> source.dussan.org Git - jquery.git/commitdiff
Selector:Manipulation: Fix DOM manip within template contents
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Tue, 15 Nov 2022 14:43:18 +0000 (15:43 +0100)
committerMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Wed, 16 Nov 2022 22:58:17 +0000 (23:58 +0100)
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

src/selector-native.js
test/unit/manipulation.js

index 90a3745cfd57f800c0b8f4df4a787059ac40dc6b..faba5114835bc04e7a8b22789d64f88d3dfc45c3 100644 (file)
@@ -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,
index 348912e6e1fccc60224ec524a3516c05ce3d6e34..6bae15465bc0bf5114dbf6da5db58e1317af675f 100644 (file)
@@ -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 );