1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:57:44 +00:00

LibHTML: Use an enum for CSS property ID's

Instead of using string everywhere, have the CSS parser produce enum
values, since they are a lot nicer to work with.

In the future we should generate most of this code based on a list of
supported CSS properties.
This commit is contained in:
Andreas Kling 2019-10-08 15:34:19 +02:00
parent 19dbfc3153
commit 31ac19543a
18 changed files with 207 additions and 94 deletions

View file

@ -0,0 +1,62 @@
#pragma once
#include <AK/Traits.h>
namespace CSS {
enum class PropertyID {
Invalid,
BackgroundColor,
BorderBottomColor,
BorderBottomStyle,
BorderBottomWidth,
BorderCollapse,
BorderLeftColor,
BorderLeftStyle,
BorderLeftWidth,
BorderRightColor,
BorderRightStyle,
BorderRightWidth,
BorderSpacing,
BorderTopColor,
BorderTopStyle,
BorderTopWidth,
Color,
Display,
FontFamily,
FontSize,
FontStyle,
FontVariant,
FontWeight,
Height,
LetterSpacing,
LineHeight,
ListStyle,
ListStyleImage,
ListStylePosition,
ListStyleType,
MarginBottom,
MarginLeft,
MarginRight,
MarginTop,
PaddingBottom,
PaddingLeft,
PaddingRight,
PaddingTop,
TextAlign,
TextDecoration,
TextIndent,
TextTransform,
Visibility,
WhiteSpace,
Width,
WordSpacing,
};
}
namespace AK {
template<>
struct Traits<CSS::PropertyID> : public GenericTraits<CSS::PropertyID> {
static unsigned hash(CSS::PropertyID property_id) { return int_hash((unsigned)property_id); }
};
}

View file

@ -4,7 +4,7 @@
#include <LibHTML/CSS/StyleValue.h>
struct StyleProperty {
String name;
CSS::PropertyID property_id;
NonnullRefPtr<StyleValue> value;
bool important { false };
};

View file

@ -2,38 +2,38 @@
#include <LibHTML/CSS/StyleProperties.h>
#include <ctype.h>
void StyleProperties::set_property(const String& name, NonnullRefPtr<StyleValue> value)
void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value)
{
m_property_values.set(name, move(value));
m_property_values.set((unsigned)id, move(value));
}
Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(const String& name) const
Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(CSS::PropertyID id) const
{
auto it = m_property_values.find(name);
auto it = m_property_values.find((unsigned)id);
if (it == m_property_values.end())
return {};
return it->value;
}
Length StyleProperties::length_or_fallback(const StringView& property_name, const Length& fallback) const
Length StyleProperties::length_or_fallback(CSS::PropertyID id, const Length& fallback) const
{
auto value = property(property_name);
auto value = property(id);
if (!value.has_value())
return fallback;
return value.value()->to_length();
}
String StyleProperties::string_or_fallback(const StringView& property_name, const StringView& fallback) const
String StyleProperties::string_or_fallback(CSS::PropertyID id, const StringView& fallback) const
{
auto value = property(property_name);
auto value = property(id);
if (!value.has_value())
return fallback;
return value.value()->to_string();
}
Color StyleProperties::color_or_fallback(const StringView& property_name, const Document& document, Color fallback) const
Color StyleProperties::color_or_fallback(CSS::PropertyID id, const Document& document, Color fallback) const
{
auto value = property(property_name);
auto value = property(id);
if (!value.has_value())
return fallback;
return value.value()->to_color(document);
@ -41,8 +41,8 @@ Color StyleProperties::color_or_fallback(const StringView& property_name, const
void StyleProperties::load_font() const
{
auto font_family = string_or_fallback("font-family", "Katica");
auto font_weight = string_or_fallback("font-weight", "normal");
auto font_family = string_or_fallback(CSS::PropertyID::FontFamily, "Katica");
auto font_weight = string_or_fallback(CSS::PropertyID::FontWeight, "normal");
String weight;
if (font_weight == "lighter")

View file

@ -15,15 +15,15 @@ public:
inline void for_each_property(Callback callback) const
{
for (auto& it : m_property_values)
callback(it.key, *it.value);
callback((CSS::PropertyID)it.key, *it.value);
}
void set_property(const String& name, NonnullRefPtr<StyleValue> value);
Optional<NonnullRefPtr<StyleValue>> property(const String& name) const;
void set_property(CSS::PropertyID, NonnullRefPtr<StyleValue> value);
Optional<NonnullRefPtr<StyleValue>> property(CSS::PropertyID) const;
Length length_or_fallback(const StringView& property_name, const Length& fallback) const;
String string_or_fallback(const StringView& property_name, const StringView& fallback) const;
Color color_or_fallback(const StringView& property_name, const Document&, Color fallback) const;
Length length_or_fallback(CSS::PropertyID, const Length& fallback) const;
String string_or_fallback(CSS::PropertyID, const StringView& fallback) const;
Color color_or_fallback(CSS::PropertyID, const Document&, Color fallback) const;
const Font& font() const
{
@ -33,7 +33,7 @@ public:
}
private:
HashMap<String, NonnullRefPtr<StyleValue>> m_property_values;
HashMap<unsigned, NonnullRefPtr<StyleValue>> m_property_values;
void load_font() const;

View file

@ -61,37 +61,36 @@ NonnullRefPtrVector<StyleRule> StyleResolver::collect_matching_rules(const Eleme
return matching_rules;
}
bool StyleResolver::is_inherited_property(const StringView& name)
bool StyleResolver::is_inherited_property(CSS::PropertyID property_id)
{
static HashTable<String> inherited_properties;
static HashTable<CSS::PropertyID> inherited_properties;
if (inherited_properties.is_empty()) {
inherited_properties.set("border-collapse");
inherited_properties.set("border-spacing");
inherited_properties.set("color");
inherited_properties.set("font-family");
inherited_properties.set("font-size");
inherited_properties.set("font-style");
inherited_properties.set("font-variant");
inherited_properties.set("font-weight");
inherited_properties.set("font");
inherited_properties.set("letter-spacing");
inherited_properties.set("line-height");
inherited_properties.set("list-style-image");
inherited_properties.set("list-style-position");
inherited_properties.set("list-style-type");
inherited_properties.set("list-style");
inherited_properties.set("text-align");
inherited_properties.set("text-indent");
inherited_properties.set("text-transform");
inherited_properties.set("visibility");
inherited_properties.set("white-space");
inherited_properties.set("word-spacing");
inherited_properties.set(CSS::PropertyID::BorderCollapse);
inherited_properties.set(CSS::PropertyID::BorderSpacing);
inherited_properties.set(CSS::PropertyID::Color);
inherited_properties.set(CSS::PropertyID::FontFamily);
inherited_properties.set(CSS::PropertyID::FontSize);
inherited_properties.set(CSS::PropertyID::FontStyle);
inherited_properties.set(CSS::PropertyID::FontVariant);
inherited_properties.set(CSS::PropertyID::FontWeight);
inherited_properties.set(CSS::PropertyID::LetterSpacing);
inherited_properties.set(CSS::PropertyID::LineHeight);
inherited_properties.set(CSS::PropertyID::ListStyle);
inherited_properties.set(CSS::PropertyID::ListStyleImage);
inherited_properties.set(CSS::PropertyID::ListStylePosition);
inherited_properties.set(CSS::PropertyID::ListStyleType);
inherited_properties.set(CSS::PropertyID::TextAlign);
inherited_properties.set(CSS::PropertyID::TextIndent);
inherited_properties.set(CSS::PropertyID::TextTransform);
inherited_properties.set(CSS::PropertyID::Visibility);
inherited_properties.set(CSS::PropertyID::WhiteSpace);
inherited_properties.set(CSS::PropertyID::WordSpacing);
// FIXME: This property is not supposed to be inherited, but we currently
// rely on inheritance to propagate decorations into line boxes.
inherited_properties.set("text-decoration");
inherited_properties.set(CSS::PropertyID::TextDecoration);
}
return inherited_properties.contains(name);
return inherited_properties.contains(property_id);
}
NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& element, const StyleProperties* parent_style) const
@ -99,9 +98,9 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& eleme
auto style = StyleProperties::create();
if (parent_style) {
parent_style->for_each_property([&](const StringView& name, auto& value) {
if (is_inherited_property(name))
style->set_property(name, value);
parent_style->for_each_property([&](auto property_id, auto& value) {
if (is_inherited_property(property_id))
style->set_property(property_id, value);
});
}
@ -110,7 +109,7 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& eleme
auto matching_rules = collect_matching_rules(element);
for (auto& rule : matching_rules) {
for (auto& property : rule.declaration().properties()) {
style->set_property(property.name, property.value);
style->set_property(property.property_id, property.value);
}
}
@ -118,7 +117,7 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& eleme
if (!style_attribute.is_null()) {
if (auto declaration = parse_css_declaration(style_attribute)) {
for (auto& property : declaration->properties()) {
style->set_property(property.name, property.value);
style->set_property(property.property_id, property.value);
}
}
}

View file

@ -22,7 +22,7 @@ public:
NonnullRefPtrVector<StyleRule> collect_matching_rules(const Element&) const;
static bool is_inherited_property(const StringView&);
static bool is_inherited_property(CSS::PropertyID);
private:
template<typename Callback>

View file

@ -6,6 +6,7 @@
#include <AK/StringView.h>
#include <LibDraw/Color.h>
#include <LibHTML/CSS/Length.h>
#include <LibHTML/CSS/PropertyID.h>
class Document;