mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:52:45 +00:00 
			
		
		
		
	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. :^)
This commit is contained in:
		
							parent
							
								
									dcd10149fe
								
							
						
					
					
						commit
						e6e41e4fb8
					
				
					 10 changed files with 529 additions and 115 deletions
				
			
		
							
								
								
									
										2
									
								
								Libraries/LibHTML/CSS/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								Libraries/LibHTML/CSS/.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +1,3 @@ | |||
| DefaultStyleSheetSource.cpp | ||||
| PropertyID.cpp | ||||
| PropertyID.h | ||||
|  |  | |||
							
								
								
									
										312
									
								
								Libraries/LibHTML/CSS/Properties.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								Libraries/LibHTML/CSS/Properties.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -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" | ||||
|   } | ||||
| } | ||||
|  | @ -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); } | ||||
| }; | ||||
| } | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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) | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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) | ||||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling