Skip to content

Commit d0a579c

Browse files
committed
Selector: Leverage the :scope pseudo-class where possible (no EdgeHTML support)
The `:scope` pseudo-class[1] has surprisingly good browser support: Chrome, Firefox & Safari have supported if for a long time; only IE & Edge lack support. This commit leverages this pseudo-class to get rid of the ID hack in most cases. Adding a temporary ID may cause layout thrashing which was reported a few times in [the past. We can't completely eliminate the ID hack in modern browses as sibling selectors require us to change context to the parent and then `:scope` stops applying to what we'd like. But it'd still improve performance in the vast majority of cases. [1] https://developer.mozilla.org/en-US/docs/Web/CSS/:scope Fixes jquerygh-4453 Ref jquerygh-4332 Ref jquery/sizzle#405
1 parent 29a9544 commit d0a579c

File tree

2 files changed

+13
-24
lines changed

2 files changed

+13
-24
lines changed

src/selector.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ define( [
66
"./var/pop",
77
"./var/push",
88
"./selector/rbuggyQSA",
9-
"./selector/support",
9+
"./var/isIE",
1010

1111
// The following utils are attached directly to the jQuery object.
1212
"./selector/contains",
1313
"./selector/escapeSelector",
1414
"./selector/uniqueSort"
15-
], function( jQuery, document, documentElement, indexOf, pop, push, rbuggyQSA, support ) {
15+
], function( jQuery, document, documentElement, indexOf, pop, push, rbuggyQSA, isIE ) {
1616

1717
"use strict";
1818

@@ -155,7 +155,7 @@ function selectorError( msg ) {
155155
}
156156

157157
function find( selector, context, results, seed ) {
158-
var m, i, elem, nid, match, groups, newSelector,
158+
var m, i, elem, nid, match, groups, newSelector, canUseScope,
159159
newContext = context && context.ownerDocument,
160160

161161
// nodeType defaults to 9, since context defaults to document
@@ -236,9 +236,10 @@ function find( selector, context, results, seed ) {
236236

237237
// We can use :scope instead of the ID hack if the browser
238238
// supports it & if we're not changing the context.
239-
if ( newContext !== context || !support.scope ) {
239+
canUseScope = newContext === context && !isIE;
240240

241-
// Capture the context ID, setting it first if necessary
241+
// Capture the context ID, setting it first if necessary
242+
if ( !canUseScope ) {
242243
if ( ( nid = context.getAttribute( "id" ) ) ) {
243244
nid = jQuery.escapeSelector( nid );
244245
} else {
@@ -250,7 +251,7 @@ function find( selector, context, results, seed ) {
250251
groups = tokenize( selector );
251252
i = groups.length;
252253
while ( i-- ) {
253-
groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
254+
groups[ i ] = ( canUseScope || "#" + nid ) + " " +
254255
toSelector( groups[ i ] );
255256
}
256257
newSelector = groups.join( "," );

test/unit/support.js

+6-18
Original file line numberDiff line numberDiff line change
@@ -58,24 +58,12 @@ testIframe(
5858
var expected,
5959
userAgent = window.navigator.userAgent,
6060
expectedMap = {
61-
edge: {
62-
scope: undefined
63-
},
64-
ie_11: {
65-
scope: undefined
66-
},
67-
chrome: {
68-
scope: true
69-
},
70-
safari: {
71-
scope: true
72-
},
73-
firefox: {
74-
scope: true
75-
},
76-
ios: {
77-
scope: true
78-
}
61+
edge: {},
62+
ie_11: {},
63+
chrome: {},
64+
safari: {},
65+
firefox: {},
66+
ios: {}
7967
};
8068

8169
if ( /edge\//i.test( userAgent ) ) {

0 commit comments

Comments
 (0)