We can have combinator sequences like [>, <part>], and they are fine.
Add a test to make sure they're handled correctly.
Differential Revision: https://phabricator.services.mozilla.com/D208668
Would generate invalid results `:has()` selector if it's in the subject
compound but also uses a pseudo-selector (e.g. `.foo:has(.bar)::after`).
Also rename `Rightmost` to `SubjectOrPseudoElement` to more accurately
describe what it indicates.
Differential Revision: https://phabricator.services.mozilla.com/D200222
For now, do the same as pseudo-elements, which is effectively to keep
them in the replaced selector but don't match them. Avoid crashing in
this case.
I filed https://github.com/w3c/csswg-drafts/issues/9600 since this issue
isn't specific about :has(), and depending on the result of that
discussion, the "proper" solution might be different.
Differential Revision: https://phabricator.services.mozilla.com/D193663
There are cases where we can run a selector match to realize that some DOM mutations
will not make a difference in the relative selector match state, which avoids
O(n^2) behaviour under some circumstances.
Differential Revision: https://phabricator.services.mozilla.com/D191307
We have ArcSelectorList for selector-lists that are cheap to copy.
For bug 1859915 and related, what we're going to end up doing is probably
expanding into the SelectorList of the parent rule unconditionally, at least
for the "single bare &" case.
It'd be nice to unify SelectorList implementations as preparation for that, and
make them cheaper to clone in general.
My proposal is making SelectorList a tagged pointer to either a single
selector, or to a ThinArc, effectively preserving the SmallVec<> optimization
we have now. This patch implements that proposal.
Depends on D191361
Differential Revision: https://phabricator.services.mozilla.com/D191362
We need to jump to an element in the correct scope just like ::slotted()
does.
Factor that code to its own function both so that it's easier to reason
about and so that the code for that function remains small. At the end
of the day other combinators like descendant or sibling get executed a
ton of times (while pseudo-elements only jump once).
Differential Revision: https://phabricator.services.mozilla.com/D189478
This undoes bug 1835681, adjusting for changes that happened since then,
because the crates don't build with the real bitflags 2, and there are
some challenges to make them work with the real bitflags 2.
Differential Revision: https://phabricator.services.mozilla.com/D187748
The idea is to share more memory when expanding nested rules (so being
able to share the whole :is() / :where() allocation), and same for the
Dependency computation (basically, share it across all descendant
selectors).
This prevents exponential explosion in cases like the one in bug 1844446
if you replace tag selectors by class selectors (so that we build
invalidation maps for them).
Differential Revision: https://phabricator.services.mozilla.com/D184283
The idea is to share more memory when expanding nested rules (so being
able to share the whole :is() / :where() allocation), and same for the
Dependency computation (basically, share it across all descendant
selectors).
This prevents exponential explosion in cases like the one in bug 1844446
if you replace tag selectors by class selectors (so that we build
invalidation maps for them).
Differential Revision: https://phabricator.services.mozilla.com/D184283
This simple relative selector cache avoids O(n^2) behaviour when the relative
selector is not in the subject position. e.g. `.anchor:has(.a) ~ .subject`,
with a DOM tree .anchor + .subject + .. + .subject.
Differential Revision: https://phabricator.services.mozilla.com/D184373
Previous code actually could not distinguish when `:has()` is on the rightmost
side or not. This caused every candidate containing any `:has()` selector to be
outright refused from being inserted into style sharing cache.
Differential Revision: https://phabricator.services.mozilla.com/D183405
This improves the testcase in bug 1837673, because it means that we only
check attributes once. Before this patch, we would check them twice: First,
the SimpleFilter path would check for the presence of the attribute, and then
later we would enumerate attributes again to check the attribute value.
Now we don't use the SimpleFilter path anymore and go straight to attribute
enumeration.
Differential Revision: https://phabricator.services.mozilla.com/D181349
The idea is to make the function small enough that it's fast to inline and
optimize by the compiler. For that:
* Move some complex bits of matches_simple_selector into functions so
that the compiler can put them out of line if it wants.
* Rename a function to be more descriptive and not force it to be
inline (that wasn't measured afaict, comes from the :nth-child(of)
implementation).
Depends on D180591
Differential Revision: https://phabricator.services.mozilla.com/D180592
For any element that anchors a `:has()` selector (i.e. Matches a selector that
contains a `:has()` on its rightmost side), we prevent style sharing altogether,
as evaluation of the `:has()` selector is required in the first place to
determine style sharing.
On the other hand, any element matching a rule containing `:has()` without
anchoring it can do style sharing for siblings, but not cousins.
Differential Revision: https://phabricator.services.mozilla.com/D176836
If this happens again, it might be worth not matching rather than
potentially crashing. Though I guess crashing is a very good way getting
it reported soon...
Differential Revision: https://phabricator.services.mozilla.com/D178921
There are separate filters for IDs, classes, attribute local names, and
element state.
Also, we invalidate siblings of elements matched against the selector
list of :nth-child(... of <selector list>) by marking matched elements
with NODE_HAS_SLOW_SELECTOR_NTH_OF.
The only remaining invalidation case invalidation case is
`:nth-child(An+B of :has())` (bug 1818155), which should not block
shipping `layout.css.nth-child-of.enabled`, because :has(...) is still
being implemented (bug 418039).
Depends on D172352
Differential Revision: https://phabricator.services.mozilla.com/D171936
This parses the ampersand as a parent selector behind an
(off-by-default) selectors feature.
The plan is to call replace_parent_selector while we're doing the
CascadeData rebuilds, which is where we can have all the ancestor
nesting information.
No behavior change.
Differential Revision: https://phabricator.services.mozilla.com/D167237