Skip to content

Selector: Make selector lists work with qSA again #5178

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

Merged
merged 3 commits into from
Dec 19, 2022

Conversation

mgol
Copy link
Member

@mgol mgol commented Dec 17, 2022

Summary

jQuery 3.6.2 started using CSS.supports( "selector(SELECTOR)" ) before using querySelectorAll on the selector. This was to solve gh-5098 - some selectors, like :has(), now have their parameters parsed in a forgiving way, meaning that :has(:fakepseudo) no longer throws but just returns 0 results, breaking that jQuery 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 jQuery 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 jQuery 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 gh-5177
Ref w3c/csswg-drafts#7280

+2 bytes

Checklist

@mgol mgol self-assigned this Dec 17, 2022
@mgol mgol added Needs review Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. Selector labels Dec 17, 2022
@mgol mgol modified the milestones: 4.0.0, 3.7.0 Dec 17, 2022
@mgol mgol force-pushed the supports-selector-list-fix-gh-5177 branch 2 times, most recently from 4255ed6 to 7f8a7a8 Compare December 17, 2022 22:15
jQuery 3.6.2 started using `CSS.supports( "selector(SELECTOR)" )` before using
`querySelectorAll` on the selector. This was to solve jquerygh-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 jQuery 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 jQuery 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 jQuery 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 jquerygh-5177
Ref w3c/csswg-drafts#7280
@mgol mgol force-pushed the supports-selector-list-fix-gh-5177 branch from 7f8a7a8 to 71f6ecd Compare December 17, 2022 22:18
@timmywil timmywil removed the Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. label Dec 19, 2022
@mgol mgol merged commit 09d988b into jquery:main Dec 19, 2022
@mgol mgol deleted the supports-selector-list-fix-gh-5177 branch December 19, 2022 17:43
mgol added a commit that referenced this pull request Dec 19, 2022
mgol added a commit that referenced this pull request Dec 19, 2022
jQuery 3.6.2 started using `CSS.supports( "selector(SELECTOR)" )` before using
`querySelectorAll` on the selector. This was to solve gh-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 jQuery 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 jQuery 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 jQuery 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 gh-5177
Closes gh-5178
Ref w3c/csswg-drafts#7280

(cherry picked from commit 09d988b)
@mgol
Copy link
Member Author

mgol commented Dec 19, 2022

Landed on main (future jQuery 4.0.0) in 09d988b and on 3.x-stable (future jQuery 3.7.0) in 848de62.

mgol added a commit that referenced this pull request Dec 19, 2022
A newly added test making sure a native selector containing
the `:valid` pseudo works when no jQuery-specific selectors
are used was failing in IE 9 as that browser lacks support
for this pseudo. This commit disables that test in IE 9.

Ref gh-5178
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

unsupported pseudo: valid with selector list
2 participants