| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | #include <LibHTML/CSS/StyleResolver.h>
 | 
					
						
							|  |  |  | #include <LibHTML/CSS/StyleSheet.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  | #include <LibHTML/CSS/StyledNode.h>
 | 
					
						
							|  |  |  | #include <LibHTML/DOM/Document.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  | #include <LibHTML/DOM/Element.h>
 | 
					
						
							|  |  |  | #include <LibHTML/Dump.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | StyleResolver::StyleResolver(Document& document) | 
					
						
							|  |  |  |     : m_document(document) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | StyleResolver::~StyleResolver() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  | static bool matches(const Selector& selector, const Element& element) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // FIXME: Support compound selectors.
 | 
					
						
							|  |  |  |     ASSERT(selector.components().size() == 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto& component = selector.components().first(); | 
					
						
							|  |  |  |     switch (component.type) { | 
					
						
							|  |  |  |     case Selector::Component::Type::Id: | 
					
						
							|  |  |  |         return component.value == element.attribute("id"); | 
					
						
							|  |  |  |     case Selector::Component::Type::Class: | 
					
						
							|  |  |  |         return element.has_class(component.value); | 
					
						
							|  |  |  |     case Selector::Component::Type::TagName: | 
					
						
							|  |  |  |         return component.value == element.tag_name(); | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         ASSERT_NOT_REACHED(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NonnullRefPtrVector<StyleRule> StyleResolver::collect_matching_rules(const Element& element) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     NonnullRefPtrVector<StyleRule> matching_rules; | 
					
						
							| 
									
										
										
										
											2019-06-29 21:42:07 +02:00
										 |  |  |     for (auto& sheet : document().stylesheets()) { | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |         for (auto& rule : sheet.rules()) { | 
					
						
							|  |  |  |             for (auto& selector : rule.selectors()) { | 
					
						
							|  |  |  |                 if (matches(selector, element)) { | 
					
						
							|  |  |  |                     matching_rules.append(rule); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     printf("Rules matching Element{%p}\n", &element); | 
					
						
							|  |  |  |     for (auto& rule : matching_rules) { | 
					
						
							|  |  |  |         dump_rule(rule); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return matching_rules; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  | NonnullRefPtr<StyledNode> StyleResolver::create_styled_node(const Document& document) | 
					
						
							| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  |     return StyledNode::create(document); | 
					
						
							| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  | NonnullRefPtr<StyledNode> StyleResolver::create_styled_node(const Element& element) | 
					
						
							| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  |     auto style = StyledNode::create(element); | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |     auto matching_rules = collect_matching_rules(element); | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  |     for (auto& rule : matching_rules) { | 
					
						
							|  |  |  |         for (auto& declaration : rule.declarations()) { | 
					
						
							|  |  |  |             style->set_property(declaration.property_name(), declaration.value()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |     return style; | 
					
						
							| 
									
										
										
										
											2019-06-27 17:47:59 +02:00
										 |  |  | } |