Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selector: Make selector lists work with qSA again #491

Merged
merged 2 commits into from
Dec 19, 2022

Conversation

mgol
Copy link
Member

@mgol mgol commented Dec 17, 2022

Sizzle 2.3.7 started using CSS.supports( "selector(SELECTOR)" ) before using querySelectorAll on the selector. This was to solve jquery/jquery#5098 - some selectors, like :has(), now had their parameters parsed in a forgiving way, meaning that :has(:fakepseudo) no longer throws but just returns 0 results, breaking that Sizzle mechanism.

A recent spec change made CSS.supports( "selector(SELECTOR)" ) always use non-forgiving parsing, allowing us to use this API for what we've used try-catch before.

To solve the issue on the spec side for older jQuery versions, :has() parameters are no longer using forgiving parsing in the latest spec update but our new mechanism is more future-proof anyway.

However, the Sizzle implementation has a bug - in
CSS.supports( "selector(SELECTOR)" ), SELECTOR needs to be a <complex-selector> and not a <complex-selector-list>. Which means that selector lists now skip qSA and go to the Sizzle custom traversal:

CSS.supports("selector(div:valid, span)"); // false
CSS.supports("selector(div:valid)"); // true
CSS.supports("selector(span)"); // true

To solve this, this commit wraps the selector list passed to CSS.supports( "selector(:is(SELECTOR))" ) with :is, making it a single selector again.

See:

Fixes jquery/jquery#5177
Ref w3c/csswg-drafts#7280

+2 bytes

@mgol mgol self-assigned this Dec 17, 2022
@mgol mgol added this to the 2.3.9 milestone Dec 17, 2022
Sizzle 2.3.7 started using `CSS.supports( "selector(SELECTOR)" )` before using
`querySelectorAll` on the selector. This was to solve jquery/jquery#5098 -
some selectors, like `:has()`, now had their parameters parsed in a forgiving
way, meaning that `:has(:fakepseudo)` no longer throws but just returns
0 results, breaking that Sizzle mechanism.

A recent spec change made `CSS.supports( "selector(SELECTOR)" )` always use
non-forgiving parsing, allowing us to use this API for what we've used
`try-catch` before.

To solve the issue on the spec side for older jQuery versions, `:has()`
parameters are no longer using forgiving parsing in the latest spec update
but our new mechanism is more future-proof anyway.

However, the Sizzle implementation has a bug - in
`CSS.supports( "selector(SELECTOR)" )`, `SELECTOR` needs to be
a `<complex-selector>` and not a `<complex-selector-list>`. Which means that
selector lists now skip `qSA` and go to the Sizzle custom traversal:
```js
CSS.supports("selector(div:valid, span)"); // false
CSS.supports("selector(div:valid)"); // true
CSS.supports("selector(span)"); // true
```

To solve this, this commit wraps the selector list passed to
`CSS.supports( "selector(:is(SELECTOR))" )` with `:is`, making it a single
selector again.

See:
* https://w3c.github.io/csswg-drafts/css-conditional-4/#at-supports-ext
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector
* https://w3c.github.io/csswg-drafts/selectors-4/#typedef-complex-selector-list

Fixes jquery/jquery#5177
Ref w3c/csswg-drafts#7280
@mgol mgol force-pushed the supports-selector-list-fix-jq-5177 branch from 4ba83c9 to 48b0c88 Compare December 17, 2022 22:49
src/sizzle.js Outdated Show resolved Hide resolved
Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
@mgol mgol merged commit 7781b65 into jquery:main Dec 19, 2022
@mgol mgol deleted the supports-selector-list-fix-jq-5177 branch December 19, 2022 17:43
mgol added a commit to jquery/jquery that referenced this pull request Dec 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

unsupported pseudo: valid with selector list
2 participants