From: Vsevolod Stakhov Date: Tue, 9 Mar 2021 12:07:27 +0000 (+0000) Subject: [Project] Css: Add opacity support X-Git-Tag: 3.0~601 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f0de57da10d978a4ceea1dcfad01c6a50d04b467;p=rspamd.git [Project] Css: Add opacity support --- diff --git a/src/libserver/css/css_colors_list.hxx b/src/libserver/css/css_colors_list.hxx index dc7f60960..b1fc5d6ee 100644 --- a/src/libserver/css/css_colors_list.hxx +++ b/src/libserver/css/css_colors_list.hxx @@ -727,6 +727,7 @@ static const robin_hood::unordered_flat_map css_col {"threedhighlight", {0, 0, 0}}, {"threedlightshadow", {0, 0, 0}}, {"threedshadow", {0, 0, 0}}, + {"transparent", {0, 0, 0, 0}}, {"window", {255, 255, 255}}, {"windowframe", {100, 100, 100}}, {"windowtext", {0, 0, 0}}, diff --git a/src/libserver/css/css_property.cxx b/src/libserver/css/css_property.cxx index b2578a367..54e927057 100644 --- a/src/libserver/css/css_property.cxx +++ b/src/libserver/css/css_property.cxx @@ -23,6 +23,7 @@ namespace rspamd::css { constexpr const auto type_map = frozen::make_unordered_map({ {"font", css_property_type::PROPERTY_FONT}, {"font-color", css_property_type::PROPERTY_FONT_COLOR}, + {"font-size", css_property_type::PROPERTY_FONT_SIZE}, {"color", css_property_type::PROPERTY_COLOR}, {"bgcolor", css_property_type::PROPERTY_BGCOLOR}, {"background", css_property_type::PROPERTY_BACKGROUND}, @@ -30,6 +31,7 @@ constexpr const auto type_map = frozen::make_unordered_map bool { return type == css_property_type::PROPERTY_COLOR || type == css_property_type::PROPERTY_BACKGROUND || @@ -103,6 +112,9 @@ struct alignas(int) css_property { return type == css_property_type::PROPERTY_HEIGHT || type == css_property_type::PROPERTY_WIDTH; } + constexpr auto is_normal_number(void) const -> bool { + return type == css_property_type::PROPERTY_OPACITY; + } }; diff --git a/src/libserver/css/css_rule.cxx b/src/libserver/css/css_rule.cxx index 5bd99bd0e..511c226d2 100644 --- a/src/libserver/css/css_rule.cxx +++ b/src/libserver/css/css_rule.cxx @@ -40,6 +40,26 @@ allowed_property_value(const css_property &prop, const css_consumed_block &parse return css_value::maybe_color_from_function(func); } } + else if (prop.is_dimension()) { + 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::number_token) { + return css_value{tok.get_number_or_default(0)}; + } + } + } + else if (prop.is_normal_number()) { + 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::number_token) { + return css_value{tok.get_normal_number_or_default(0)}; + } + } + } return std::nullopt; } diff --git a/src/libserver/css/css_tokeniser.hxx b/src/libserver/css/css_tokeniser.hxx index 3776b36e5..53ec4f2db 100644 --- a/src/libserver/css/css_tokeniser.hxx +++ b/src/libserver/css/css_tokeniser.hxx @@ -111,6 +111,41 @@ struct css_parser_token { return def; } + auto get_number_or_default(double def) const -> double { + if (std::holds_alternative(value)) { + auto dbl = std::get(value); + + if (flags & css_parser_token::number_percent) { + dbl /= 100.0; + } + + return dbl; + } + + return def; + } + + auto get_normal_number_or_default(double def) const -> double { + if (std::holds_alternative(value)) { + auto dbl = std::get(value); + + if (flags & css_parser_token::number_percent) { + dbl /= 100.0; + } + + if (dbl < 0) { + return 0.0; + } + else if (dbl > 1.0) { + return 1.0; + } + + return dbl; + } + + return def; + } + /* Debugging routines */ constexpr auto get_token_type() -> const char *; /* This function might be slow */ diff --git a/src/libserver/css/css_value.cxx b/src/libserver/css/css_value.cxx index aa842e2e2..719633e68 100644 --- a/src/libserver/css/css_value.cxx +++ b/src/libserver/css/css_value.cxx @@ -182,27 +182,7 @@ constexpr static inline auto sl_component_convert(const css_parser_token &tok) double ret = 0.0; if (tok.type == css_parser_token::token_type::number_token) { - auto dbl = std::get(tok.value); - - if (tok.flags & css_parser_token::number_percent) { - if (dbl > 100) { - dbl = 100; - } - else if (dbl < 0) { - dbl = 0; - } - ret = (dbl / 100.0); - } - else { - if (dbl > 1) { - dbl = 1; - } - else if (dbl < 0) { - dbl = 0; - } - - ret = (dbl); - } + ret = tok.get_normal_number_or_default(ret); } return ret; diff --git a/src/libserver/css/css_value.hxx b/src/libserver/css/css_value.hxx index 0e675e0ca..8fa450e73 100644 --- a/src/libserver/css/css_value.hxx +++ b/src/libserver/css/css_value.hxx @@ -56,9 +56,9 @@ enum class css_display_value { struct css_value { enum class css_value_type { CSS_VALUE_COLOR, - CSS_VALUE_SIZE, + CSS_VALUE_NUMBER, CSS_VALUE_DISPLAY, - CSS_VALUE_FLAG, + CSS_VALUE_OPACITY, CSS_VALUE_NYI, } type; @@ -69,8 +69,8 @@ struct css_value { css_value(const css_color &color) : type(css_value_type::CSS_VALUE_COLOR), value(color) {} - css_value(double sz) : - type(css_value_type::CSS_VALUE_SIZE), value(sz) {} + css_value(double num) : + type(css_value_type::CSS_VALUE_NUMBER), value(num) {} constexpr std::optional to_color(void) const { if (type == css_value_type::CSS_VALUE_COLOR) { @@ -80,8 +80,8 @@ struct css_value { return std::nullopt; } - constexpr std::optional to_size(void) const { - if (type == css_value_type::CSS_VALUE_SIZE) { + constexpr std::optional to_number(void) const { + if (type == css_value_type::CSS_VALUE_NUMBER) { return std::get(value); } diff --git a/test/lua/unit/css.lua b/test/lua/unit/css.lua index 86119641e..9f9201191 100644 --- a/test/lua/unit/css.lua +++ b/test/lua/unit/css.lua @@ -100,6 +100,11 @@ body { ]], [[ /* Colors */ +p { color: rgb(100%, 50%, 0%); opacity: -1; } /* very transparent solid orange */ +p { color: rgb(100%, 50%, 0%); opacity: 2; } /* 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 */ * { color: hsl(0, 100%, 50%) !important } /* red */ * { color: hsl(120, 100%, 50%) important } /* lime */ * { color: hsl(120, 100%, 25%) } /* dark green */