Skip to content

Commit cd0239b

Browse files
authored
Selector: Use shallow document comparisons to avoid IE/Edge cras… (#459)
IE/Edge sometimes crash when comparing documents between frames using the strict equality operator (`===` & `!==`). Funnily enough, shallow comparisons (`==` & `!=`) work without crashing. Fixes jquery/jquery#4441 Closes gh-459 Ref jquery/jquery#4471
1 parent bdf2397 commit cd0239b

File tree

4 files changed

+135
-53
lines changed

4 files changed

+135
-53
lines changed

dist/sizzle.js

+67-26
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Released under the MIT license
77
* https://js.foundation/
88
*
9-
* Date: 2019-08-20
9+
* Date: 2019-10-01
1010
*/
1111
( function( window ) {
1212
var i,
@@ -251,10 +251,7 @@ function Sizzle( selector, context, results, seed ) {
251251

252252
// Try to shortcut find operations (as opposed to filters) in HTML documents
253253
if ( !seed ) {
254-
255-
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
256-
setDocument( context );
257-
}
254+
setDocument( context );
258255
context = context || document;
259256

260257
if ( documentIsHTML ) {
@@ -602,7 +599,11 @@ setDocument = Sizzle.setDocument = function( node ) {
602599
doc = node ? node.ownerDocument || node : preferredDoc;
603600

604601
// Return early if doc is invalid or already selected
605-
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
602+
// Support: IE 11+, Edge 17 - 18+
603+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
604+
// two documents; shallow comparisons work.
605+
// eslint-disable-next-line eqeqeq
606+
if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
606607
return document;
607608
}
608609

@@ -611,9 +612,13 @@ setDocument = Sizzle.setDocument = function( node ) {
611612
docElem = document.documentElement;
612613
documentIsHTML = !isXML( document );
613614

614-
// Support: IE 9-11, Edge
615+
// Support: IE 9 - 11+, Edge 12 - 18+
615616
// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
616-
if ( preferredDoc !== document &&
617+
// Support: IE 11+, Edge 17 - 18+
618+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
619+
// two documents; shallow comparisons work.
620+
// eslint-disable-next-line eqeqeq
621+
if ( preferredDoc != document &&
617622
( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
618623

619624
// Support: IE 11, Edge
@@ -928,7 +933,11 @@ setDocument = Sizzle.setDocument = function( node ) {
928933
}
929934

930935
// Calculate position if both inputs belong to the same document
931-
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
936+
// Support: IE 11+, Edge 17 - 18+
937+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
938+
// two documents; shallow comparisons work.
939+
// eslint-disable-next-line eqeqeq
940+
compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
932941
a.compareDocumentPosition( b ) :
933942

934943
// Otherwise we know they are disconnected
@@ -939,13 +948,20 @@ setDocument = Sizzle.setDocument = function( node ) {
939948
( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
940949

941950
// Choose the first element that is related to our preferred document
942-
if ( a === document ||
943-
a.ownerDocument === preferredDoc &&
951+
// Support: IE 11+, Edge 17 - 18+
952+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
953+
// two documents; shallow comparisons work.
954+
// eslint-disable-next-line eqeqeq
955+
if ( a == document || a.ownerDocument == preferredDoc &&
944956
contains( preferredDoc, a ) ) {
945957
return -1;
946958
}
947-
if ( b === document ||
948-
b.ownerDocument === preferredDoc &&
959+
960+
// Support: IE 11+, Edge 17 - 18+
961+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
962+
// two documents; shallow comparisons work.
963+
// eslint-disable-next-line eqeqeq
964+
if ( b == document || b.ownerDocument == preferredDoc &&
949965
contains( preferredDoc, b ) ) {
950966
return 1;
951967
}
@@ -975,8 +991,14 @@ setDocument = Sizzle.setDocument = function( node ) {
975991

976992
// Parentless nodes are either documents or disconnected
977993
if ( !aup || !bup ) {
978-
return a === document ? -1 :
979-
b === document ? 1 :
994+
995+
// Support: IE 11+, Edge 17 - 18+
996+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
997+
// two documents; shallow comparisons work.
998+
/* eslint-disable eqeqeq */
999+
return a == document ? -1 :
1000+
b == document ? 1 :
1001+
/* eslint-enable eqeqeq */
9801002
aup ? -1 :
9811003
bup ? 1 :
9821004
sortInput ?
@@ -1009,8 +1031,13 @@ setDocument = Sizzle.setDocument = function( node ) {
10091031
siblingCheck( ap[ i ], bp[ i ] ) :
10101032

10111033
// Otherwise nodes in our document sort first
1012-
ap[ i ] === preferredDoc ? -1 :
1013-
bp[ i ] === preferredDoc ? 1 :
1034+
// Support: IE 11+, Edge 17 - 18+
1035+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1036+
// two documents; shallow comparisons work.
1037+
/* eslint-disable eqeqeq */
1038+
ap[ i ] == preferredDoc ? -1 :
1039+
bp[ i ] == preferredDoc ? 1 :
1040+
/* eslint-enable eqeqeq */
10141041
0;
10151042
};
10161043

@@ -1022,11 +1049,7 @@ Sizzle.matches = function( expr, elements ) {
10221049
};
10231050

10241051
Sizzle.matchesSelector = function( elem, expr ) {
1025-
1026-
// Set document vars if needed
1027-
if ( ( elem.ownerDocument || elem ) !== document ) {
1028-
setDocument( elem );
1029-
}
1052+
setDocument( elem );
10301053

10311054
if ( support.matchesSelector && documentIsHTML &&
10321055
!nonnativeSelectorCache[ expr + " " ] &&
@@ -1055,7 +1078,11 @@ Sizzle.matchesSelector = function( elem, expr ) {
10551078
Sizzle.contains = function( context, elem ) {
10561079

10571080
// Set document vars if needed
1058-
if ( ( context.ownerDocument || context ) !== document ) {
1081+
// Support: IE 11+, Edge 17 - 18+
1082+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1083+
// two documents; shallow comparisons work.
1084+
// eslint-disable-next-line eqeqeq
1085+
if ( ( context.ownerDocument || context ) != document ) {
10591086
setDocument( context );
10601087
}
10611088
return contains( context, elem );
@@ -1064,7 +1091,11 @@ Sizzle.contains = function( context, elem ) {
10641091
Sizzle.attr = function( elem, name ) {
10651092

10661093
// Set document vars if needed
1067-
if ( ( elem.ownerDocument || elem ) !== document ) {
1094+
// Support: IE 11+, Edge 17 - 18+
1095+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1096+
// two documents; shallow comparisons work.
1097+
// eslint-disable-next-line eqeqeq
1098+
if ( ( elem.ownerDocument || elem ) != document ) {
10681099
setDocument( elem );
10691100
}
10701101

@@ -2098,7 +2129,12 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
20982129
len = elems.length;
20992130

21002131
if ( outermost ) {
2101-
outermostContext = context === document || context || outermost;
2132+
2133+
// Support: IE 11+, Edge 17 - 18+
2134+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2135+
// two documents; shallow comparisons work.
2136+
// eslint-disable-next-line eqeqeq
2137+
outermostContext = context == document || context || outermost;
21022138
}
21032139

21042140
// Add elements passing elementMatchers directly to results
@@ -2107,7 +2143,12 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
21072143
for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
21082144
if ( byElement && elem ) {
21092145
j = 0;
2110-
if ( !context && elem.ownerDocument !== document ) {
2146+
2147+
// Support: IE 11+, Edge 17 - 18+
2148+
// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2149+
// two documents; shallow comparisons work.
2150+
// eslint-disable-next-line eqeqeq
2151+
if ( !context && elem.ownerDocument != document ) {
21112152
setDocument( elem );
21122153
xml = !documentIsHTML;
21132154
}

0 commit comments

Comments
 (0)