mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 16:49:54 +00:00
LibWeb/CSS: Parse @page size
descriptor
This commit is contained in:
parent
d8c6b872a3
commit
9415bffd9b
Notes:
github-actions[bot]
2025-05-15 08:54:31 +00:00
Author: https://github.com/AtkinsSJ
Commit: 9415bffd9b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4735
6 changed files with 114 additions and 23 deletions
|
@ -137,6 +137,13 @@
|
||||||
"syntax": [
|
"syntax": [
|
||||||
"<'margin-top'>"
|
"<'margin-top'>"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"initial": "auto",
|
||||||
|
"FIXME": "Replace with actual syntax once we parse grammar properly",
|
||||||
|
"syntax": [
|
||||||
|
"<page-size>"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -481,6 +481,18 @@
|
||||||
"scroll",
|
"scroll",
|
||||||
"visible"
|
"visible"
|
||||||
],
|
],
|
||||||
|
"page-size": [
|
||||||
|
"a5",
|
||||||
|
"a4",
|
||||||
|
"a3",
|
||||||
|
"b5",
|
||||||
|
"b4",
|
||||||
|
"jis-b5",
|
||||||
|
"jis-b4",
|
||||||
|
"letter",
|
||||||
|
"legal",
|
||||||
|
"ledger"
|
||||||
|
],
|
||||||
"pointer-events": [
|
"pointer-events": [
|
||||||
"auto",
|
"auto",
|
||||||
"all",
|
"all",
|
||||||
|
|
|
@ -60,6 +60,9 @@
|
||||||
"-libweb-palette-window",
|
"-libweb-palette-window",
|
||||||
"-libweb-palette-window-text",
|
"-libweb-palette-window-text",
|
||||||
"-libweb-right",
|
"-libweb-right",
|
||||||
|
"a3",
|
||||||
|
"a4",
|
||||||
|
"a5",
|
||||||
"absolute",
|
"absolute",
|
||||||
"accentcolor",
|
"accentcolor",
|
||||||
"accentcolortext",
|
"accentcolortext",
|
||||||
|
@ -82,6 +85,8 @@
|
||||||
"appworkspace",
|
"appworkspace",
|
||||||
"auto",
|
"auto",
|
||||||
"auto-add",
|
"auto-add",
|
||||||
|
"b4",
|
||||||
|
"b5",
|
||||||
"back",
|
"back",
|
||||||
"background",
|
"background",
|
||||||
"backwards",
|
"backwards",
|
||||||
|
@ -120,8 +125,8 @@
|
||||||
"col-resize",
|
"col-resize",
|
||||||
"collapse",
|
"collapse",
|
||||||
"color",
|
"color",
|
||||||
"color-dodge",
|
|
||||||
"color-burn",
|
"color-burn",
|
||||||
|
"color-dodge",
|
||||||
"column",
|
"column",
|
||||||
"column-reverse",
|
"column-reverse",
|
||||||
"common-ligatures",
|
"common-ligatures",
|
||||||
|
@ -150,9 +155,9 @@
|
||||||
"diagonal-fractions",
|
"diagonal-fractions",
|
||||||
"difference",
|
"difference",
|
||||||
"disc",
|
"disc",
|
||||||
"discretionary-ligatures",
|
|
||||||
"disclosure-closed",
|
"disclosure-closed",
|
||||||
"disclosure-open",
|
"disclosure-open",
|
||||||
|
"discretionary-ligatures",
|
||||||
"distribute",
|
"distribute",
|
||||||
"dotted",
|
"dotted",
|
||||||
"double",
|
"double",
|
||||||
|
@ -243,6 +248,8 @@
|
||||||
"isolate",
|
"isolate",
|
||||||
"isolate-override",
|
"isolate-override",
|
||||||
"italic",
|
"italic",
|
||||||
|
"jis-b4",
|
||||||
|
"jis-b5",
|
||||||
"jis04",
|
"jis04",
|
||||||
"jis78",
|
"jis78",
|
||||||
"jis83",
|
"jis83",
|
||||||
|
@ -258,12 +265,15 @@
|
||||||
"larger",
|
"larger",
|
||||||
"layout",
|
"layout",
|
||||||
"lch",
|
"lch",
|
||||||
|
"ledger",
|
||||||
"left",
|
"left",
|
||||||
"legacy",
|
"legacy",
|
||||||
|
"legal",
|
||||||
"less",
|
"less",
|
||||||
|
"letter",
|
||||||
"light",
|
"light",
|
||||||
"lighter",
|
|
||||||
"lighten",
|
"lighten",
|
||||||
|
"lighter",
|
||||||
"line-through",
|
"line-through",
|
||||||
"linear",
|
"linear",
|
||||||
"lining-nums",
|
"lining-nums",
|
||||||
|
@ -469,12 +479,12 @@
|
||||||
"textfield",
|
"textfield",
|
||||||
"thick",
|
"thick",
|
||||||
"thin",
|
"thin",
|
||||||
"titling-caps",
|
|
||||||
"threeddarkshadow",
|
"threeddarkshadow",
|
||||||
"threedface",
|
"threedface",
|
||||||
"threedhighlight",
|
"threedhighlight",
|
||||||
"threedlightshadow",
|
"threedlightshadow",
|
||||||
"threedshadow",
|
"threedshadow",
|
||||||
|
"titling-caps",
|
||||||
"to-zero",
|
"to-zero",
|
||||||
"top",
|
"top",
|
||||||
"traditional",
|
"traditional",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
#include <LibWeb/CSS/StyleValues/CSSKeywordValue.h>
|
#include <LibWeb/CSS/StyleValues/CSSKeywordValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/FontSourceStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/FontSourceStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
|
@ -83,12 +84,69 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_descripto
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return StyleValueList::create(move(valid_sources), StyleValueList::Separator::Comma);
|
return StyleValueList::create(move(valid_sources), StyleValueList::Separator::Comma);
|
||||||
}
|
}
|
||||||
case DescriptorMetadata::ValueType::OptionalDeclarationValue:
|
case DescriptorMetadata::ValueType::OptionalDeclarationValue: {
|
||||||
// `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them.
|
// `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them.
|
||||||
while (tokens.has_next_token())
|
while (tokens.has_next_token())
|
||||||
tokens.discard_a_token();
|
tokens.discard_a_token();
|
||||||
return UnresolvedStyleValue::create(move(component_values), false, {});
|
return UnresolvedStyleValue::create(move(component_values), false, {});
|
||||||
case DescriptorMetadata::ValueType::PositivePercentage:
|
}
|
||||||
|
case DescriptorMetadata::ValueType::PageSize: {
|
||||||
|
// https://drafts.csswg.org/css-page-3/#page-size-prop
|
||||||
|
// <length [0,∞]>{1,2} | auto | [ <page-size> || [ portrait | landscape ] ]
|
||||||
|
|
||||||
|
// auto
|
||||||
|
if (auto value = parse_all_as_single_keyword_value(tokens, Keyword::Auto))
|
||||||
|
return value.release_nonnull();
|
||||||
|
|
||||||
|
// <length [0,∞]>{1,2}
|
||||||
|
if (auto first_length = parse_length_value(tokens)) {
|
||||||
|
if (first_length->is_length() && first_length->as_length().length().raw_value() < 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (auto second_length = parse_length_value(tokens)) {
|
||||||
|
if (second_length->is_length() && second_length->as_length().length().raw_value() < 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return StyleValueList::create(StyleValueVector { first_length.release_nonnull(), second_length.release_nonnull() }, StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return first_length.release_nonnull();
|
||||||
|
}
|
||||||
|
|
||||||
|
// [ <page-size> || [ portrait | landscape ] ]
|
||||||
|
RefPtr<CSSStyleValue const> page_size;
|
||||||
|
RefPtr<CSSStyleValue const> orientation;
|
||||||
|
if (auto first_keyword = parse_keyword_value(tokens)) {
|
||||||
|
if (first_is_one_of(first_keyword->to_keyword(), Keyword::Landscape, Keyword::Portrait)) {
|
||||||
|
orientation = first_keyword.release_nonnull();
|
||||||
|
} else if (keyword_to_page_size(first_keyword->to_keyword()).has_value()) {
|
||||||
|
page_size = first_keyword.release_nonnull();
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto second_keyword = parse_keyword_value(tokens)) {
|
||||||
|
if (orientation.is_null() && first_is_one_of(second_keyword->to_keyword(), Keyword::Landscape, Keyword::Portrait)) {
|
||||||
|
orientation = second_keyword.release_nonnull();
|
||||||
|
} else if (page_size.is_null() && keyword_to_page_size(second_keyword->to_keyword()).has_value()) {
|
||||||
|
page_size = second_keyword.release_nonnull();
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Portrait is considered the default orientation, so don't include it.
|
||||||
|
if (orientation->to_keyword() == Keyword::Portrait)
|
||||||
|
return page_size.release_nonnull();
|
||||||
|
|
||||||
|
return StyleValueList::create(StyleValueVector { page_size.release_nonnull(), orientation.release_nonnull() }, StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
|
return page_size ? page_size.release_nonnull() : orientation.release_nonnull();
|
||||||
|
}
|
||||||
|
case DescriptorMetadata::ValueType::PositivePercentage: {
|
||||||
if (auto percentage_value = parse_percentage_value(tokens)) {
|
if (auto percentage_value = parse_percentage_value(tokens)) {
|
||||||
if (percentage_value->is_percentage()) {
|
if (percentage_value->is_percentage()) {
|
||||||
if (percentage_value->as_percentage().value() < 0)
|
if (percentage_value->as_percentage().value() < 0)
|
||||||
|
@ -104,13 +162,15 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_descripto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
case DescriptorMetadata::ValueType::String:
|
case DescriptorMetadata::ValueType::String:
|
||||||
return parse_string_value(tokens);
|
return parse_string_value(tokens);
|
||||||
case DescriptorMetadata::ValueType::UnicodeRangeTokens:
|
case DescriptorMetadata::ValueType::UnicodeRangeTokens: {
|
||||||
return parse_comma_separated_value_list(tokens, [this](auto& tokens) -> RefPtr<CSSStyleValue const> {
|
return parse_comma_separated_value_list(tokens, [this](auto& tokens) -> RefPtr<CSSStyleValue const> {
|
||||||
return parse_unicode_range_value(tokens);
|
return parse_unicode_range_value(tokens);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
if (!parsed_style_value || tokens.has_next_token())
|
if (!parsed_style_value || tokens.has_next_token())
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct DescriptorMetadata {
|
||||||
FamilyName,
|
FamilyName,
|
||||||
FontSrcList,
|
FontSrcList,
|
||||||
OptionalDeclarationValue,
|
OptionalDeclarationValue,
|
||||||
|
PageSize,
|
||||||
PositivePercentage,
|
PositivePercentage,
|
||||||
String,
|
String,
|
||||||
UnicodeRangeTokens,
|
UnicodeRangeTokens,
|
||||||
|
@ -386,6 +387,8 @@ DescriptorMetadata get_descriptor_metadata(AtRuleID at_rule_id, DescriptorID des
|
||||||
return "FontSrcList"_string;
|
return "FontSrcList"_string;
|
||||||
if (syntax_string == "<declaration-value>?"sv)
|
if (syntax_string == "<declaration-value>?"sv)
|
||||||
return "OptionalDeclarationValue"_string;
|
return "OptionalDeclarationValue"_string;
|
||||||
|
if (syntax_string == "<page-size>"sv)
|
||||||
|
return "PageSize"_string;
|
||||||
if (syntax_string == "<percentage [0,∞]>"sv)
|
if (syntax_string == "<percentage [0,∞]>"sv)
|
||||||
return "PositivePercentage"_string;
|
return "PositivePercentage"_string;
|
||||||
if (syntax_string == "<string>"sv)
|
if (syntax_string == "<string>"sv)
|
||||||
|
|
|
@ -2,20 +2,19 @@ Harness status: OK
|
||||||
|
|
||||||
Found 15 tests
|
Found 15 tests
|
||||||
|
|
||||||
1 Pass
|
15 Pass
|
||||||
14 Fail
|
|
||||||
Pass Test setup
|
Pass Test setup
|
||||||
Fail size: 640px 480px
|
Pass size: 640px 480px
|
||||||
Fail size: 8.5in 11in
|
Pass size: 8.5in 11in
|
||||||
Fail size: 3in 10in
|
Pass size: 3in 10in
|
||||||
Fail size: auto
|
Pass size: auto
|
||||||
Fail size: a5
|
Pass size: a5
|
||||||
Fail size: a4
|
Pass size: a4
|
||||||
Fail size: a3
|
Pass size: a3
|
||||||
Fail size: b5
|
Pass size: b5
|
||||||
Fail size: b4
|
Pass size: b4
|
||||||
Fail size: jis-b5
|
Pass size: jis-b5
|
||||||
Fail size: jis-b4
|
Pass size: jis-b4
|
||||||
Fail size: landscape
|
Pass size: landscape
|
||||||
Fail size: letter
|
Pass size: letter
|
||||||
Fail size: legal landscape
|
Pass size: legal landscape
|
Loading…
Add table
Add a link
Reference in a new issue