-
Notifications
You must be signed in to change notification settings - Fork 24
Implement :matches() #48
Comments
@SimonSapin First way is not possible, we have the same problem with selector lists, where only the greatest specificity of the selectors that matched count. Second way is inefficient, we should actually have an pub enum MaybePartiallyComputedSpecificity {
Exact { value: u32 }
Partial { bounds: Range<Specificity>, token: ??? }
} The token would be used to continue the computing of the partial specificity at a better place in the selector list than from the beginning again. |
Relevant quote from the spec about selector lists (emphasis mine):
|
How so?
We deal with this by not considering selector lists as units, but only the individual selectors they contain. This loop creates a We can expand
How so? I don’t understand what |
Didn't I reply to you on IRC already yesterday? :) For the first part of your reply, I didn't know that selector lists were expanded into individual selectors. Doesn't that mean you have to check whether all of them check, for the specificity? Why would you want to do that if your selector list is The token would remember that |
That’s an interesting optimization we could do, but I think it’s orthogonal to how |
I'm back on this. |
Relevant spec: https://drafts.csswg.org/selectors-4/#matches
What makes this non-trivial is the handling of specificity: https://drafts.csswg.org/selectors-4/#specificity-rules
For example,
div :matches(.foo, #bar)
is equivalentdiv .foo, div #bar
. The latter is a selector list that contains two selectors. (See terminology.) In Selectors level 3, selectors have an intrinsic specificity (here(0, 1, 1)
and(1, 0, 1)
, respectively) but selector lists don’t. This is a consequence of the principle that these two bits of CSS are equivalent:Going back to
div :matches(.foo, #bar)
, preserving the equivalence means that, in Selectors level 4, the specificity is not intrinsic to (all) selectors anymore: the specificity of:matches()
depends on which of its arguments actually matches for a given element.I know of two ways to implement this:
Expand at parse time a selector list that contains
:matches()
to the equivalent, longer selector list that doesn’t. This works without changing much code, but it cause a combinatorial explosion of the size of selectors with more than one:matches()
pseudo-class. For example (from the user-agent stylesheet)… this expands to 64 alternatives. The run-time cost of matching this may be prohibitive
Change our matching code so that specificity is not determined at parse-time but is a result of matching. (A return value of
Option<Specificity>
instead ofbool
for a given(element, selector)
set of arguments.) This might make more difficult plans to JIT-compile selectors or match them on the GPUCC @pcwalton, @nox
The text was updated successfully, but these errors were encountered: