]> source.dussan.org Git - rspamd.git/commitdiff
[Project] Html/Css: Implement visibility rules for a block
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 14 Jun 2021 12:42:28 +0000 (13:42 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 14 Jun 2021 13:07:29 +0000 (14:07 +0100)
src/libserver/html/html.cxx
src/libserver/html/html_block.hxx
src/lua/lua_html.cxx

index eb4d806d7d422266d168e7c18472832e71baa282..f30b9d1b87e9a8282dc8703c72a9db35eb7a2c7e 100644 (file)
@@ -1654,6 +1654,8 @@ html_process_input(rspamd_mempool_t *pool,
        /* Propagate styles */
        hc->traverse_block_tags([](const html_tag *tag) -> bool {
                if (tag->block) {
+                       tag->block->compute_visibility();
+
                        for (const auto *cld_tag : tag->children) {
                                if (cld_tag->block) {
                                        cld_tag->block->propagate_block(*tag->block);
index 91348086411a1e2ef9e172557ed77f4a23c049c9..0958debdd82bba5025641adc3036d4e87db39d38 100644 (file)
@@ -18,6 +18,7 @@
 #pragma once
 
 #include "libserver/css/css_value.hxx"
+#include <cmath>
 
 namespace rspamd::html {
 
@@ -39,6 +40,7 @@ struct html_block {
        constexpr static const auto width_mask = 0x1 << 3;
        constexpr static const auto display_mask = 0x1 << 4;
        constexpr static const auto font_size_mask = 0x1 << 5;
+       constexpr static const auto invisible_flag = 0x1 << 6;
 
        /* Helpers to set mask when setting the elements */
        auto set_fgcolor(const rspamd::css::css_color &c) -> void {
@@ -159,6 +161,59 @@ struct html_block {
                size_prop(font_size_mask, font_size, other.font_size, 1024);
        }
 
+       auto compute_visibility(void) -> void {
+               if (mask & display_mask) {
+                       if (display == css::css_display_value::DISPLAY_HIDDEN) {
+                               mask |= invisible_flag;
+
+                               return;
+                       }
+               }
+
+               if (mask & font_size_mask) {
+                       if (font_size == 0) {
+                               mask |= invisible_flag;
+
+                               return;
+                       }
+               }
+
+               /* Check if we have both bg/fg colors */
+               if ((mask & (bg_color_mask|fg_color_mask)) == (bg_color_mask|fg_color_mask)) {
+                       if (fg_color.alpha < 10) {
+                               /* Too transparent */
+                               mask |= invisible_flag;
+
+                               return;
+                       }
+
+                       if (bg_color.alpha > 10) {
+                               auto diff_r = std::abs(fg_color.r - bg_color.r);
+                               auto diff_g = std::abs(fg_color.g - bg_color.g);
+                               auto diff_b = std::abs(fg_color.b - bg_color.b);
+                               auto ravg = (fg_color.r + bg_color.r) / 2.0;
+
+                               diff_r *= diff_r;
+                               diff_g *= diff_g;
+                               diff_b *= diff_b;
+
+                               auto diff = std::sqrt(2.0 * diff_r + 4.0 * diff_g + 3.0 * diff_b +
+                                                 (ravg * (diff_r - diff_b) / 256.0)) / 256.0;
+
+                               if (diff < 0.1) {
+                                       mask |= invisible_flag;
+                                       return;
+                               }
+                       }
+               }
+
+               mask &= ~invisible_flag;
+       }
+
+       auto is_visible(void) const -> bool {
+               return (mask & invisible_flag) != 0;
+       }
+
        /**
         * Returns a default html block for root HTML element
         * @return
index 3b9b7a7defba19a7be5925cfe8bb23940be0d2a7..0972fde984765cc26d26ec1c3d74a91f0f7e7926 100644 (file)
@@ -381,9 +381,8 @@ lua_html_push_block (lua_State *L, const struct rspamd::html::html_block *bl)
                lua_settable(L, -3);
        }
 
-       /* TODO: fix */
        lua_pushstring(L, "visible");
-       lua_pushboolean(L, true);
+       lua_pushboolean(L, (bl->mask & rspamd::html::html_block::invisible_flag) == 0);
        lua_settable(L, -3);
 }