[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 toqSAand 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 throughqSAat 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
qSAis 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
qSAintry-catchand 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: