Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit68aa2ef

Browse files
mgolgibson042
andauthored
Selector: Stop relying on CSS.supports( "selector(...)" )
`CSS.supports( "selector(...)" )` has different semantics than selectors passedto `querySelectorAll`. Apart from the fact that the former returns `false` forunrecognized selectors and the latter throws, `qSA` is more forgiving andaccepts some invalid selectors, auto-correcting them where needed - forexample, mismatched brackers are auto-closed. This behavior difference isbreaking for many users.To add to that, a recent CSSWG resolution made `:is()` & `:where()` the onlypseudos with forgiving parsing; browsers are in the process of making `:has()`parsing unforgiving.Taking all that into account, we go back to our previous try-catch approachwithout relying on `CSS.supports( "selector(...)" )`. The only differenceis we detect forgiving parsing in `:has()` and mark the selector as buggy.The PR also updates `playwright-webkit` so that we test against a versionof WebKit that already has non-forgiving `:has()`.Fixesgh-5194Closesgh-5206Refgh-5098Refgh-5107Refw3c/csswg-drafts#7676Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
1 parent2e644e8 commit68aa2ef

File tree

5 files changed

+36
-64
lines changed

5 files changed

+36
-64
lines changed

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"load-grunt-tasks":"5.1.0",
5858
"multiparty":"4.2.3",
5959
"native-promise-only":"0.8.1",
60-
"playwright-webkit":"1.29.2",
60+
"playwright-webkit":"1.30.0",
6161
"promises-aplus-tests":"2.1.2",
6262
"q":"1.5.1",
6363
"qunit":"2.10.1",

‎src/selector.js

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import selectorError from "./selector/selectorError.js";
2222
importunescapeSelectorfrom"./selector/unescapeSelector.js";
2323
importtokenizefrom"./selector/tokenize.js";
2424
importtoSelectorfrom"./selector/toSelector.js";
25-
importsupportfrom"./selector/support.js";
2625

2726
// The following utils are attached directly to the jQuery object.
2827
import"./selector/escapeSelector.js";
@@ -189,32 +188,6 @@ function find( selector, context, results, seed ) {
189188
}
190189

191190
try{
192-
193-
// `qSA` may not throw for unrecognized parts using forgiving parsing:
194-
// https://drafts.csswg.org/selectors/#forgiving-selector
195-
// like the `:is()` pseudo-class:
196-
// https://drafts.csswg.org/selectors/#matches
197-
// `CSS.supports` is still expected to return `false` then:
198-
// https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
199-
// https://drafts.csswg.org/css-conditional-4/#dfn-support-selector
200-
if(support.cssSupportsSelector&&
201-
202-
// `CSS.supports( "selector(...)" )` requires the argument to the
203-
// `selector` function to be a `<complex-selector>`, not
204-
// a `<complex-selector-list>` which our selector may be. Wrapping with
205-
// `:is` works around the issue and is supported by all browsers
206-
// we support except for IE which will fail the support test anyway.
207-
// eslint-disable-next-line no-undef
208-
!CSS.supports("selector(:is("+newSelector+"))")){
209-
210-
// Support: IE 11+
211-
// Throw to get to the same code path as an error directly in qSA.
212-
// Note: once we only support browser supporting
213-
// `CSS.supports('selector(...)')`, we can most likely drop
214-
// the `try-catch`. IE doesn't implement the API.
215-
thrownewError();
216-
}
217-
218191
push.apply(results,
219192
newContext.querySelectorAll(newSelector)
220193
);

‎src/selector/rbuggyQSA.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ if ( isIE ) {
2121
);
2222
}
2323

24-
if(!support.cssSupportsSelector){
25-
26-
// Support: Chrome 105+, Safari 15.4+
27-
//`:has()` uses a forgiving selector list as an argument so our regular
28-
//`try-catch` mechanism fails to catch`:has()`with arguments not supported
29-
//natively like`:has(:contains("Foo"))`. Where supported & spec-compliant,
30-
//we nowuse `CSS.supports("selector(:is(SELECTOR_TO_BE_TESTED))")`, but
31-
//outside that we mark `:has` as buggy.
24+
if(!support.cssHas){
25+
26+
// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
27+
//Our regular `try-catch` mechanism fails to detect natively-unsupported
28+
//pseudo-classes inside`:has()`(such as `:has(:contains("Foo"))`)
29+
//in browsers that parse the`:has()` argument as a forgiving selector list.
30+
//https://drafts.csswg.org/selectors/#relational nowrequires the argument
31+
//to be parsed unforgivingly, but browsers have not yet fully adjusted.
3232
rbuggyQSA.push(":has");
3333
}
3434

‎src/selector/support.js

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
1+
importdocumentfrom"../var/document.js";
12
importsupportfrom"../var/support.js";
23

3-
// Support: IE 11+
4-
// IE doesn't support `CSS.supports( "selector(...)" )`; it will throw
5-
// in this support test.
4+
// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
5+
// Make sure the the `:has()` argument is parsed unforgivingly.
6+
// We include `*` in the test to detect buggy implementations that are
7+
// _selectively_ forgiving (specifically when the list includes at least
8+
// one valid selector).
9+
// Note that we treat complete lack of support for `:has()` as if it were
10+
// spec-compliant support, which is fine because use of `:has()` in such
11+
// environments will fail in the qSA path and fall back to jQuery traversal
12+
// anyway.
613
try{
7-
/* eslint-disable no-undef */
8-
9-
// Support: Chrome 105+, Firefox <106, Safari 15.4+
10-
// Make sure forgiving mode is not used in `CSS.supports( "selector(...)" )`.
11-
//
12-
// `:is()` uses a forgiving selector list as an argument and is widely
13-
// implemented, so it's a good one to test against.
14-
support.cssSupportsSelector=CSS.supports("selector(*)")&&
15-
16-
// `*` is needed as Safari & newer Chrome implemented something in between
17-
// for `:has()` - it throws in `qSA` if it only contains an unsupported
18-
// argument but multiple ones, one of which is supported, are fine.
19-
// We want to play safe in case `:is()` gets the same treatment.
20-
!CSS.supports("selector(:is(*,:jqfake))");
21-
22-
/* eslint-enable */
14+
document.querySelector(":has(*,:jqfake)");
15+
support.cssHas=false;
2316
}catch(e){
24-
support.cssSupportsSelector=false;
17+
support.cssHas=true;
2518
}
2619

2720
exportdefaultsupport;

‎test/unit/support.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,39 +59,43 @@ testIframe(
5959
userAgent=window.navigator.userAgent,
6060
expectedMap={
6161
ie_11:{
62-
cssSupportsSelector:false,
62+
cssHas:true,
6363
reliableTrDimensions:false
6464
},
6565
chrome:{
66-
cssSupportsSelector:false,
66+
cssHas:false,
6767
reliableTrDimensions:true
6868
},
6969
safari:{
70-
cssSupportsSelector:false,
70+
cssHas:false,
7171
reliableTrDimensions:true
7272
},
7373
webkit:{
74-
cssSupportsSelector:true,
74+
cssHas:true,
7575
reliableTrDimensions:true
7676
},
7777
firefox_102:{
78-
cssSupportsSelector:false,
78+
cssHas:true,
7979
reliableTrDimensions:false
8080
},
8181
firefox:{
82-
cssSupportsSelector:true,
82+
cssHas:true,
8383
reliableTrDimensions:false
8484
},
85+
ios_14_15_3:{
86+
cssHas:true,
87+
reliableTrDimensions:true
88+
},
8589
ios:{
86-
cssSupportsSelector:false,
90+
cssHas:false,
8791
reliableTrDimensions:true
8892
}
8993
};
9094

9195
// Make the selector-native build pass tests.
9296
for(browserKeyinexpectedMap){
9397
if(!includesModule("selector")){
94-
deleteexpectedMap[browserKey].cssSupportsSelector;
98+
deleteexpectedMap[browserKey].cssHas;
9599
}
96100
}
97101

@@ -105,6 +109,8 @@ testIframe(
105109
expected=expectedMap.firefox_102;
106110
}elseif(/firefox/i.test(userAgent)){
107111
expected=expectedMap.firefox;
112+
}elseif(/iphoneos(?:14_|15_[0123])/i.test(userAgent)){
113+
expected=expectedMap.ios_14_15_3;
108114
}elseif(/(?:iphone|ipad);.*(?:iphone)?os\d+_/i.test(userAgent)){
109115
expected=expectedMap.ios;
110116
}elseif(typeofURLSearchParams!=="undefined"&&

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp