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

@ -8,17 +8,39 @@
#include <LibWeb/CSS/CSSGroupingRule.h>
#include <LibWeb/CSS/CSSPageDescriptors.h>
#include <LibWeb/CSS/Selector.h>
namespace Web::CSS {
enum class PagePseudoClass : u8 {
Left,
Right,
First,
Blank,
};
Optional<PagePseudoClass> page_pseudo_class_from_string(StringView);
StringView to_string(PagePseudoClass);
class PageSelector {
public:
PageSelector(Optional<FlyString> name, Vector<PagePseudoClass>);
Optional<FlyString> name() const { return m_name; }
Vector<PagePseudoClass> const& pseudo_classes() const { return m_pseudo_classes; }
String serialize() const;
private:
Optional<FlyString> m_name;
Vector<PagePseudoClass> m_pseudo_classes;
};
using PageSelectorList = Vector<PageSelector>;
// https://drafts.csswg.org/css-page-3/#at-ruledef-page
class CSSPageRule final : public CSSGroupingRule {
WEB_PLATFORM_OBJECT(CSSPageRule, CSSGroupingRule);
GC_DECLARE_ALLOCATOR(CSSPageRule);
public:
[[nodiscard]] static GC::Ref<CSSPageRule> create(JS::Realm&, SelectorList&&, GC::Ref<CSSPageDescriptors>, CSSRuleList&);
[[nodiscard]] static GC::Ref<CSSPageRule> create(JS::Realm&, PageSelectorList&&, GC::Ref<CSSPageDescriptors>, CSSRuleList&);
virtual ~CSSPageRule() override = default;
@ -29,14 +51,26 @@ public:
GC::Ref<CSSPageDescriptors const> descriptors() const { return m_style; }
private:
CSSPageRule(JS::Realm&, SelectorList&&, GC::Ref<CSSPageDescriptors>, CSSRuleList&);
CSSPageRule(JS::Realm&, PageSelectorList&&, GC::Ref<CSSPageDescriptors>, CSSRuleList&);
virtual void initialize(JS::Realm&) override;
virtual String serialized() const override;
virtual void visit_edges(Visitor&) override;
SelectorList m_selectors;
PageSelectorList m_selectors;
GC::Ref<CSSPageDescriptors> m_style;
};
}
namespace AK {
template<>
struct Formatter<Web::CSS::PageSelector> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, Web::CSS::PageSelector const& selector)
{
return Formatter<StringView>::format(builder, selector.serialize());
}
};
}