🌐 AI搜索 & 代理 主页
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"load-grunt-tasks": "5.1.0",
"multiparty": "4.2.3",
"native-promise-only": "0.8.1",
"playwright-webkit": "1.29.2",
"playwright-webkit": "1.30.0",
"promises-aplus-tests": "2.1.2",
"q": "1.5.1",
"qunit": "2.10.1",
Expand Down
27 changes: 0 additions & 27 deletions src/selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import selectorError from "./selector/selectorError.js";
import unescapeSelector from "./selector/unescapeSelector.js";
import tokenize from "./selector/tokenize.js";
import toSelector from "./selector/toSelector.js";
import support from "./selector/support.js";

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

try {

// `qSA` may not throw for unrecognized parts using forgiving parsing:
// https://drafts.csswg.org/selectors/#forgiving-selector
// like the `:is()` pseudo-class:
// https://drafts.csswg.org/selectors/#matches
// `CSS.supports` is still expected to return `false` then:
// https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn
// https://drafts.csswg.org/css-conditional-4/#dfn-support-selector
if ( support.cssSupportsSelector &&

// `CSS.supports( "selector(...)" )` requires the argument to the
// `selector` function to be a `<complex-selector>`, not
// a `<complex-selector-list>` which our selector may be. Wrapping with
// `:is` works around the issue and is supported by all browsers
// we support except for IE which will fail the support test anyway.
// eslint-disable-next-line no-undef
!CSS.supports( "selector(:is(" + newSelector + "))" ) ) {

// Support: IE 11+
// Throw to get to the same code path as an error directly in qSA.
// Note: once we only support browser supporting
// `CSS.supports('selector(...)')`, we can most likely drop
// the `try-catch`. IE doesn't implement the API.
throw new Error();
}

push.apply( results,
newContext.querySelectorAll( newSelector )
);
Expand Down
16 changes: 8 additions & 8 deletions src/selector/rbuggyQSA.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ if ( isIE ) {
);
}

if ( !support.cssSupportsSelector ) {

// Support: Chrome 105+, Safari 15.4+
// `:has()` uses a forgiving selector list as an argument so our regular
// `try-catch` mechanism fails to catch `:has()` with arguments not supported
// natively like `:has(:contains("Foo"))`. Where supported & spec-compliant,
// we now use `CSS.supports("selector(:is(SELECTOR_TO_BE_TESTED))")`, but
// outside that we mark `:has` as buggy.
if ( !support.cssHas ) {

// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
// Our regular `try-catch` mechanism fails to detect natively-unsupported
// pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
// in browsers that parse the `:has()` argument as a forgiving selector list.
// https://drafts.csswg.org/selectors/#relational now requires the argument
// to be parsed unforgivingly, but browsers have not yet fully adjusted.
rbuggyQSA.push( ":has" );
}

Expand Down
33 changes: 13 additions & 20 deletions src/selector/support.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import document from "../var/document.js";
import support from "../var/support.js";

// Support: IE 11+
// IE doesn't support `CSS.supports( "selector(...)" )`; it will throw
// in this support test.
// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
// Make sure the the `:has()` argument is parsed unforgivingly.
// We include `*` in the test to detect buggy implementations that are
// _selectively_ forgiving (specifically when the list includes at least
// one valid selector).
// Note that we treat complete lack of support for `:has()` as if it were
// spec-compliant support, which is fine because use of `:has()` in such
// environments will fail in the qSA path and fall back to jQuery traversal
// anyway.
try {
/* eslint-disable no-undef */

// Support: Chrome 105+, Firefox <106, Safari 15.4+
// Make sure forgiving mode is not used in `CSS.supports( "selector(...)" )`.
//
// `:is()` uses a forgiving selector list as an argument and is widely
// implemented, so it's a good one to test against.
support.cssSupportsSelector = CSS.supports( "selector(*)" ) &&

// `*` is needed as Safari & newer Chrome implemented something in between
// for `:has()` - it throws in `qSA` if it only contains an unsupported
// argument but multiple ones, one of which is supported, are fine.
// We want to play safe in case `:is()` gets the same treatment.
!CSS.supports( "selector(:is(*,:jqfake))" );

/* eslint-enable */
document.querySelector( ":has(*,:jqfake)" );
support.cssHas = false;
} catch ( e ) {
support.cssSupportsSelector = false;
support.cssHas = true;
}

export default support;
22 changes: 14 additions & 8 deletions test/unit/support.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,39 +59,43 @@ testIframe(
userAgent = window.navigator.userAgent,
expectedMap = {
ie_11: {
cssSupportsSelector: false,
cssHas: true,
reliableTrDimensions: false
},
chrome: {
cssSupportsSelector: false,
cssHas: false,
reliableTrDimensions: true
},
safari: {
cssSupportsSelector: false,
cssHas: false,
reliableTrDimensions: true
},
webkit: {
cssSupportsSelector: true,
cssHas: true,
reliableTrDimensions: true
},
firefox_102: {
cssSupportsSelector: false,
cssHas: true,
reliableTrDimensions: false
},
firefox: {
cssSupportsSelector: true,
cssHas: true,
reliableTrDimensions: false
},
ios_14_15_3: {
cssHas: true,
reliableTrDimensions: true
},
ios: {
cssSupportsSelector: false,
cssHas: false,
reliableTrDimensions: true
}
};

// Make the selector-native build pass tests.
for ( browserKey in expectedMap ) {
if ( !includesModule( "selector" ) ) {
delete expectedMap[ browserKey ].cssSupportsSelector;
delete expectedMap[ browserKey ].cssHas;
}
}

Expand All @@ -105,6 +109,8 @@ testIframe(
expected = expectedMap.firefox_102;
} else if ( /firefox/i.test( userAgent ) ) {
expected = expectedMap.firefox;
} else if ( /iphone os (?:14_|15_[0123])/i.test( userAgent ) ) {
expected = expectedMap.ios_14_15_3;
} else if ( /(?:iphone|ipad);.*(?:iphone)? os \d+_/i.test( userAgent ) ) {
expected = expectedMap.ios;
} else if ( typeof URLSearchParams !== "undefined" &&
Expand Down