LibWeb/CSS: Parse @page bleed, marks, page-orientation descriptors

These don't have WPT tests so I've added some myself.
This commit is contained in:
Sam Atkins 2025-05-14 16:05:53 +01:00
commit 3a235e9050
Notes: github-actions[bot] 2025-05-15 08:54:25 +00:00
10 changed files with 190 additions and 1 deletions

View file

@ -108,6 +108,13 @@
"spec": "https://drafts.csswg.org/css-page-3/#at-page-rule",
"FIXME": "There are a lot more properties that are valid, see https://drafts.csswg.org/css-page-3/#properties-list",
"descriptors": {
"bleed": {
"initial": "auto",
"syntax": [
"auto",
"<length>"
]
},
"margin": {
"initial": "0",
"syntax": [
@ -138,6 +145,21 @@
"<'margin-top'>"
]
},
"marks": {
"initial": "none",
"syntax": [
"none",
"crop || cross"
]
},
"page-orientation": {
"initial": "upright",
"syntax": [
"upright",
"rotate-left",
"rotate-right"
]
},
"size": {
"initial": "auto",
"FIXME": "Replace with actual syntax once we parse grammar properly",

View file

@ -141,6 +141,8 @@
"copy",
"cover",
"crisp-edges",
"crop",
"cross",
"crosshair",
"currentcolor",
"cursive",
@ -391,6 +393,8 @@
"revert-layer",
"ridge",
"right",
"rotate-left",
"rotate-right",
"round",
"row",
"row-resize",
@ -506,6 +510,7 @@
"upper-latin",
"upper-roman",
"uppercase",
"upright",
"use-credentials",
"vertical-lr",
"vertical-rl",

View file

@ -61,6 +61,36 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_descripto
},
[&](DescriptorMetadata::ValueType value_type) -> RefPtr<CSSStyleValue const> {
switch (value_type) {
case DescriptorMetadata::ValueType::CropOrCross: {
// crop || cross
auto first = parse_keyword_value(tokens);
auto second = parse_keyword_value(tokens);
if (!first)
return nullptr;
RefPtr<CSSStyleValue const> crop;
RefPtr<CSSStyleValue const> cross;
if (first->to_keyword() == Keyword::Crop)
crop = first;
else if (first->to_keyword() == Keyword::Cross)
cross = first;
else
return nullptr;
if (!second)
return first.release_nonnull();
if (crop.is_null() && second->to_keyword() == Keyword::Crop)
crop = second.release_nonnull();
else if (cross.is_null() && second->to_keyword() == Keyword::Cross)
cross = second.release_nonnull();
else
return nullptr;
return StyleValueList::create(StyleValueVector { crop.release_nonnull(), cross.release_nonnull() }, StyleValueList::Separator::Space);
}
case DescriptorMetadata::ValueType::FamilyName:
return parse_family_name_value(tokens);
case DescriptorMetadata::ValueType::FontSrcList: {
@ -84,6 +114,8 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_descripto
return nullptr;
return StyleValueList::create(move(valid_sources), StyleValueList::Separator::Comma);
}
case DescriptorMetadata::ValueType::Length:
return parse_length_value(tokens);
case DescriptorMetadata::ValueType::OptionalDeclarationValue: {
// `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them.
while (tokens.has_next_token())