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: Stop relying on CSS.supports( "selector(...)" ) #5206

Merged
merged 3 commits into from
Feb 14, 2023

Conversation

mgol
Copy link
Member

@mgol mgol commented Feb 9, 2023

Summary

CSS.supports( "selector(...)" ) has different semantics than selectors passed to querySelectorAll. Apart from the fact that the former returns false for unrecognized selectors and the latter throws, qSA is more forgiving and accepts some invalid selectors, auto-correcting them where needed - for example, mismatched brackets are auto-closed. This behavior difference is breaking for many users.

To add to that, a recent CSSWG resolution made :is() & :where() the only pseudos 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 approach without relying on CSS.supports( "selector(...)" ). The only difference is we detect forgiving parsing in :has() and mark the selector as buggy.

The PR also updates playwright-webkit so that we test against a version of WebKit that already has non-forgiving :has().

Fixes gh-5194
Ref gh-5098
Ref gh-5107
Ref w3c/csswg-drafts#7676

-41 bytes

Checklist

  • New tests have been added to show the fix or feature works
  • Grunt build and unit tests pass locally with these changes
  • If needed, a docs issue/PR was created at https://github.com/jquery/api.jquery.com

@mgol mgol added Selector Needs review Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. labels Feb 9, 2023
@mgol mgol added this to the 4.0.0 milestone Feb 9, 2023
@mgol mgol self-assigned this Feb 9, 2023
@mgol
Copy link
Member Author

mgol commented Feb 9, 2023

I didn't write any new unit tests. I was wondering whether to do that but while being able to leverage the more forgiving native qSA parsing was our goal, I'm not sure if we want to guarantee such lax parsing in our unit tests. What do you think?

@mgol
Copy link
Member Author

mgol commented Feb 9, 2023

I still need to prepare a version for 3.x-stable (it won't be an exact cherry-pick) and Sizzle.

@mgol
Copy link
Member Author

mgol commented Feb 9, 2023

The 3.x version of this PR: #5207.

@mgol
Copy link
Member Author

mgol commented Feb 10, 2023

Sizzle PR: jquery/sizzle#493

@timmywil timmywil removed the Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. label Feb 13, 2023
Copy link
Member

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I left some comment rewording suggestions.

src/selector/rbuggyQSA.js Outdated Show resolved Hide resolved
src/selector/support.js Outdated Show resolved Hide resolved
mgol and others added 2 commits February 14, 2023 00:30
`CSS.supports( "selector(...)" )` has different semantics than selectors passed
to `querySelectorAll`. Apart from the fact that the former returns `false` for
unrecognized selectors and the latter throws, `qSA` is more forgiving and
accepts some invalid selectors, auto-correcting them where needed - for
example, mismatched brackers are auto-closed. This behavior difference is
breaking for many users.

To add to that, a recent CSSWG resolution made `:is()` & `:where()` the only
pseudos 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 approach
without relying on `CSS.supports( "selector(...)" )`. The only difference
is we detect forgiving parsing in `:has()` and mark the selector as buggy.

The PR also updates `playwright-webkit` so that we test against a version
of WebKit that already has non-forgiving `:has()`.

Fixes jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
@mgol mgol force-pushed the has-non-forgiving branch from 880fad5 to 5817baa Compare February 13, 2023 23:30
@mgol mgol removed the Needs review label Feb 14, 2023
@mgol mgol merged commit 68aa2ef into jquery:main Feb 14, 2023
@mgol mgol deleted the has-non-forgiving branch February 14, 2023 09:11
mgol added a commit that referenced this pull request Feb 14, 2023
`CSS.supports( "selector(...)" )` has different semantics than selectors passed
to `querySelectorAll`. Apart from the fact that the former returns `false` for
unrecognized selectors and the latter throws, `qSA` is more forgiving and
accepts some invalid selectors, auto-correcting them where needed - for
example, mismatched brackers are auto-closed. This behavior difference is
breaking for many users.

To add to that, a recent CSSWG resolution made `:is()` & `:where()` the only
pseudos 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 approach
without relying on `CSS.supports( "selector(...)" )`. The only difference
is we detect forgiving parsing in `:has()` and mark the selector as buggy.

The PR also updates `playwright-webkit` so that we test against a version
of WebKit that already has non-forgiving `:has()`.

Fixes gh-5194
Closes gh-5207
Ref gh-5206
Ref gh-5098
Ref gh-5107
Ref w3c/csswg-drafts#7676
mgol added a commit to jquery/sizzle that referenced this pull request Feb 14, 2023
`CSS.supports( "selector(...)" )` has different semantics than selectors passed
to `querySelectorAll`. Apart from the fact that the former returns `false` for
unrecognized selectors and the latter throws, `qSA` is more forgiving and
accepts some invalid selectors, auto-correcting them where needed - for
example, mismatched brackers are auto-closed. This behavior difference is
breaking for many users.

To add to that, a recent CSSWG resolution made `:is()` & `:where()` the only
pseudos 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 approach
without relying on `CSS.supports( "selector(...)" )`. The only difference
is we detect forgiving parsing in `:has()` and mark the selector as buggy.

Fixes jquery/jquery#5194
Closes gh-493
Ref jquery/jquery#5098
Ref jquery/jquery#5206
Ref jquery/jquery#5207
Ref gh-486
Ref w3c/csswg-drafts#7676
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.

jQuery 3.6.3 throws on some invalid selectors accepted in <=3.6.1 in Firefox (it works in Chrome & Safari)
3 participants