diff --git a/Libraries/LibWeb/CSS/Descriptors.json b/Libraries/LibWeb/CSS/Descriptors.json index 8d6d8432c4b..e9ad81d3dfb 100644 --- a/Libraries/LibWeb/CSS/Descriptors.json +++ b/Libraries/LibWeb/CSS/Descriptors.json @@ -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", + "" + ] + }, "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", diff --git a/Libraries/LibWeb/CSS/Keywords.json b/Libraries/LibWeb/CSS/Keywords.json index a5ca8b0aee2..abd75df14cf 100644 --- a/Libraries/LibWeb/CSS/Keywords.json +++ b/Libraries/LibWeb/CSS/Keywords.json @@ -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", diff --git a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp index 661161899b5..199e39d19ee 100644 --- a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp @@ -61,6 +61,36 @@ Parser::ParseErrorOr> Parser::parse_descripto }, [&](DescriptorMetadata::ValueType value_type) -> RefPtr { 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 crop; + RefPtr 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> 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()) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSDescriptors.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSDescriptors.cpp index 3840c9a3aac..e6c84f531f8 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSDescriptors.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSDescriptors.cpp @@ -118,8 +118,10 @@ RefPtr descriptor_initial_value(AtRuleID, DescriptorID); struct DescriptorMetadata { enum class ValueType { // FIXME: Parse the grammar instead of hard-coding all the options! + CropOrCross, FamilyName, FontSrcList, + Length, OptionalDeclarationValue, PageSize, PositivePercentage, @@ -387,6 +389,8 @@ DescriptorMetadata get_descriptor_metadata(AtRuleID at_rule_id, DescriptorID des return "FontSrcList"_string; if (syntax_string == "?"sv) return "OptionalDeclarationValue"_string; + if (syntax_string == ""sv) + return "Length"_string; if (syntax_string == ""sv) return "PageSize"_string; if (syntax_string == ""sv) @@ -395,13 +399,18 @@ DescriptorMetadata get_descriptor_metadata(AtRuleID at_rule_id, DescriptorID des return "String"_string; if (syntax_string == "#"sv) return "UnicodeRangeTokens"_string; + dbgln("Unrecognized value type: `{}`", syntax_string); VERIFY_NOT_REACHED(); }(); option_generator.set("value_type"sv, value_type); option_generator.append(R"~~~( metadata.syntax.empend(DescriptorMetadata::ValueType::@value_type@); )~~~"); - + } else if (syntax_string == "crop || cross"sv) { + // FIXME: This is extra hacky. + option_generator.append(R"~~~( + metadata.syntax.empend(DescriptorMetadata::ValueType::CropOrCross); +)~~~"); } else { // Keyword option_generator.set("keyword:titlecase"sv, title_casify(syntax_string)); diff --git a/Tests/LibWeb/Text/expected/css/page-bleed.txt b/Tests/LibWeb/Text/expected/css/page-bleed.txt new file mode 100644 index 00000000000..0b9fe76493a --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/page-bleed.txt @@ -0,0 +1,8 @@ +"bleed: auto": parsed as "auto" +"bleed: 1in": parsed as "1in" +"bleed: -2cm": parsed as "-2cm" +"bleed: auto 1in": INVALID +"bleed: 3cm auto": INVALID +"bleed: 1cm 2cm": INVALID +"bleed: orange": INVALID +"bleed: none": INVALID diff --git a/Tests/LibWeb/Text/expected/css/page-marks.txt b/Tests/LibWeb/Text/expected/css/page-marks.txt new file mode 100644 index 00000000000..4d3263bba38 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/page-marks.txt @@ -0,0 +1,11 @@ +"marks: none": parsed as "none" +"marks: crop": parsed as "crop" +"marks: cross": parsed as "cross" +"marks: crop cross": parsed as "crop cross" +"marks: cross crop": parsed as "crop cross" +"marks: none crop": INVALID +"marks: crop crop": INVALID +"marks: cross cross": INVALID +"marks: cross crop cross": INVALID +"marks: orange": INVALID +"marks: auto": INVALID diff --git a/Tests/LibWeb/Text/expected/css/page-page-orientation.txt b/Tests/LibWeb/Text/expected/css/page-page-orientation.txt new file mode 100644 index 00000000000..06628e94a28 --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/page-page-orientation.txt @@ -0,0 +1,7 @@ +"page-orientation: upright": parsed as "upright" +"page-orientation: rotate-left": parsed as "rotate-left" +"page-orientation: rotate-right": parsed as "rotate-right" +"page-orientation: auto": INVALID +"page-orientation: none": INVALID +"page-orientation: rotate-left rotate-right": INVALID +"page-orientation: 90deg": INVALID diff --git a/Tests/LibWeb/Text/input/css/page-bleed.html b/Tests/LibWeb/Text/input/css/page-bleed.html new file mode 100644 index 00000000000..47d4a432712 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/page-bleed.html @@ -0,0 +1,31 @@ + + + + diff --git a/Tests/LibWeb/Text/input/css/page-marks.html b/Tests/LibWeb/Text/input/css/page-marks.html new file mode 100644 index 00000000000..73ec6be4e5c --- /dev/null +++ b/Tests/LibWeb/Text/input/css/page-marks.html @@ -0,0 +1,34 @@ + + + + diff --git a/Tests/LibWeb/Text/input/css/page-page-orientation.html b/Tests/LibWeb/Text/input/css/page-page-orientation.html new file mode 100644 index 00000000000..3a62f2a1636 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/page-page-orientation.html @@ -0,0 +1,30 @@ + + + +