From 2d9d6d5b476b9cd1c546592817ef8e96b32e5792 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Mon, 29 Jul 2019 22:06:18 +0200 Subject: [PATCH] Selector: Make selector-native's isXMLDoc recognize HTML-embedded SVG This commit also backports some jQuery.isXMLDoc tests from master so that this behavior doesn't regress. (partially cherry-picked from 79b74e043a4ee737d44a95094ff1184e40bd5b16) Closes gh-4438 Ref jquery/sizzle#378 Ref jquery/sizzle#436 --- src/selector-native.js | 14 +++++++---- test/unit/core.js | 54 +++++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/selector-native.js b/src/selector-native.js index da837a004..05cd8eaeb 100644 --- a/src/selector-native.js +++ b/src/selector-native.js @@ -34,6 +34,7 @@ define( [ */ var hasDuplicate, sortInput, + rhtmlSuffix = /HTML$/i, sortStable = jQuery.expando.split( "" ).sort( sortOrder ).join( "" ) === jQuery.expando, matches = documentElement.matches || documentElement.webkitMatchesSelector || @@ -200,11 +201,14 @@ jQuery.extend( { return a === bup || !!( bup && bup.nodeType === 1 && adown.contains( bup ) ); }, isXMLDoc: function( elem ) { - - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && ( elem.ownerDocument || elem ).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; + var namespace = elem.namespaceURI, + documentElement = ( elem.ownerDocument || elem ).documentElement; + + // Assume HTML when documentElement doesn't yet exist, such as inside + // document fragments. + return !rhtmlSuffix.test( namespace || + documentElement && documentElement.nodeName || + "HTML" ); }, expr: { attrHandle: {}, diff --git a/test/unit/core.js b/test/unit/core.js index 28f40ab56..2f40462f3 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -380,6 +380,52 @@ QUnit.test( "isXMLDoc - HTML", function( assert ) { document.body.removeChild( iframe ); } ); +QUnit.test( "isXMLDoc - embedded SVG", function( assert ) { + assert.expect( 6 ); + + var htmlTree = jQuery( "
" + + "" + + "" + + "" + + "
" + )[ 0 ]; + + assert.strictEqual( jQuery.isXMLDoc( htmlTree ), false, "disconnected div element" ); + assert.strictEqual( jQuery.isXMLDoc( htmlTree.firstChild ), true, + "disconnected HTML-embedded SVG root element" ); + + assert.strictEqual( jQuery.isXMLDoc( htmlTree.firstChild.firstChild ), true, + "disconnected HTML-embedded SVG child element" ); + + document.getElementById( "qunit-fixture" ).appendChild( htmlTree ); + assert.strictEqual( jQuery.isXMLDoc( htmlTree ), false, "connected div element" ); + assert.strictEqual( jQuery.isXMLDoc( htmlTree.firstChild ), true, + "connected HTML-embedded SVG root element" ); + + assert.strictEqual( jQuery.isXMLDoc( htmlTree.firstChild.firstChild ), true, + "disconnected HTML-embedded SVG child element" ); +} ); + +QUnit.test( "isXMLDoc - XML", function( assert ) { + assert.expect( 8 ); + + var xml = createDashboardXML(); + var svg = jQuery.parseXML( + "" + + "" + ); + assert.ok( jQuery.isXMLDoc( xml ), "XML document" ); + assert.ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); + assert.ok( jQuery.isXMLDoc( xml.documentElement.firstChild ), "XML child element" ); + assert.ok( jQuery.isXMLDoc( jQuery( "tab", xml )[ 0 ] ), "XML tab Element" ); + + assert.ok( jQuery.isXMLDoc( svg ), "SVG document" ); + assert.ok( jQuery.isXMLDoc( svg.documentElement ), "SVG documentElement" ); + assert.ok( jQuery.isXMLDoc( svg.documentElement.firstChild ), "SVG child element" ); + assert.ok( jQuery.isXMLDoc( jQuery( "desc", svg )[ 0 ] ), "XML desc Element" ); +} ); + QUnit.test( "XSS via location.hash", function( assert ) { var done = assert.async(); assert.expect( 1 ); @@ -399,14 +445,6 @@ QUnit.test( "XSS via location.hash", function( assert ) { } } ); -QUnit.test( "isXMLDoc - XML", function( assert ) { - assert.expect( 3 ); - var xml = createDashboardXML(); - assert.ok( jQuery.isXMLDoc( xml ), "XML document" ); - assert.ok( jQuery.isXMLDoc( xml.documentElement ), "XML documentElement" ); - assert.ok( jQuery.isXMLDoc( jQuery( "tab", xml )[ 0 ] ), "XML Tab Element" ); -} ); - QUnit.test( "jQuery('html')", function( assert ) { assert.expect( 18 ); -- 2.39.5