]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Css: Add opacity support
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Mar 2021 12:07:27 +0000 (12:07 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Mar 2021 12:07:27 +0000 (12:07 +0000)
src/libserver/css/css_colors_list.hxx
src/libserver/css/css_property.cxx
src/libserver/css/css_property.hxx
src/libserver/css/css_rule.cxx
src/libserver/css/css_tokeniser.hxx
src/libserver/css/css_value.cxx
src/libserver/css/css_value.hxx
test/lua/unit/css.lua

index dc7f60960e405dd78328dff4a8fe8d31a8476b68..b1fc5d6ee3845c122e34e3cd0e079a776b2da00e 100644 (file)
@@ -727,6 +727,7 @@ static const robin_hood::unordered_flat_map<std::string_view, css_color> 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}},
index b2578a367aa147a39a7ebc1cffec35e1ce35cc67..54e927057d4c5d3bc3de9315fdbb2c6a777b0e38 100644 (file)
@@ -23,6 +23,7 @@ namespace rspamd::css {
 constexpr const auto type_map = frozen::make_unordered_map<frozen::string, css_property_type>({
                {"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<frozen::string, css_p
                {"width", css_property_type::PROPERTY_WIDTH},
                {"display", css_property_type::PROPERTY_DISPLAY},
                {"visibility", css_property_type::PROPERTY_VISIBILITY},
+               {"opacity", css_property_type::PROPERTY_OPACITY},
 });
 
 auto token_string_to_property(const std::string_view &inp)
index 670dfaddb771961906e41d2449cb74a6927e5901..3908c6d16716abd56625106455a37e4d8ad2397c 100644 (file)
@@ -32,6 +32,7 @@ namespace rspamd::css {
 enum class css_property_type : std::uint16_t {
        PROPERTY_FONT = 0,
        PROPERTY_FONT_COLOR,
+       PROPERTY_FONT_SIZE,
        PROPERTY_COLOR,
        PROPERTY_BGCOLOR,
        PROPERTY_BACKGROUND,
@@ -39,6 +40,7 @@ enum class css_property_type : std::uint16_t {
        PROPERTY_WIDTH,
        PROPERTY_DISPLAY,
        PROPERTY_VISIBILITY,
+       PROPERTY_OPACITY,
        PROPERTY_NYI,
 };
 
@@ -65,6 +67,9 @@ struct alignas(int) css_property {
                case css_property_type::PROPERTY_FONT_COLOR:
                        ret = "font-color";
                        break;
+               case css_property_type::PROPERTY_FONT_SIZE:
+                       ret = "font-size";
+                       break;
                case css_property_type::PROPERTY_COLOR:
                        ret = "color";
                        break;
@@ -86,6 +91,9 @@ struct alignas(int) css_property {
                case css_property_type::PROPERTY_VISIBILITY:
                        ret = "visibility";
                        break;
+               case css_property_type::PROPERTY_OPACITY:
+                       ret = "opacity";
+                       break;
                default:
                        break;
                }
@@ -93,6 +101,7 @@ struct alignas(int) css_property {
                return ret;
        }
 
+       /* Helpers to define which values are valid for which properties */
        constexpr auto is_color(void) const -> 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;
+       }
 };
 
 
index 5bd99bd0edf70b2bc24db979a08e62e8ae35685a..511c226d2357d83a49e4a19a95cae64db0efdaa2 100644 (file)
@@ -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;
 }
index 3776b36e52c5e82599541cce5e63680aa0f4e8bf..53ec4f2db03bb4cc3fb6fe0da6f6a9c9a8678dc2 100644 (file)
@@ -111,6 +111,41 @@ struct css_parser_token {
                return def;
        }
 
+       auto get_number_or_default(double def) const -> double {
+               if (std::holds_alternative<double>(value)) {
+                       auto dbl = std::get<double>(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<double>(value)) {
+                       auto dbl = std::get<double>(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 */
index aa842e2e27942f3017466da62e33e13ffea8a63a..719633e6838313ca24838b4320a07c2f11f0755b 100644 (file)
@@ -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<double>(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;
index 0e675e0ca1f6af1db28b20515fd0c265b14507b6..8fa450e732b8dfad6da30f2c892209eb52709d06 100644 (file)
@@ -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<css_color> 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<double> to_size(void) const {
-               if (type == css_value_type::CSS_VALUE_SIZE) {
+       constexpr std::optional<double> to_number(void) const {
+               if (type == css_value_type::CSS_VALUE_NUMBER) {
                        return std::get<double>(value);
                }
 
index 86119641eba7058324a852e652490e684618f706..9f92011918f479396278a83c301445d0bd34bec0 100644 (file)
@@ -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 */