css_function_block(css_parser_token &&tok) :
function(std::forward<css_parser_token>(tok)) {}
- auto as_string() const -> const std::string_view & {
+ auto as_string() const -> std::string_view {
return function.get_string_or_default("");
}
{"visibility", css_property_type::PROPERTY_VISIBILITY},
});
-auto token_string_to_property(const std::string_view &inp) -> css_property_type {
+auto token_string_to_property(const std::string_view &inp)
+ -> css_property_type
+{
css_property_type ret = css_property_type::PROPERTY_NYI;
return ret;
}
-auto css_property::from_token(const css_parser_token &tok) -> tl::expected<css_property,css_parse_error>
+auto css_property::from_token(const css_parser_token &tok)
+ -> tl::expected<css_property,css_parse_error>
{
if (tok.type == css_parser_token::token_type::ident_token) {
auto sv = tok.get_string_or_default("");
- return css_property{token_string_to_property(sv)};
+ return css_property{token_string_to_property(sv), css_property_flag::FLAG_NORMAL};
}
return tl::unexpected{css_parse_error(css_parse_error_type::PARSE_ERROR_NYI)};
* To be extended with properties that are interesting from the email
* point of view
*/
-enum class css_property_type {
+enum class css_property_type : std::uint16_t {
PROPERTY_FONT = 0,
PROPERTY_FONT_COLOR,
PROPERTY_COLOR,
PROPERTY_NYI,
};
-struct css_property {
+enum class css_property_flag : std::uint16_t {
+ FLAG_NORMAL,
+ FLAG_IMPORTANT,
+ FLAG_NOT_IMPORTANT
+};
+
+struct alignas(int) css_property {
css_property_type type;
+ css_property_flag flag;
+
static tl::expected<css_property,css_parse_error> from_token(
const css_parser_token &tok);
{
declarations_vec ret;
bool can_continue = true;
- css_property cur_property{css_property_type::PROPERTY_NYI};
- static const css_property bad_property{css_property_type::PROPERTY_NYI};
+ css_property cur_property{css_property_type::PROPERTY_NYI,
+ css_property_flag::FLAG_NORMAL};
+ static const css_property bad_property{css_property_type::PROPERTY_NYI,
+ css_property_flag::FLAG_NORMAL};
std::unique_ptr<css_rule> cur_rule;
enum {
ignore_value, /* For unknown properties */
} state = parse_property;
+ auto seen_not = false;
+
while (can_continue) {
const auto &next_tok = next_block_functor();
if (parser_tok.type == css_parser_token::token_type::semicolon_token) {
ret.push_back(std::move(cur_rule));
state = parse_property;
+ seen_not = false;
continue;
}
+ else if (parser_tok.type == css_parser_token::token_type::delim_token) {
+ if (parser_tok.get_string_or_default("") == "!") {
+ /* Probably something like !important */
+ seen_not = true;
+ }
+ }
+ else if (parser_tok.type == css_parser_token::token_type::ident_token) {
+ if (parser_tok.get_string_or_default("") == "important") {
+ if (seen_not) {
+ msg_debug_css("add !important flag to property %s",
+ cur_property.to_string());
+ cur_property.flag = css_property_flag::FLAG_NOT_IMPORTANT;
+ }
+ else {
+ msg_debug_css("add important flag to property %s",
+ cur_property.to_string());
+ cur_property.flag = css_property_flag::FLAG_IMPORTANT;
+ }
+
+ seen_not = false;
+
+ continue;
+ }
+ else {
+ seen_not = false;
+ }
+ }
}
auto maybe_value = allowed_property_value(cur_property, next_tok);
auto operator=(css_parser_token &&other) -> css_parser_token& = default;
auto adjust_dim(const css_parser_token &dim_token) -> bool;
- auto get_string_or_default(const std::string_view &def) const -> const std::string_view & {
- if (value.index() == 0) {
+ auto get_string_or_default(const std::string_view &def) const -> std::string_view {
+ if (std::holds_alternative<std::string_view>(value)) {
return std::get<std::string_view>(value);
}
+ else if (std::holds_alternative<char>(value)) {
+ return std::string_view(&std::get<char>(value), 1);
+ }
return def;
}
DISPLAY_HIDDEN
};
-/*
- * CSS flags
- */
-enum class css_flag_value {
- FLAG_INHERIT,
- FLAG_IMPORTANT,
- FLAG_NOTIMPORTANT
-};
-
/*
* Value handler, uses std::variant instead of polymorphic classes for now
* for simplicity
std::variant<css_color,
double,
css_display_value,
- css_flag_value,
std::monostate> value;
css_value(const css_color &color) :
return std::nullopt;
}
- constexpr std::optional<css_flag_value> to_flag(void) const {
- if (type == css_value_type::CSS_VALUE_FLAG) {
- return std::get<css_flag_value>(value);
- }
-
- return std::nullopt;
- }
-
constexpr bool is_valid(void) const {
return (type != css_value_type::CSS_VALUE_NYI);
}
]],
[[
/* Colors */
-* { color: hsl(0, 100%, 50%) } /* red */
-* { color: hsl(120, 100%, 50%) } /* lime */
+* { color: hsl(0, 100%, 50%) !important } /* red */
+* { color: hsl(120, 100%, 50%) important } /* lime */
* { color: hsl(120, 100%, 25%) } /* dark green */
* { color: hsl(120, 100%, 75%) } /* light green */
* { color: hsl(120, 75%, 75%) } /* pastel green, and so on */