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 79b74e043a)

Closes gh-4438
Ref jquery/sizzle#378
Ref jquery/sizzle#436
This commit is contained in:
Michał Gołębiowski-Owczarek 2019-07-29 22:06:18 +02:00 committed by GitHub
parent 90f78b9aab
commit 2d9d6d5b47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 12 deletions

View File

@ -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 ) {
var namespace = elem.namespaceURI,
documentElement = ( elem.ownerDocument || elem ).documentElement;
// 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;
// Assume HTML when documentElement doesn't yet exist, such as inside
// document fragments.
return !rhtmlSuffix.test( namespace ||
documentElement && documentElement.nodeName ||
"HTML" );
},
expr: {
attrHandle: {},

View File

@ -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( "<div>" +
"<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='1' width='1'>" +
"<desc></desc>" +
"</svg>" +
"</div>"
)[ 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(
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " +
"\"http://www.w3.org/Gaphics/SVG/1.1/DTD/svg11.dtd\">" +
"<svg version='1.1' xmlns='http://www.w3.org/2000/svg'><desc/></svg>"
);
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 );