jquery / sizzle

A sizzlin' hot selector engine.
https://sizzlejs.com
Other
6.29k stars 951 forks source link

Selector: Make selector lists work with `qSA` again #491

Closed mgol closed 1 year ago

mgol commented 1 year ago

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