LibWeb/CSS: Parse @page selectors

Ideally we'd be able to share the code between page selectors and style
ones, but given how simple page selectors are, some code duplication is
the simpler option.
This commit is contained in:
Sam Atkins 2025-05-13 13:05:08 +01:00
commit 1aa5631610
Notes: github-actions[bot] 2025-05-15 08:54:44 +00:00
6 changed files with 163 additions and 27 deletions

View file

@ -15,12 +15,56 @@ namespace Web::CSS {
GC_DEFINE_ALLOCATOR(CSSPageRule);
GC::Ref<CSSPageRule> CSSPageRule::create(JS::Realm& realm, SelectorList&& selectors, GC::Ref<CSSPageDescriptors> style, CSSRuleList& rules)
Optional<PagePseudoClass> page_pseudo_class_from_string(StringView input)
{
if (input.equals_ignoring_ascii_case("blank"sv))
return PagePseudoClass::Blank;
if (input.equals_ignoring_ascii_case("first"sv))
return PagePseudoClass::First;
if (input.equals_ignoring_ascii_case("left"sv))
return PagePseudoClass::Left;
if (input.equals_ignoring_ascii_case("right"sv))
return PagePseudoClass::Right;
return {};
}
StringView to_string(PagePseudoClass pseudo_class)
{
switch (pseudo_class) {
case PagePseudoClass::Blank:
return "blank"sv;
case PagePseudoClass::First:
return "first"sv;
case PagePseudoClass::Left:
return "left"sv;
case PagePseudoClass::Right:
return "right"sv;
}
VERIFY_NOT_REACHED();
}
PageSelector::PageSelector(Optional<FlyString> name, Vector<PagePseudoClass> pseudo_classes)
: m_name(move(name))
, m_pseudo_classes(move(pseudo_classes))
{
}
String PageSelector::serialize() const
{
StringBuilder builder;
if (m_name.has_value())
builder.append(m_name.value());
for (auto pseudo_class : m_pseudo_classes)
builder.appendff(":{}", to_string(pseudo_class));
return builder.to_string_without_validation();
}
GC::Ref<CSSPageRule> CSSPageRule::create(JS::Realm& realm, PageSelectorList&& selectors, GC::Ref<CSSPageDescriptors> style, CSSRuleList& rules)
{
return realm.create<CSSPageRule>(realm, move(selectors), style, rules);
}
CSSPageRule::CSSPageRule(JS::Realm& realm, SelectorList&& selectors, GC::Ref<CSSPageDescriptors> style, CSSRuleList& rules)
CSSPageRule::CSSPageRule(JS::Realm& realm, PageSelectorList&& selectors, GC::Ref<CSSPageDescriptors> style, CSSRuleList& rules)
: CSSGroupingRule(realm, rules, Type::Page)
, m_selectors(move(selectors))
, m_style(style)
@ -38,7 +82,10 @@ void CSSPageRule::initialize(JS::Realm& realm)
String CSSPageRule::selector_text() const
{
// The selectorText attribute, on getting, must return the result of serializing the associated selector list.
return serialize_a_group_of_selectors(m_selectors);
// https://www.w3.org/TR/cssom/#serialize-a-group-of-selectors
// To serialize a group of selectors serialize each selector in the group of selectors and then serialize a comma-separated list of these serializations.
return MUST(String::join(", "sv, m_selectors));
}
// https://drafts.csswg.org/cssom/#dom-csspagerule-selectortext