srctree

Robin Linden parent 4ccc270c 2063d837
css: Handle style in the text-decoration shorthand

inlinesplit
css/parser.cpp added: 61, removed: 14, total 47
@@ -669,18 +669,28 @@ void Parser::expand_border_radius_values(Declarations &declarations, std::string
// https://drafts.csswg.org/css-text-decor/#text-decoration-property
void Parser::expand_text_decoration_values(Declarations &declarations, std::string_view value) {
Tokenizer tokenizer{value, ' '};
// TODO(robinlinden): CSS level 3 text-decorations.
if (tokenizer.size() != 1) {
spdlog::warn("Unsupported text-decoration value: '{}'", value);
return;
// TODO(robinlinden): global values, text-decoration-color, text-decoration-thickness.
 
static constexpr std::array kTextDecorationLineKeywords{"none", "underline", "overline", "line-through", "blink"};
static constexpr std::array kTextDecorationStyleKeywords{"solid", "double", "dotted", "dashed", "wavy"};
 
std::optional<std::string_view> line;
std::optional<std::string_view> style;
 
for (auto v = tokenizer.get(); v.has_value(); v = tokenizer.next().get()) {
if (is_in_array<kTextDecorationLineKeywords>(*v) && !line.has_value()) {
line = *v;
} else if (is_in_array<kTextDecorationStyleKeywords>(*v) && !style.has_value()) {
style = *v;
} else {
spdlog::warn("Unsupported text-decoration value: '{}'", value);
return;
}
}
 
auto text_decoration = tokenizer.get();
assert(text_decoration.has_value());
 
declarations.insert_or_assign(PropertyId::TextDecorationColor, "currentcolor");
declarations.insert_or_assign(PropertyId::TextDecorationLine, *text_decoration);
declarations.insert_or_assign(PropertyId::TextDecorationStyle, "solid");
declarations.insert_or_assign(PropertyId::TextDecorationLine, line.value_or("none"));
declarations.insert_or_assign(PropertyId::TextDecorationStyle, style.value_or("solid"));
}
 
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex-flow
 
css/parser_test.cpp added: 61, removed: 14, total 47
@@ -87,7 +87,7 @@ ValueT get_and_erase(
}
 
void text_decoration_tests() {
etest::test("parser: text-decoration, 1 value", [] {
etest::test("parser: text-decoration, line", [] {
auto rules = css::parse("p { text-decoration: underline; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations,
@@ -98,10 +98,47 @@ void text_decoration_tests() {
});
});
 
// This will fail once we support CSS Level 3 text-decorations.
etest::test("parser: text-decoration, 2 values", [] {
etest::test("parser: text-decoration, line & style", [] {
auto rules = css::parse("p { text-decoration: underline dotted; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations,
std::map<css::PropertyId, std::string>{
{css::PropertyId::TextDecorationColor, "currentcolor"},
{css::PropertyId::TextDecorationLine, "underline"},
{css::PropertyId::TextDecorationStyle, "dotted"},
});
});
 
etest::test("parser: text-decoration, duplicate line", [] {
auto rules = css::parse("p { text-decoration: underline overline; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations, std::map<css::PropertyId, std::string>{});
});
 
etest::test("parser: text-decoration, duplicate style", [] {
auto rules = css::parse("p { text-decoration: dotted dotted; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations, std::map<css::PropertyId, std::string>{});
});
 
// This will fail once we support text-decoration-thickness.
etest::test("parser: text-decoration, line & thickness", [] {
auto rules = css::parse("p { text-decoration: underline 3px; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations, std::map<css::PropertyId, std::string>{});
});
 
// This will fail once we support text-decoration-color.
etest::test("parser: text-decoration, line & color", [] {
auto rules = css::parse("p { text-decoration: overline blue; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations, std::map<css::PropertyId, std::string>{});
});
 
// This will fail once we support global values.
etest::test("parser: text-decoration, global value", [] {
auto rules = css::parse("p { text-decoration: inherit; }").rules;
auto const &p = rules.at(0);
expect_eq(p.declarations, std::map<css::PropertyId, std::string>{});
});
}