StyleResolver.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include <LibHTML/CSS/StyleResolver.h>
  2. #include <LibHTML/CSS/StyleSheet.h>
  3. #include <LibHTML/DOM/Document.h>
  4. #include <LibHTML/DOM/Element.h>
  5. #include <LibHTML/Dump.h>
  6. #include <stdio.h>
  7. StyleResolver::StyleResolver(Document& document)
  8. : m_document(document)
  9. {
  10. }
  11. StyleResolver::~StyleResolver()
  12. {
  13. }
  14. static bool matches(const Selector& selector, const Element& element)
  15. {
  16. // FIXME: Support compound selectors.
  17. ASSERT(selector.components().size() == 1);
  18. auto& component = selector.components().first();
  19. switch (component.type) {
  20. case Selector::Component::Type::Id:
  21. return component.value == element.attribute("id");
  22. case Selector::Component::Type::Class:
  23. return element.has_class(component.value);
  24. case Selector::Component::Type::TagName:
  25. return component.value == element.tag_name();
  26. default:
  27. ASSERT_NOT_REACHED();
  28. }
  29. }
  30. NonnullRefPtrVector<StyleRule> StyleResolver::collect_matching_rules(const Element& element) const
  31. {
  32. NonnullRefPtrVector<StyleRule> matching_rules;
  33. for (auto& sheet : document().stylesheets()) {
  34. for (auto& rule : sheet.rules()) {
  35. for (auto& selector : rule.selectors()) {
  36. if (matches(selector, element)) {
  37. matching_rules.append(rule);
  38. break;
  39. }
  40. }
  41. }
  42. }
  43. #ifdef HTML_DEBUG
  44. printf("Rules matching Element{%p}\n", &element);
  45. for (auto& rule : matching_rules) {
  46. dump_rule(rule);
  47. }
  48. #endif
  49. return matching_rules;
  50. }
  51. StyleProperties StyleResolver::resolve_style(const Element& element, const StyleProperties* parent_properties) const
  52. {
  53. StyleProperties style_properties;
  54. if (parent_properties) {
  55. parent_properties->for_each_property([&](const StringView& name, auto& value) {
  56. // TODO: proper inheritance
  57. if (name.starts_with("font") || name == "white-space")
  58. style_properties.set_property(name, value);
  59. });
  60. }
  61. auto matching_rules = collect_matching_rules(element);
  62. for (auto& rule : matching_rules) {
  63. for (auto& declaration : rule.declarations()) {
  64. style_properties.set_property(declaration.property_name(), declaration.value());
  65. }
  66. }
  67. return style_properties;
  68. }