From a06f20da1b35484f006755d44077c023a4bd788d Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 10 Mar 2021 20:57:32 +0000 Subject: [PATCH] [Project] Css: Add display value support --- src/libserver/css/css_rule.cxx | 11 ++++++- src/libserver/css/css_value.cxx | 52 ++++++++++++++++++++++++++++----- src/libserver/css/css_value.hxx | 6 ++-- test/lua/unit/css.lua | 4 +-- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx index 684e5776f..d16be2276 100644 --- a/src/libserver/css/css_rule.cxx +++ b/src/libserver/css/css_rule.cxx @@ -133,7 +133,6 @@ allowed_property_value(const css_property &prop, const css_consumed_block &parse return ret; } } - if (prop.is_dimension()) { if (parser_block.is_token()) { /* A single token */ @@ -144,6 +143,16 @@ allowed_property_value(const css_property &prop, const css_consumed_block &parse } } } + if (prop.is_display()) { + if (parser_block.is_token()) { + /* A single token */ + const auto &tok = parser_block.get_token_or_empty(); + + if (tok.type == css_parser_token::token_type::ident_token) { + return css_value::maybe_display_from_string(tok.get_string_or_default("")); + } + } + } if (prop.is_normal_number()) { if (parser_block.is_token()) { /* A single token */ diff --git a/src/libserver/css/css_value.cxx b/src/libserver/css/css_value.cxx index 94c340ac5..5470e8f30 100644 --- a/src/libserver/css/css_value.cxx +++ b/src/libserver/css/css_value.cxx @@ -16,18 +16,12 @@ #include "css_value.hxx" #include "css_colors_list.hxx" +#include "frozen/unordered_map.h" +#include "frozen/string.h" #include "contrib/robin-hood/robin_hood.h" namespace rspamd::css { - - -tl::expected -css_value::from_css_block(const css_consumed_block &bl) -{ - return tl::unexpected{css_parse_error(css_parse_error_type::PARSE_ERROR_NYI)}; -} - auto css_value::maybe_color_from_string(const std::string_view &input) -> std::optional { @@ -295,6 +289,44 @@ auto css_value::maybe_dimension_from_number(const css_parser_token &tok) return std::nullopt; } +constexpr const auto display_names_map = frozen::make_unordered_map({ + {"hidden", css_display_value::DISPLAY_HIDDEN}, + {"none", css_display_value::DISPLAY_HIDDEN}, + {"inline", css_display_value::DISPLAY_NORMAL}, + {"block", css_display_value::DISPLAY_NORMAL}, + {"content", css_display_value::DISPLAY_NORMAL}, + {"flex", css_display_value::DISPLAY_NORMAL}, + {"grid" , css_display_value::DISPLAY_NORMAL}, + {"inline-block", css_display_value::DISPLAY_NORMAL}, + {"inline-flex", css_display_value::DISPLAY_NORMAL}, + {"inline-grid", css_display_value::DISPLAY_NORMAL}, + {"inline-table", css_display_value::DISPLAY_NORMAL}, + {"list-item", css_display_value::DISPLAY_NORMAL}, + {"run-in", css_display_value::DISPLAY_NORMAL}, + {"table", css_display_value::DISPLAY_NORMAL}, + {"table-caption", css_display_value::DISPLAY_NORMAL}, + {"table-column-group", css_display_value::DISPLAY_NORMAL}, + {"table-header-group", css_display_value::DISPLAY_NORMAL}, + {"table-footer-group", css_display_value::DISPLAY_NORMAL}, + {"table-row-group", css_display_value::DISPLAY_NORMAL}, + {"table-cell", css_display_value::DISPLAY_NORMAL}, + {"table-column", css_display_value::DISPLAY_NORMAL}, + {"table-row", css_display_value::DISPLAY_NORMAL}, + {"initial", css_display_value::DISPLAY_NORMAL}, +}); + +auto css_value::maybe_display_from_string(const std::string_view &input) + -> std::optional +{ + auto f = display_names_map.find(input); + + if (f != display_names_map.end()) { + return css_value{f->second}; + } + + return std::nullopt; +} + auto css_value::debug_str() const -> std::string { @@ -318,6 +350,10 @@ auto css_value::debug_str() const -> std::string ret += "%"; } } + else if constexpr (std::is_same_v) { + ret += "display: "; + ret += (arg == css_display_value::DISPLAY_HIDDEN ? "hidden" : "normal"); + } else if constexpr (std::is_integral_v) { ret += "integral: " + std::to_string(static_cast(arg)); } diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx index d7c8f5c45..93324a57c 100644 --- a/src/libserver/css/css_value.hxx +++ b/src/libserver/css/css_value.hxx @@ -82,6 +82,8 @@ struct css_value { type(css_value_type::CSS_VALUE_NUMBER), value(num) {} css_value(css_dimension dim) : type(css_value_type::CSS_VALUE_DIMENSION), value(dim) {} + css_value(css_display_value d) : + type(css_value_type::CSS_VALUE_DISPLAY), value(d) {} auto to_color(void) const -> std::optional { if (type == css_value_type::CSS_VALUE_COLOR) { @@ -121,8 +123,6 @@ struct css_value { auto debug_str() const -> std::string; - static auto from_css_block(const css_consumed_block &bl) -> tl::expected; - static auto maybe_color_from_string(const std::string_view &input) -> std::optional; static auto maybe_color_from_hex(const std::string_view &input) @@ -131,6 +131,8 @@ struct css_value { -> std::optional; static auto maybe_dimension_from_number(const css_parser_token &tok) -> std::optional; + static auto maybe_display_from_string(const std::string_view &input) + -> std::optional; }; } diff --git a/test/lua/unit/css.lua b/test/lua/unit/css.lua index 5bb197bf2..3078ed3bc 100644 --- a/test/lua/unit/css.lua +++ b/test/lua/unit/css.lua @@ -100,8 +100,8 @@ body { ]], [[ /* Colors */ -p { color: rgb(100%, 50%, 0%); opacity: -1; width: 1em; } /* very transparent solid orange */ -p { color: rgb(100%, 50%, 0%); opacity: 2; } /* very transparent solid orange */ +p { color: rgb(100%, 50%, 0%); opacity: -1; width: 1em; display: none; } /* very transparent solid orange */ +p { color: rgb(100%, 50%, 0%); opacity: 2; display: inline; } /* very transparent solid orange */ p { color: rgb(100%, 50%, 0%); opacity: 0.5; } /* very transparent solid orange */ p { color: rgb(100%, 50%, 0%); opacity: 1; width: 99%; } /* very transparent solid orange */ p { color: rgb(100%, 50%, 0%); opacity: 10%; width: 99%; } /* very transparent solid orange */ -- 2.39.5