mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibWeb/CSS: Reject invalid :has() contents after absolutizing nesting
After we absolutize the contents of :has(), we check that those child selectors don't contain anything that :has() rejects. This is a separate path than the checks inside the parser, which is unfortunate. Fixes a WPT ref test. :^)
This commit is contained in:
parent
da31c10ce1
commit
3a71b8cda3
Notes:
github-actions[bot]
2024-11-14 19:08:17 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/3a71b8cda36 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2340
2 changed files with 38 additions and 1 deletions
|
@ -624,6 +624,33 @@ Optional<Selector::CompoundSelector> Selector::CompoundSelector::absolutized(Sel
|
|||
};
|
||||
}
|
||||
|
||||
static bool contains_invalid_contents_for_has(Selector const& selector)
|
||||
{
|
||||
// :has() has special validity rules:
|
||||
// - It can't appear inside itself
|
||||
// - It bans most pseudo-elements
|
||||
// https://drafts.csswg.org/selectors/#relational
|
||||
|
||||
for (auto const& compound_selector : selector.compound_selectors()) {
|
||||
for (auto const& simple_selector : compound_selector.simple_selectors) {
|
||||
if (simple_selector.type == Selector::SimpleSelector::Type::PseudoElement) {
|
||||
if (!is_has_allowed_pseudo_element(simple_selector.pseudo_element().type()))
|
||||
return true;
|
||||
}
|
||||
if (simple_selector.type == Selector::SimpleSelector::Type::PseudoClass) {
|
||||
if (simple_selector.pseudo_class().type == PseudoClass::Has)
|
||||
return true;
|
||||
for (auto& child_selector : simple_selector.pseudo_class().argument_selector_list) {
|
||||
if (contains_invalid_contents_for_has(*child_selector))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<Selector::SimpleSelector> Selector::SimpleSelector::absolutized(Selector::SimpleSelector const& selector_for_nesting) const
|
||||
{
|
||||
switch (type) {
|
||||
|
@ -647,6 +674,17 @@ Optional<Selector::SimpleSelector> Selector::SimpleSelector::absolutized(Selecto
|
|||
}
|
||||
pseudo_class.argument_selector_list = move(new_selector_list);
|
||||
}
|
||||
|
||||
// :has() has special validity rules
|
||||
if (pseudo_class.type == PseudoClass::Has) {
|
||||
for (auto const& selector : pseudo_class.argument_selector_list) {
|
||||
if (contains_invalid_contents_for_has(selector)) {
|
||||
dbgln_if(CSS_PARSER_DEBUG, "After absolutizing, :has() would contain invalid contents; rejecting");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SimpleSelector {
|
||||
.type = Type::PseudoClass,
|
||||
.value = move(pseudo_class),
|
||||
|
|
|
@ -59,7 +59,6 @@ Text/input/wpt-import/html/infrastructure/safe-passing-of-structured-data/resour
|
|||
Text/input/wpt-import/css/css-flexbox/flex-item-compressible-001.html
|
||||
|
||||
; WPT ref-tests that currently fail
|
||||
Ref/input/wpt-import/css/css-nesting/has-nesting.html
|
||||
Ref/input/wpt-import/css/css-nesting/host-nesting-003.html
|
||||
Ref/input/wpt-import/css/css-nesting/host-nesting-004.html
|
||||
Ref/input/wpt-import/css/CSS2/floats/floats-wrap-top-below-bfc-002r.xht
|
||||
|
|
Loading…
Reference in a new issue