srctree

Robin Linden parent df169736 1eb24aaa
style: Support parsing and applying inline styles

inlinesplit
style/style.cpp added: 39, removed: 2, total 37
@@ -5,12 +5,16 @@
#include "style/style.h"
 
#include "css/media_query.h"
#include "css/parser.h"
#include "util/string.h"
 
#include <algorithm>
#include <iterator>
#include <string>
#include <utility>
 
using namespace std::literals;
 
namespace style {
namespace {
bool has_class(dom::Element const &element, std::string_view needle_class) {
@@ -138,6 +142,20 @@ std::vector<std::pair<css::PropertyId, std::string>> matching_rules(
}
}
 
if (auto const *element = std::get_if<dom::Element>(&node.node)) {
auto style_attr = element->attributes.find("style");
if (style_attr != element->attributes.end()) {
// TODO(robinlinden): Incredibly hacky, but our //css parser doesn't support
// parsing only declarations. Replace with the //css2 parser once possible.
auto element_style = css::parse("dummy{"s + style_attr->second + "}"s);
// The above should always parse to 1 rule when using the old parser.
assert(element_style.size() == 1);
if (element_style.size() == 1) {
std::ranges::copy(element_style[0].declarations, std::back_inserter(matched_rules));
}
}
}
 
return matched_rules;
}
 
 
style/style_test.cpp added: 39, removed: 2, total 37
@@ -30,6 +30,24 @@ bool check_parents(style::StyledNode const &a, style::StyledNode const &b) {
 
return *a.parent == *b.parent;
}
 
void inline_css_tests() {
etest::test("inline css: is applied", [] {
dom::Node dom = dom::Element{"div", {{"style", {"font-size:2px"}}}};
auto styled = style::style_tree(dom, {}, {});
expect_eq(styled->properties, std::vector{std::pair{css::PropertyId::FontSize, "2px"s}});
});
 
etest::test("inline css: overrides the stylesheet", [] {
dom::Node dom = dom::Element{"div", {{"style", {"font-size:2px"}}}};
auto styled = style::style_tree(dom, {css::Rule{{"div"}, {{css::PropertyId::FontSize, "2000px"}}}}, {});
 
// The last property is the one that's applied.
expect_eq(styled->properties,
std::vector{
std::pair{css::PropertyId::FontSize, "2000px"s}, std::pair{css::PropertyId::FontSize, "2px"s}});
});
}
} // namespace
 
int main() {
@@ -220,5 +238,6 @@ int main() {
expect(check_parents(*style::style_tree(root, stylesheet), expected));
});
 
inline_css_tests();
return etest::run_all_tests();
}