diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-11-18 11:12:58 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-11-18 11:48:41 +0100 |
commit | e6e41e4fb888918a3d75e6c112a3f5c996bb3393 (patch) | |
tree | 34f81cf93e703f63c1cd19b335e4f98452229137 | |
parent | dcd10149feac4c17247a5e06cf850df6ed8e4aab (diff) | |
download | serenity-e6e41e4fb888918a3d75e6c112a3f5c996bb3393.zip |
LibHTML: Start building a simple code generator for CSS properties
Code for parsing and stringifying CSS properties is now generated based
on LibHTML/CSS/Properties.json
At the moment, the file tells us three things:
- The name of a property
- Its initial value
- Whether it's inherited
Also, for shorthand properties, it provides a list of all the longhand
properties it may expand too. This is not actually used in the engine
yet though.
This *finally* makes layout tree dumps show the names of CSS properties
in effect, instead of "CSS::PropertyID(32)" and such. :^)
10 files changed, 529 insertions, 115 deletions
diff --git a/Libraries/LibHTML/CSS/.gitignore b/Libraries/LibHTML/CSS/.gitignore index 887283905e..ae00c71e95 100644 --- a/Libraries/LibHTML/CSS/.gitignore +++ b/Libraries/LibHTML/CSS/.gitignore @@ -1 +1,3 @@ DefaultStyleSheetSource.cpp +PropertyID.cpp +PropertyID.h diff --git a/Libraries/LibHTML/CSS/Properties.json b/Libraries/LibHTML/CSS/Properties.json new file mode 100644 index 0000000000..b7d5e0456e --- /dev/null +++ b/Libraries/LibHTML/CSS/Properties.json @@ -0,0 +1,312 @@ +{ + "background-attachment": { + "inherited": false, + "initial": "scroll" + }, + "background-color": { + "inherited": false, + "initial": "transparent" + }, + "background-image": { + "inherited": false, + "initial": "none" + }, + "background-position": { + "inherited": false, + "initial": "0% 0%" + }, + "background-repeat": { + "inherited": false, + "initial": "repeat" + }, + "border": { + "longhands": [ + "border-width", + "border-style", + "border-color" + ] + }, + "border-bottom-color": { + "initial": "currentColor", + "inherited": false + }, + "border-bottom-style": { + "initial": "none", + "inherited": false + }, + "border-bottom-width": { + "initial": "medium", + "inherited": false + }, + "border-color": { + "longhands": [ + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color" + ] + }, + "border-collapse": { + "inherited": true, + "initial": "separate" + }, + "border-left-color": { + "initial": "currentColor", + "inherited": false + }, + "border-left-style": { + "initial": "none", + "inherited": false + }, + "border-left-width": { + "initial": "medium", + "inherited": false + }, + "border-right-color": { + "initial": "currentColor", + "inherited": false + }, + "border-right-style": { + "initial": "none", + "inherited": false + }, + "border-right-width": { + "initial": "medium", + "inherited": false + }, + "border-spacing": { + "inherited": true, + "initial": "0" + }, + "border-style": { + "longhands": [ + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style" + ] + }, + "border-top-color": { + "initial": "currentColor", + "inherited": false + }, + "border-top-style": { + "initial": "none", + "inherited": false + }, + "border-top-width": { + "initial": "medium", + "inherited": false + }, + "border-width": { + "longhands": [ + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width" + ] + }, + "bottom": { + "inherited": false, + "initial": "auto" + }, + "caption-side": { + "inherited": true, + "initial": "top" + }, + "clear": { + "inherited": false, + "initial": "none" + }, + "clip": { + "inherited": true, + "initial": "auto" + }, + "color": { + "inherited": true, + "initial": "" + }, + "cursor": { + "inherited": true, + "initial": "auto" + }, + "direction": { + "inherited": true, + "initial": "ltr" + }, + "display": { + "inherited": false, + "initial": "inline" + }, + "float": { + "inherited": false, + "initial": "none" + }, + "font-family": { + "inherited": true, + "initial": "sans-serif" + }, + "font-size": { + "inherited": true, + "initial": "medium" + }, + "font-style": { + "inherited": true, + "initial": "normal" + }, + "font-variant": { + "inherited": true, + "initial": "normal" + }, + "font-weight": { + "inherited": true, + "initial": "normal" + }, + "height": { + "inherited": false, + "initial": "auto" + }, + "left": { + "inherited": false, + "initial": "auto" + }, + "letter-spacing": { + "inherited": true, + "initial": "normal" + }, + "line-height": { + "inherited": true, + "initial": "normal" + }, + "list-style": { + "longhands": [ + "list-style-type", + "list-style-position", + "list-style-image" + ] + }, + "list-style-image": { + "inherited": true, + "initial": "none" + }, + "list-style-position": { + "inherited": true, + "initial": "outside" + }, + "list-style-type": { + "inherited": true, + "initial": "disc" + }, + "margin": { + "longhands": [ + "margin-top", + "margin-right", + "margin-bottom", + "margin-left" + ] + }, + "margin-bottom": { + "inherited": false, + "initial": "0" + }, + "margin-left": { + "inherited": false, + "initial": "0" + }, + "margin-right": { + "inherited": false, + "initial": "0" + }, + "margin-top": { + "inherited": false, + "initial": "0" + }, + "max-height": { + "inherited": false, + "initial": "none" + }, + "max-width": { + "inherited": false, + "initial": "none" + }, + "min-height": { + "inherited": false, + "initial": "0" + }, + "min-width": { + "inherited": false, + "initial": "0" + }, + "padding": { + "longhands": [ + "padding-top", + "padding-right", + "padding-bottom", + "padding-left" + ] + }, + "padding-bottom": { + "inherited": false, + "initial": "0" + }, + "padding-left": { + "inherited": false, + "initial": "0" + }, + "padding-right": { + "inherited": false, + "initial": "0" + }, + "padding-top": { + "inherited": false, + "initial": "0" + }, + "right": { + "inherited": false, + "initial": "auto" + }, + "text-align": { + "inherited": true, + "initial": "left" + }, + "text-decoration": { + "inherited": false, + "initial": "none" + }, + "text-indent": { + "inherited": true, + "initial": "0" + }, + "text-transform": { + "inherited": true, + "initial": "none" + }, + "top": { + "inherited": false, + "initial": "auto" + }, + "vertical-align": { + "inherited": false, + "initial": "baseline" + }, + "visibility": { + "inherited": true, + "initial": "visible" + }, + "width": { + "inherited": false, + "initial": "auto" + }, + "white-space": { + "inherited": true, + "initial": "normal" + }, + "word-spacing": { + "inherited": true, + "initial": "normal" + }, + "z-index": { + "inherited": false, + "initial": "auto" + } +} diff --git a/Libraries/LibHTML/CSS/PropertyID.h b/Libraries/LibHTML/CSS/PropertyID.h deleted file mode 100644 index 3702da99b6..0000000000 --- a/Libraries/LibHTML/CSS/PropertyID.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include <AK/Traits.h> - -namespace CSS { -enum class PropertyID { - Invalid, - - BackgroundColor, - BackgroundImage, - 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); } -}; -} diff --git a/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Generate_CSS_PropertyID_cpp.cpp b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Generate_CSS_PropertyID_cpp.cpp new file mode 100644 index 0000000000..7c1e7734e0 --- /dev/null +++ b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Generate_CSS_PropertyID_cpp.cpp @@ -0,0 +1,66 @@ +#include <AK/JsonObject.h> +#include <AK/StringBuilder.h> +#include <LibCore/CFile.h> +#include <ctype.h> +#include <stdio.h> + +static String title_casify(const String& dashy_name) +{ + auto parts = dashy_name.split('-'); + StringBuilder builder; + for (auto& part : parts) { + if (part.is_empty()) + continue; + builder.append(toupper(part[0])); + if (part.length() == 1) + continue; + builder.append(part.substring_view(1, part.length() - 1)); + } + return builder.to_string(); +} + +int main(int argc, char** argv) +{ + if (argc != 2) { + fprintf(stderr, "usage: %s <path/to/CSS/Properties.json>\n", argv[0]); + return 1; + } + auto file = CFile::construct(argv[1]); + if (!file->open(CIODevice::ReadOnly)) + return 1; + + auto json = JsonValue::from_string(file->read_all()); + ASSERT(json.is_object()); + + dbg() << "#include <AK/Assertions.h>"; + dbg() << "#include <LibHTML/CSS/PropertyID.h>"; + dbg() << "namespace CSS {"; + + dbg() << "PropertyID property_id_from_string(const StringView& string) {"; + + json.as_object().for_each_member([&](auto& name, auto& value) { + ASSERT(value.is_object()); + dbg() << " if (string == \"" << name << "\")"; + dbg() << " return PropertyID::" << title_casify(name) << ";"; + }); + + dbg() << " return PropertyID::Invalid;"; + + dbg() << "}"; + + dbg() << "const char* string_from_property_id(PropertyID property_id) {"; + dbg() << " switch (property_id) {"; + json.as_object().for_each_member([&](auto& name, auto& value) { + ASSERT(value.is_object()); + dbg() << " case PropertyID::" << title_casify(name) << ":"; + dbg() << " return \"" << name << "\";"; + }); + dbg() << " default:"; + dbg() << " ASSERT_NOT_REACHED();"; + dbg() << " return nullptr;"; + dbg() << " }"; + dbg() << "}"; + dbg() << "}"; + + return 0; +} diff --git a/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Makefile b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Makefile new file mode 100644 index 0000000000..7e4bc8d3d3 --- /dev/null +++ b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_cpp/Makefile @@ -0,0 +1,33 @@ +PROGRAM = Generate_CSS_PropertyID_cpp + +OBJS = \ + Generate_CSS_PropertyID_cpp.o \ + $(SERENITY_ROOT)/AK/String.o \ + $(SERENITY_ROOT)/AK/StringImpl.o \ + $(SERENITY_ROOT)/AK/StringBuilder.o \ + $(SERENITY_ROOT)/AK/StringView.o \ + $(SERENITY_ROOT)/AK/JsonValue.o \ + $(SERENITY_ROOT)/AK/JsonParser.o \ + $(SERENITY_ROOT)/AK/LogStream.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CIODevice.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CFile.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CObject.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CEvent.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CSocket.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CLocalSocket.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CNotifier.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CLocalServer.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CEventLoop.o + +all: $(PROGRAM) + +CXXFLAGS = -std=c++17 -Wall -Wextra + +%.o: %.cpp + $(PRE_CXX) $(CXX) $(CXXFLAGS) -I../ -I$(SERENITY_ROOT)/ -I$(SERENITY_ROOT)/Libraries/ -o $@ -c $< + +$(PROGRAM): $(OBJS) + $(CXX) $(LDFLAGS) -I../ -I$(SERENITY_ROOT)/ -I$(SERENITY_ROOT)/Libraries/ -o $(PROGRAM) $(OBJS) + +clean: + rm -f $(PROGRAM) $(OBJS) diff --git a/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Generate_CSS_PropertyID_h.cpp b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Generate_CSS_PropertyID_h.cpp new file mode 100644 index 0000000000..ba5a7c3562 --- /dev/null +++ b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Generate_CSS_PropertyID_h.cpp @@ -0,0 +1,61 @@ +#include <AK/JsonObject.h> +#include <AK/StringBuilder.h> +#include <LibCore/CFile.h> +#include <ctype.h> +#include <stdio.h> + +static String title_casify(const String& dashy_name) +{ + auto parts = dashy_name.split('-'); + StringBuilder builder; + for (auto& part : parts) { + if (part.is_empty()) + continue; + builder.append(toupper(part[0])); + if (part.length() == 1) + continue; + builder.append(part.substring_view(1, part.length() - 1)); + } + return builder.to_string(); +} + +int main(int argc, char** argv) +{ + if (argc != 2) { + fprintf(stderr, "usage: %s <path/to/CSS/Properties.json>\n", argv[0]); + return 1; + } + auto file = CFile::construct(argv[1]); + if (!file->open(CIODevice::ReadOnly)) + return 1; + + auto json = JsonValue::from_string(file->read_all()); + ASSERT(json.is_object()); + + dbg() << "#pragma once"; + dbg() << "#include <AK/StringView.h>"; + dbg() << "#include <AK/Traits.h>"; + + dbg() << "namespace CSS {"; + dbg() << "enum class PropertyID {"; + dbg() << " Invalid,"; + + json.as_object().for_each_member([&](auto& name, auto& value) { + ASSERT(value.is_object()); + dbg() << " " << title_casify(name) << ","; + }); + + dbg() << "};\n\ +PropertyID property_id_from_string(const StringView&);\n\ +const char* string_from_property_id(PropertyID);\n\ +}\n\ +\n\ +namespace AK {\n\ +template<>\n\ +struct Traits<CSS::PropertyID> : public GenericTraits<CSS::PropertyID> {\n\ + static unsigned hash(CSS::PropertyID property_id) { return int_hash((unsigned)property_id); }\n\ +};\n\ +}\n"; + + return 0; +} diff --git a/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Makefile b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Makefile new file mode 100644 index 0000000000..783256d9e9 --- /dev/null +++ b/Libraries/LibHTML/CodeGenerators/Generate_CSS_PropertyID_h/Makefile @@ -0,0 +1,33 @@ +PROGRAM = Generate_CSS_PropertyID_h + +OBJS = \ + Generate_CSS_PropertyID_h.o \ + $(SERENITY_ROOT)/AK/String.o \ + $(SERENITY_ROOT)/AK/StringImpl.o \ + $(SERENITY_ROOT)/AK/StringBuilder.o \ + $(SERENITY_ROOT)/AK/StringView.o \ + $(SERENITY_ROOT)/AK/JsonValue.o \ + $(SERENITY_ROOT)/AK/JsonParser.o \ + $(SERENITY_ROOT)/AK/LogStream.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CIODevice.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CFile.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CObject.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CEvent.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CSocket.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CLocalSocket.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CNotifier.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CLocalServer.o \ + $(SERENITY_ROOT)/Libraries/LibCore/CEventLoop.o + +all: $(PROGRAM) + +CXXFLAGS = -std=c++17 -Wall -Wextra + +%.o: %.cpp + $(PRE_CXX) $(CXX) $(CXXFLAGS) -I../ -I$(SERENITY_ROOT)/ -I$(SERENITY_ROOT)/Libraries/ -o $@ -c $< + +$(PROGRAM): $(OBJS) + $(CXX) $(LDFLAGS) -I../ -I$(SERENITY_ROOT)/ -I$(SERENITY_ROOT)/Libraries/ -o $(PROGRAM) $(OBJS) + +clean: + rm -f $(PROGRAM) $(OBJS) diff --git a/Libraries/LibHTML/Dump.cpp b/Libraries/LibHTML/Dump.cpp index 7d3cd81769..19032d448f 100644 --- a/Libraries/LibHTML/Dump.cpp +++ b/Libraries/LibHTML/Dump.cpp @@ -1,4 +1,5 @@ #include <AK/Utf8View.h> +#include <LibHTML/CSS/PropertyID.h> #include <LibHTML/CSS/StyleSheet.h> #include <LibHTML/DOM/Comment.h> #include <LibHTML/DOM/Document.h> @@ -128,7 +129,7 @@ void dump_tree(const LayoutNode& layout_node) layout_node.style().for_each_property([&](auto property_id, auto& value) { for (int i = 0; i < indent; ++i) dbgprintf(" "); - dbgprintf(" (CSS::PropertyID(%u): %s)\n", (unsigned)property_id, value.to_string().characters()); + dbgprintf(" (%s: %s)\n", CSS::string_from_property_id(property_id), value.to_string().characters()); }); ++indent; diff --git a/Libraries/LibHTML/Makefile.shared b/Libraries/LibHTML/Makefile.shared index 9c06ef23f8..41359c9f6d 100644 --- a/Libraries/LibHTML/Makefile.shared +++ b/Libraries/LibHTML/Makefile.shared @@ -22,6 +22,7 @@ LIBHTML_OBJS = \ DOM/Text.o \ DOM/DocumentType.o \ DOM/ElementFactory.o \ + CSS/PropertyID.o \ CSS/Selector.o \ CSS/StyleSheet.o \ CSS/StyleRule.o \ @@ -59,21 +60,36 @@ LIBHTML_OBJS = \ Dump.o GENERATED_SOURCES = \ - CSS/DefaultStyleSheetSource.cpp + CSS/DefaultStyleSheetSource.cpp \ + CSS/PropertyID.h \ + CSS/PropertyID.cpp OBJS = $(EXTRA_OBJS) $(LIBHTML_OBJS) LIBRARY = libhtml.a DEFINES += -DUSERLAND +Dump.cpp: CSS/PropertyID.h +Parser/CSSParser.cpp: CSS/PropertyID.h + CSS/DefaultStyleSheetSource.cpp: CSS/Default.css Scripts/GenerateStyleSheetSource.sh @echo "GENERATE $@"; Scripts/GenerateStyleSheetSource.sh default_stylesheet_source $< > $@ +CSS/PropertyID.h: CSS/Properties.json CodeGenerators/Generate_CSS_PropertyID_h/Generate_CSS_PropertyID_h.cpp + make -C CodeGenerators/Generate_CSS_PropertyID_h + @echo "GENERATE $@"; CodeGenerators/Generate_CSS_PropertyID_h/Generate_CSS_PropertyID_h $< > $@ + +CSS/PropertyID.cpp: CSS/Properties.json CodeGenerators/Generate_CSS_PropertyID_cpp/Generate_CSS_PropertyID_cpp.cpp CSS/PropertyID.h + make -C CodeGenerators/Generate_CSS_PropertyID_cpp + @echo "GENERATE $@"; CodeGenerators/Generate_CSS_PropertyID_cpp/Generate_CSS_PropertyID_cpp $< > $@ + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< -include $(OBJS:%.o=%.d) clean: + make -C CodeGenerators/Generate_CSS_PropertyID_h clean + make -C CodeGenerators/Generate_CSS_PropertyID_cpp clean @echo "CLEAN"; rm -f $(LIBRARY) $(OBJS) *.d $(GENERATED_SOURCES) diff --git a/Libraries/LibHTML/Parser/CSSParser.cpp b/Libraries/LibHTML/Parser/CSSParser.cpp index 4d8e8e0f3f..97ec907304 100644 --- a/Libraries/LibHTML/Parser/CSSParser.cpp +++ b/Libraries/LibHTML/Parser/CSSParser.cpp @@ -1,4 +1,5 @@ #include <AK/HashMap.h> +#include <LibHTML/CSS/PropertyID.h> #include <LibHTML/CSS/StyleSheet.h> #include <LibHTML/Parser/CSSParser.h> #include <ctype.h> @@ -48,55 +49,6 @@ NonnullRefPtr<StyleValue> parse_css_value(const StringView& view) return StringStyleValue::create(string); } -static CSS::PropertyID parse_css_property_id(const StringView& string) -{ - static HashMap<String, CSS::PropertyID> map; - if (map.is_empty()) { - map.set("background-color", CSS::PropertyID::BackgroundColor); - map.set("border-bottom-style", CSS::PropertyID::BorderBottomStyle); - map.set("border-bottom-width", CSS::PropertyID::BorderBottomWidth); - map.set("border-collapse", CSS::PropertyID::BorderCollapse); - map.set("border-left-style", CSS::PropertyID::BorderLeftStyle); - map.set("border-left-width", CSS::PropertyID::BorderLeftWidth); - map.set("border-right-style", CSS::PropertyID::BorderRightStyle); - map.set("border-right-width", CSS::PropertyID::BorderRightWidth); - map.set("border-spacing", CSS::PropertyID::BorderSpacing); - map.set("border-top-style", CSS::PropertyID::BorderTopStyle); - map.set("border-top-width", CSS::PropertyID::BorderTopWidth); - map.set("color", CSS::PropertyID::Color); - map.set("display", CSS::PropertyID::Display); - map.set("font-family", CSS::PropertyID::FontFamily); - map.set("font-size", CSS::PropertyID::FontSize); - map.set("font-style", CSS::PropertyID::FontStyle); - map.set("font-variant", CSS::PropertyID::FontVariant); - map.set("font-weight", CSS::PropertyID::FontWeight); - map.set("height", CSS::PropertyID::Height); - map.set("letter-spacing", CSS::PropertyID::LetterSpacing); - map.set("line-height", CSS::PropertyID::LineHeight); - map.set("list-style", CSS::PropertyID::ListStyle); - map.set("list-style-image", CSS::PropertyID::ListStyleImage); - map.set("list-style-position", CSS::PropertyID::ListStylePosition); - map.set("list-style-type", CSS::PropertyID::ListStyleType); - map.set("margin-bottom", CSS::PropertyID::MarginBottom); - map.set("margin-left", CSS::PropertyID::MarginLeft); - map.set("margin-right", CSS::PropertyID::MarginRight); - map.set("margin-top", CSS::PropertyID::MarginTop); - map.set("padding-bottom", CSS::PropertyID::PaddingBottom); - map.set("padding-left", CSS::PropertyID::PaddingLeft); - map.set("padding-right", CSS::PropertyID::PaddingRight); - map.set("padding-top", CSS::PropertyID::PaddingTop); - map.set("text-align", CSS::PropertyID::TextAlign); - map.set("text-decoration", CSS::PropertyID::TextDecoration); - map.set("text-indent", CSS::PropertyID::TextIndent); - map.set("text-transform", CSS::PropertyID::TextTransform); - map.set("visibility", CSS::PropertyID::Visibility); - map.set("white-space", CSS::PropertyID::WhiteSpace); - map.set("width", CSS::PropertyID::Width); - map.set("word-spacing", CSS::PropertyID::WordSpacing); - } - return map.get(string).value_or(CSS::PropertyID::Invalid); -} - class CSSParser { public: CSSParser(const StringView& input) @@ -331,7 +283,8 @@ public: if (peek() && peek() != '}') consume_specific(';'); - return StyleProperty { parse_css_property_id(property_name), parse_css_value(property_value), is_important }; + auto property_id = CSS::property_id_from_string(property_name); + return StyleProperty { property_id, parse_css_value(property_value), is_important }; } void parse_declaration() |