mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibWeb/CSS: Keep invalid parts of <forgiving-selector-list>
s around
Attempt 2! Reverts 2a5dbedad4
This time, set up a different combinator when producing a relative
invalid selector rather than a standalone one. This fixes the crash.
Original description below for simplicity because it still applies.
---
Selectors like `:is(.valid, &!?!?!invalid)` need to keep the invalid
part around, even though it will never match, for a couple of reasons:
- Serialization needs to include them
- For nesting, we care if a `&` appeared anywhere in the selector, even
in an invalid part.
So this patch introduces an `Invalid` simple selector type, which simply
holds its original ComponentValues. We search through these looking for
`&`, and we dump them out directly when asked to serialize.
This commit is contained in:
parent
329cd946ac
commit
5a1eb9e220
Notes:
github-actions[bot]
2024-11-14 12:20:58 +00:00
Author: https://github.com/AtkinsSJ
Commit: 5a1eb9e220
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2335
8 changed files with 111 additions and 3 deletions
|
@ -11,6 +11,28 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
static bool component_value_contains_nesting_selector(Parser::ComponentValue const& component_value)
|
||||
{
|
||||
if (component_value.is_delim('&'))
|
||||
return true;
|
||||
|
||||
if (component_value.is_block()) {
|
||||
for (auto const& child_value : component_value.block().value) {
|
||||
if (component_value_contains_nesting_selector(child_value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (component_value.is_function()) {
|
||||
for (auto const& child_value : component_value.function().value) {
|
||||
if (component_value_contains_nesting_selector(child_value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Selector::Selector(Vector<CompoundSelector>&& compound_selectors)
|
||||
: m_compound_selectors(move(compound_selectors))
|
||||
{
|
||||
|
@ -44,6 +66,17 @@ Selector::Selector(Vector<CompoundSelector>&& compound_selectors)
|
|||
if (m_contains_the_nesting_selector)
|
||||
break;
|
||||
}
|
||||
if (simple_selector.type == SimpleSelector::Type::Invalid) {
|
||||
auto& invalid = simple_selector.value.get<SimpleSelector::Invalid>();
|
||||
for (auto& item : invalid.component_values) {
|
||||
if (component_value_contains_nesting_selector(item)) {
|
||||
m_contains_the_nesting_selector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_contains_the_nesting_selector)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_contains_the_nesting_selector)
|
||||
break;
|
||||
|
@ -184,6 +217,9 @@ u32 Selector::specificity() const
|
|||
// The parented case is handled by replacing & with :is().
|
||||
// So if we got here, the specificity is 0.
|
||||
break;
|
||||
case SimpleSelector::Type::Invalid:
|
||||
// Ignore invalid selectors
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,6 +396,12 @@ String Selector::SimpleSelector::serialize() const
|
|||
// AD-HOC: Not in spec yet.
|
||||
s.append('&');
|
||||
break;
|
||||
case Type::Invalid:
|
||||
// AD-HOC: We're not told how to do these. Just serialize their component values.
|
||||
auto invalid = value.get<Invalid>();
|
||||
for (auto const& component_value : invalid.component_values)
|
||||
s.append(component_value.to_string());
|
||||
break;
|
||||
}
|
||||
return MUST(s.to_string());
|
||||
}
|
||||
|
@ -602,6 +644,7 @@ Selector::SimpleSelector Selector::SimpleSelector::absolutized(Selector::SimpleS
|
|||
case Type::Class:
|
||||
case Type::Attribute:
|
||||
case Type::PseudoElement:
|
||||
case Type::Invalid:
|
||||
// Everything else isn't affected
|
||||
return *this;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue