From 1dbfa1f48f4e872a40432b9270acd2456e694190 Mon Sep 17 00:00:00 2001 From: Paulo Medeiros Date: Mon, 16 Sep 2024 17:02:40 +0200 Subject: [PATCH] style: add flex shorthand parser --- src/web/vaev-style/styles.h | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/web/vaev-style/styles.h b/src/web/vaev-style/styles.h index 5cc0f52..5f67153 100644 --- a/src/web/vaev-style/styles.h +++ b/src/web/vaev-style/styles.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -7,6 +8,8 @@ #include "base.h" #include "computed.h" +#include "karm-base/res.h" +#include "karm-logger/logger.h" #include "vaev-base/numbers.h" #include "values.h" @@ -869,6 +872,85 @@ struct FlexFlowProp { } }; +// https://www.w3.org/TR/css-flexbox-1/#propdef-flex +struct FlexProp { + Tuple value = initial(); + + static Tuple initial() { + return { + Width{Width::AUTO}, + 0, + 1, + }; + } + + static constexpr Str name() { return "flex"; } + + void apply(Computed &c) const { + c.flex.cow().basis = value.v0; + c.flex.cow().grow = value.v1; + c.flex.cow().shrink = value.v2; + } + + Res<> parse(Cursor &c) { + if (c.ended()) + return Error::invalidData("unexpected end of input"); + + if (c.skip(Css::Token::ident("none"))) { + value.v0 = Width{Width::AUTO}; + value.v1 = value.v2 = 0; + return Ok(); + } else if (c.skip(Css::Token::ident("initial"))) { + value.v0 = Width{Width::AUTO}; + value.v1 = 0, value.v2 = 1; + return Ok(); + } + + auto parseGrowShrink = [&c]() -> Res> { + auto grow = parseValue(c); + if (not grow) + return Error::invalidData("expected flex item grow"); + + Number growValue = grow.unwrap(); + + Number shrinkValue; + auto shrink = parseValue(c); + if (shrink) + shrinkValue = shrink.unwrap(); + else + shrinkValue = 1; + return Ok(Tuple{growValue, shrinkValue}); + }; + + auto maybeGrowShrinkValues = parseGrowShrink(); + if (maybeGrowShrinkValues) { + auto growShrinkValues = maybeGrowShrinkValues.unwrap(); + value.v1 = growShrinkValues.v0, value.v2 = growShrinkValues.v1; + + auto basis = parseValue(c); + if (basis) + value.v0 = basis.unwrap(); + else + value.v0 = FlexBasis(Width(Length(0, Length::Unit::PX))); + } else { + auto basis = parseValue(c); + if (basis) + value.v0 = basis.unwrap(); + else + return Error::invalidData("expected flex item grow or basis"); + + maybeGrowShrinkValues = parseGrowShrink(); + if (maybeGrowShrinkValues) { + auto growShrinkValues = maybeGrowShrinkValues.unwrap(); + value.v1 = growShrinkValues.v0, value.v2 = growShrinkValues.v1; + } else { + value.v1 = value.v2 = 1; + } + } + return Ok(); + } +}; + // MARK: Fonts ----------------------------------------------------------------- // https://www.w3.org/TR/css-fonts-4/#font-family-prop @@ -1591,6 +1673,7 @@ using _StyleProp = Union< FlexShrinkProp, FlexWrapProp, FlexFlowProp, + FlexProp, // Font FontFamilyProp,