From 26676f385c051affd123a40c5e354a52e64e8fc2 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 14 Jun 2021 13:42:28 +0100 Subject: [PATCH] [Project] Html/Css: Implement visibility rules for a block --- src/libserver/html/html.cxx | 2 ++ src/libserver/html/html_block.hxx | 55 +++++++++++++++++++++++++++++++ src/lua/lua_html.cxx | 3 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/libserver/html/html.cxx b/src/libserver/html/html.cxx index eb4d806d7..f30b9d1b8 100644 --- a/src/libserver/html/html.cxx +++ b/src/libserver/html/html.cxx @@ -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); diff --git a/src/libserver/html/html_block.hxx b/src/libserver/html/html_block.hxx index 913480864..0958debdd 100644 --- a/src/libserver/html/html_block.hxx +++ b/src/libserver/html/html_block.hxx @@ -18,6 +18,7 @@ #pragma once #include "libserver/css/css_value.hxx" +#include 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 diff --git a/src/lua/lua_html.cxx b/src/lua/lua_html.cxx index 3b9b7a7de..0972fde98 100644 --- a/src/lua/lua_html.cxx +++ b/src/lua/lua_html.cxx @@ -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); } -- 2.39.5