From 0621ac861fa39185aac2e4493af17b2d764cb17f Mon Sep 17 00:00:00 2001 From: VAN BOSSUYT Nicolas Date: Sat, 9 Nov 2024 23:27:25 +0100 Subject: [PATCH] vaev-style: Add break properties. --- src/vaev-style/styles.h | 61 +++++++++++++++++++++++++++++++++++++++ src/vaev-style/values.cpp | 57 ++++++++++++++++++++++++++++++++++++ src/vaev-style/values.h | 11 +++++++ 3 files changed, 129 insertions(+) diff --git a/src/vaev-style/styles.h b/src/vaev-style/styles.h index 36ea8a1..7314fc4 100644 --- a/src/vaev-style/styles.h +++ b/src/vaev-style/styles.h @@ -983,6 +983,62 @@ struct BorderSpacingProp { } }; +// MARK: Breaks ---------------------------------------------------------------- + +// https://www.w3.org/TR/css-break-3/#propdef-break-after +struct BreakAfterProp { + BreakBetween value = initial(); + + static constexpr Str name() { return "break-after"; } + + static constexpr BreakBetween initial() { return BreakBetween::AUTO; } + + void apply(Computed &c) const { + c.break_.cow().after = value; + } + + Res<> parse(Cursor &c) { + value = try$(parseValue(c)); + return Ok(); + } +}; + +// https://www.w3.org/TR/css-break-3/#propdef-break-before +struct BreakBeforeProp { + BreakBetween value = initial(); + + static constexpr Str name() { return "break-before"; } + + static constexpr BreakBetween initial() { return BreakBetween::AUTO; } + + void apply(Computed &c) const { + c.break_.cow().before = value; + } + + Res<> parse(Cursor &c) { + value = try$(parseValue(c)); + return Ok(); + } +}; + +// https://www.w3.org/TR/css-break-3/#break-within +struct BreakInsideProp { + BreakInside value = initial(); + + static constexpr Str name() { return "break-inside"; } + + static constexpr BreakInside initial() { return BreakInside::AUTO; } + + void apply(Computed &c) const { + c.break_.cow().inside = value; + } + + Res<> parse(Cursor &c) { + value = try$(parseValue(c)); + return Ok(); + } +}; + // MARK: Flex ------------------------------------------------------------------ // https://www.w3.org/TR/css-flexbox-1/#flex-basis-property @@ -2216,6 +2272,11 @@ using _StyleProp = Union< BorderCollapseProp, BorderSpacingProp, + // Breaks + BreakAfterProp, + BreakBeforeProp, + BreakInsideProp, + // Flex FlexBasisProp, FlexDirectionProp, diff --git a/src/vaev-style/values.cpp b/src/vaev-style/values.cpp index 9dc2c84..6c4dde2 100644 --- a/src/vaev-style/values.cpp +++ b/src/vaev-style/values.cpp @@ -175,6 +175,63 @@ Res ValueParser::parse(Cursor &c) { return Error::invalidData("expected border spacing value"); } +// MARK: BreakAfter & BreakBefore +// https://www.w3.org/TR/css-break-3/#propdef-break-after +// https://www.w3.org/TR/css-break-3/#propdef-break-before +Res ValueParser::parse(Cursor &c) { + if (c.ended()) + return Error::invalidData("unexpected end of input"); + + if (c.skip(Css::Token::ident("auto"))) { + return Ok(BreakBetween::AUTO); + } else if (c.skip(Css::Token::ident("avoid"))) { + return Ok(BreakBetween::AVOID); + } else if (c.skip(Css::Token::ident("avoid-page"))) { + return Ok(BreakBetween::AVOID_PAGE); + } else if (c.skip(Css::Token::ident("page"))) { + return Ok(BreakBetween::PAGE); + } else if (c.skip(Css::Token::ident("left"))) { + return Ok(BreakBetween::LEFT); + } else if (c.skip(Css::Token::ident("right"))) { + return Ok(BreakBetween::RIGHT); + } else if (c.skip(Css::Token::ident("recto"))) { + return Ok(BreakBetween::RECTO); + } else if (c.skip(Css::Token::ident("verso"))) { + return Ok(BreakBetween::VERSO); + } else if (c.skip(Css::Token::ident("avoid-column"))) { + return Ok(BreakBetween::AVOID_COLUMN); + } else if (c.skip(Css::Token::ident("column"))) { + return Ok(BreakBetween::COLUMN); + } else if (c.skip(Css::Token::ident("avoid-region"))) { + return Ok(BreakBetween::AVOID_REGION); + } else if (c.skip(Css::Token::ident("region"))) { + return Ok(BreakBetween::REGION); + } + + return Error::invalidData("expected break between value"); +} + +// MARK: BreakInside +// https://www.w3.org/TR/css-break-3/#break-within +Res ValueParser::parse(Cursor &c) { + if (c.ended()) + return Error::invalidData("unexpected end of input"); + + if (c.skip(Css::Token::ident("auto"))) { + return Ok(BreakInside::AUTO); + } else if (c.skip(Css::Token::ident("avoid"))) { + return Ok(BreakInside::AVOID); + } else if (c.skip(Css::Token::ident("avoid-page"))) { + return Ok(BreakInside::AVOID_PAGE); + } else if (c.skip(Css::Token::ident("avoid-column"))) { + return Ok(BreakInside::AVOID_COLUMN); + } else if (c.skip(Css::Token::ident("avoid-region"))) { + return Ok(BreakInside::AVOID_REGION); + } + + return Error::invalidData("expected break between value"); +} + // MARK: Color // https://drafts.csswg.org/css-color diff --git a/src/vaev-style/values.h b/src/vaev-style/values.h index ab701ed..5f65c9f 100644 --- a/src/vaev-style/values.h +++ b/src/vaev-style/values.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -64,6 +65,16 @@ struct ValueParser { static Res parse(Cursor &c); }; +template <> +struct ValueParser { + static Res parse(Cursor &c); +}; + +template <> +struct ValueParser { + static Res parse(Cursor &c); +}; + template struct ValueParser> { static Res> parse(Cursor &c) {