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: Use jQuery :has if CSS.supports(selector(...)) non-compliant #5107

Merged
merged 1 commit into from
Sep 19, 2022

Conversation

mgol
Copy link
Member

@mgol mgol commented Sep 5, 2022

Summary

jQuery has followed the following logic for selector handling for ages:

  1. Modify the selector to adhere to scoping rules jQuery mandates.
  2. Try qSA on the modified selector. If it succeeds, use the results.
  3. If qSA threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like :is() & :has() use. That means providing unrecognized
selectors as parameters to :is() & :has() no longer throws an error, it will
just return no results. That made browsers with native :has() support break
selectors using jQuery extensions inside, e.g. :has(:contains("Item")).

Detecting support for selectors can also be done via:

CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )

which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:

  1. In browsers supports the new spec change to CSS.supports( "selector()" ),
    use it before trying qSA.
  2. Otherwise, add :has to the buggy selectors list.

Fixes gh-5098

+118 bytes but +93 out of that is this new mechanism using CSS.supports( "selector()" ) which we have to add anyway due to what I described above. Of course, suggestions on how to reduce that welcome.

A backport of that to Sizzle will be required once this PR is accepted.

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 Sep 5, 2022
@mgol mgol added this to the 4.0.0 milestone Sep 5, 2022
@mgol mgol self-assigned this Sep 5, 2022
@mgol mgol force-pushed the css-supports-has branch 4 times, most recently from ff6a2e2 to 6842abe Compare September 5, 2022 15:23
@mgol
Copy link
Member Author

mgol commented Sep 5, 2022

Chrome 105 is not available in GitHub Actions yet but I checked locally that all tests are passing there.

mgol added a commit to mgol/jquery that referenced this pull request Sep 8, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
@mgol
Copy link
Member Author

mgol commented Sep 9, 2022

Oh, tests already run on Chrome 105 in this PR. That confirms the fix works.

mgol added a commit to mgol/sizzle that referenced this pull request Sep 11, 2022
Sizzle has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the Sizzle custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Fixes jquery/jquery#5098
Ref jquery/jquery#5107
@mgol
Copy link
Member Author

mgol commented Sep 11, 2022

Sizzle version of this PR, meant for jQuery 3.6.2: jquery/sizzle#486

mgol added a commit to mgol/jquery that referenced this pull request Sep 12, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
// eslint-disable-next-line no-undef
!CSS.supports( "selector(" + newSelector + ")" ) ) {

// Support: IE 11+
Copy link
Member Author

Choose a reason for hiding this comment

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

This is actually not just targeted at IE but at all browsers where CSS.supports is buggy. I should update the comment.

@mgol mgol changed the title Selector: Use jQuery :has if CSS.supports(selector(...)) non-compliant Selector: Use jQuery :has if CSS.supports(selector(...)) non-compliant Sep 15, 2022
Copy link
Member

@timmywil timmywil left a comment

Choose a reason for hiding this comment

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

LGTM!

mgol added a commit to mgol/sizzle that referenced this pull request Sep 19, 2022
Sizzle has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the Sizzle custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Fixes jquery/jquery#5098
Ref jquery/jquery#5107
@mgol mgol removed Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. Needs review labels Sep 19, 2022
mgol added a commit to mgol/sizzle that referenced this pull request Sep 19, 2022
Sizzle has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the Sizzle custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Fixes jquery/jquery#5098
Ref jquery/jquery#5107
Ref w3c/csswg-drafts#7676
@mgol mgol deleted the css-supports-has branch September 19, 2022 18:56
mgol added a commit to jquery/sizzle that referenced this pull request Sep 19, 2022
…liant

Sizzle has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the Sizzle custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Fixes jquery/jquery#5098
Closes gh-486
Ref jquery/jquery#5107
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Sep 19, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Sep 21, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Sep 21, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Sep 21, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Oct 3, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Oct 3, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Oct 3, 2022
mgol added a commit to mgol/jquery that referenced this pull request Oct 3, 2022
mgol added a commit that referenced this pull request Oct 4, 2022
mgol added a commit to mgol/jquery that referenced this pull request Oct 4, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Oct 4, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Nov 17, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Nov 17, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Dec 1, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Dec 1, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Dec 13, 2022
The failure was caused by incorrect usage of self-closing tags, incompatible
with jQuery 3.5.0+.

As of this commit, all tests pass in Firefox 104.0.2 and almost all in
Chrome 105.0.5195.102 - with the exception of ones fixed in jquerygh-5107.

From Sizzle tests run on `jQuery.find`, apart from the above, there are still
two failures in both these browsers:
* `selector: id`: ID Selector on Form with an input that has a name of 'id'
   (#lengthtest)
* `utilities: Sizzle.uniqueSort`: Attached/detached mixture (array) &
  Attached/detached mixture (quasi-array)
mgol added a commit to mgol/jquery that referenced this pull request Dec 13, 2022
jQuery has followed the following logic for selector handling for ages:
1. Modify the selector to adhere to scoping rules jQuery mandates.
2. Try `qSA` on the modified selector. If it succeeds, use the results.
3. If `qSA` threw an error, run the jQuery custom traversal instead.

It worked fine so far but now CSS has a concept of forgiving selector lists that
some selectors like `:is()` & `:has()` use. That means providing unrecognized
selectors as parameters to `:is()` & `:has()` no longer throws an error, it will
just return no results. That made browsers with native `:has()` support break
selectors using jQuery extensions inside, e.g. `:has(:contains("Item"))`.

Detecting support for selectors can also be done via:

```js
CSS.supports( "selector(SELECTOR_TO_BE_TESTED)" )
```
which returns a boolean. There was a recent spec change requiring this API to
always use non-forgiving parsing:
w3c/csswg-drafts#7280 (comment)
However, no browsers have implemented this change so far.

To solve this, two changes are being made:
1. In browsers supports the new spec change to `CSS.supports( "selector()" )`,
   use it before trying `qSA`.
2. Otherwise, add `:has` to the buggy selectors list.

Ref jquerygh-5098
Ref jquerygh-5107
Ref jquery/sizzle#486
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Feb 9, 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 jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Feb 9, 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 jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Feb 9, 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 jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Feb 13, 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 jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
mgol added a commit to mgol/jquery that referenced this pull request Feb 13, 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 jquerygh-5194
Ref jquerygh-5098
Ref jquerygh-5107
Ref w3c/csswg-drafts#7676
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-5206
Ref gh-5098
Ref gh-5107
Ref w3c/csswg-drafts#7676

Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
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
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.

Selector :contains within :has seems broken on Chrome
2 participants