[selectors] May new pseudos using forgiving parsing be introduced in the future? #8378
Labels
Closed as Question Answered
Used when the issue is more of a question than a problem, and it's been answered.
selectors-4
Current Work
In #7676, I reported the forgiving nature of
:has()
to be breaking jQuery. tl;dr is jQuery uses try-catch on some version of the selector passed toqSA
and does its own traversal when it throws as a fallback. With the help of some support tests, a regex is constructed that identifies buggy selectors which don't get passed throughqSA
at all and go straight to the jQuery traversal.:has()
has been since made non-forgiving but during the discussion it was suggested that jQuery shouldn't rely on try-catch as some selectors may be forgiving and the fact there's no error thrown doesn't mean the selector works natively. We were directed to useCSS.supports( "selector(...)" )
which was made always non-forgiving1, the spec change that only made it to Firefox stable so far. jQuery 3.6.2 implemented this change in browsers with spec-compliantCSS.supports( "selector(...)" )
(i.e., currently just Firefox). jQuery 3.6.3 changed that toCSS.supports( "selector(:is(...))" )
as bareselector(...)
doesn't support selector lists which jQuery accepts as input.However, we didn't take into account that those two approaches differ and
qSA
is way more forgiving thanCSS.supports( "selector(...)" )
, even beyond:is()
&:where()
. For example, nativeqSA( ":before" )
returns 0 results but does not throw whileCSS.supports( "selector(:is(:before))" )
isfalse
. The same for unterminated brackets:qSA( "[attr=val" )
works and returns valid results but bothCSS.supports( "selector(:is([attr=val))" )
andCSS.supports( "selector([attr=val)" )
arefalse
. We've already gotten multiple reports about these differences.Due to the above issues, we're considering reverting to the previous behavior and relying on
qSA
intry-catch
and just marking:has()
as buggy in all browsers where it's still forgiving (i.e. now both Chrome & Safari but that should change soon). However, we'd feel safer hearing some assurances that we won't hit a similar issue with other pseudos that we've just gone through with:has()
. The comment #7676 (comment) and the spec2 suggest the list is fixed and no future selectors will ever use forgiving parsing other than:is()
or:where()
but I wanted to double check. We'd only have problems if such a pseudo matched another one implemented by jQuery, i.e. roughly anything from Selectors Level 3 or any of the jQuery extensions like:contains()
or:eq()
.jQuery doesn't currently plan to implement
:is()
or:where()
in its custom traversal; if it one day does, it will be a complete rewrite of the selector module so this discussion will likely be irrelevant.Footnotes
https://w3c.github.io/csswg-drafts/css-conditional-4/#dfn-support-selector ↩
https://drafts.csswg.org/selectors/#forgiving-selector ↩
The text was updated successfully, but these errors were encountered: