mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	LibHTML: Add support for <body bgcolor="#rrggbb" text="#rrggbb">
This patch implements basic support for presentational hints, which are old-school HTML attributes that affect style. You add support for a presentational hint attribute by overriding Element::apply_presentational_hints(StyleProperties&) and setting all of the corresponding CSS properties as appropriate. To make the background color fill the entire document, not just the bounds of the <body> element's LayoutNode, we special-case it in the HtmlView::paint_event() code for now. I'm not entirely sure what the nicest solution would be, but I'm sure we'll discover it eventually.
This commit is contained in:
		
							parent
							
								
									a7ca719c4e
								
							
						
					
					
						commit
						9808d35554
					
				
					 12 changed files with 94 additions and 5 deletions
				
			
		|  | @ -69,6 +69,8 @@ NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& eleme | |||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     element.apply_presentational_hints(*style_properties); | ||||
| 
 | ||||
|     auto matching_rules = collect_matching_rules(element); | ||||
|     for (auto& rule : matching_rules) { | ||||
|         for (auto& property : rule.declaration().properties()) { | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <LibHTML/CSS/StyleResolver.h> | ||||
| #include <LibHTML/DOM/Document.h> | ||||
| #include <LibHTML/DOM/Element.h> | ||||
| #include <LibHTML/DOM/HTMLBodyElement.h> | ||||
| #include <LibHTML/DOM/HTMLHeadElement.h> | ||||
| #include <LibHTML/DOM/HTMLHtmlElement.h> | ||||
| #include <LibHTML/DOM/HTMLTitleElement.h> | ||||
|  | @ -52,6 +53,14 @@ const HTMLHeadElement* Document::head() const | |||
|     return static_cast<const HTMLHeadElement*>(html->first_child_with_tag_name("head")); | ||||
| } | ||||
| 
 | ||||
| const HTMLBodyElement* Document::body() const | ||||
| { | ||||
|     auto* html = document_element(); | ||||
|     if (!html) | ||||
|         return nullptr; | ||||
|     return static_cast<const HTMLBodyElement*>(html->first_child_with_tag_name("body")); | ||||
| } | ||||
| 
 | ||||
| String Document::title() const | ||||
| { | ||||
|     auto* head_element = head(); | ||||
|  | @ -73,3 +82,20 @@ void Document::attach_to_frame(Badge<Frame>, Frame& frame) | |||
| void Document::detach_from_frame(Badge<Frame>, Frame&) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| Color Document::background_color() const | ||||
| { | ||||
|     auto* body_element = body(); | ||||
|     if (!body_element) | ||||
|         return Color::White; | ||||
| 
 | ||||
|     auto* body_layout_node = body_element->layout_node(); | ||||
|     if (!body_layout_node) | ||||
|         return Color::White; | ||||
| 
 | ||||
|     auto background_color = body_layout_node->style().property("background-color"); | ||||
|     if (!background_color.has_value() || !background_color.value()->is_color()) | ||||
|         return Color::White; | ||||
| 
 | ||||
|     return background_color.value()->to_color(); | ||||
| } | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| #include <LibHTML/DOM/ParentNode.h> | ||||
| 
 | ||||
| class Frame; | ||||
| class HTMLBodyElement; | ||||
| class HTMLHtmlElement; | ||||
| class HTMLHeadElement; | ||||
| class LayoutNode; | ||||
|  | @ -35,6 +36,7 @@ public: | |||
| 
 | ||||
|     const HTMLHtmlElement* document_element() const; | ||||
|     const HTMLHeadElement* head() const; | ||||
|     const HTMLBodyElement* body() const; | ||||
| 
 | ||||
|     String title() const; | ||||
| 
 | ||||
|  | @ -44,6 +46,8 @@ public: | |||
|     Frame* frame() { return m_frame.ptr(); } | ||||
|     const Frame* frame() const { return m_frame.ptr(); } | ||||
| 
 | ||||
|     Color background_color() const; | ||||
| 
 | ||||
| private: | ||||
|     OwnPtr<StyleResolver> m_style_resolver; | ||||
|     NonnullRefPtrVector<StyleSheet> m_sheets; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <LibHTML/DOM/ParentNode.h> | ||||
| #include <AK/String.h> | ||||
| #include <LibHTML/DOM/ParentNode.h> | ||||
| 
 | ||||
| class Attribute { | ||||
| public: | ||||
|  | @ -42,6 +42,8 @@ public: | |||
| 
 | ||||
|     bool has_class(const StringView&) const; | ||||
| 
 | ||||
|     virtual void apply_presentational_hints(StyleProperties&) const {} | ||||
| 
 | ||||
| private: | ||||
|     Attribute* find_attribute(const String& name); | ||||
|     const Attribute* find_attribute(const String& name) const; | ||||
|  | @ -49,4 +51,3 @@ private: | |||
|     String m_tag_name; | ||||
|     Vector<Attribute> m_attributes; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										27
									
								
								Libraries/LibHTML/DOM/HTMLBodyElement.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Libraries/LibHTML/DOM/HTMLBodyElement.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| #include <LibHTML/CSS/StyleProperties.h> | ||||
| #include <LibHTML/CSS/StyleValue.h> | ||||
| #include <LibHTML/DOM/HTMLBodyElement.h> | ||||
| 
 | ||||
| HTMLBodyElement::HTMLBodyElement(Document& document, const String& tag_name) | ||||
|     : HTMLElement(document, tag_name) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| HTMLBodyElement::~HTMLBodyElement() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void HTMLBodyElement::apply_presentational_hints(StyleProperties& style) const | ||||
| { | ||||
|     for_each_attribute([&](auto& name, auto& value) { | ||||
|         if (name == "bgcolor") { | ||||
|             auto color = Color::from_string(value); | ||||
|             if (color.has_value()) | ||||
|                 style.set_property("background-color", ColorStyleValue::create(color.value())); | ||||
|         } else if (name == "text") { | ||||
|             auto color = Color::from_string(value); | ||||
|             if (color.has_value()) | ||||
|                 style.set_property("color", ColorStyleValue::create(color.value())); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
							
								
								
									
										11
									
								
								Libraries/LibHTML/DOM/HTMLBodyElement.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Libraries/LibHTML/DOM/HTMLBodyElement.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <LibHTML/DOM/HTMLElement.h> | ||||
| 
 | ||||
| class HTMLBodyElement : public HTMLElement { | ||||
| public: | ||||
|     HTMLBodyElement(Document&, const String& tag_name); | ||||
|     virtual ~HTMLBodyElement() override; | ||||
| 
 | ||||
|     virtual void apply_presentational_hints(StyleProperties&) const override; | ||||
| }; | ||||
|  | @ -27,6 +27,8 @@ RefPtr<LayoutNode> Node::create_layout_node(const StyleResolver& resolver, const | |||
|     if (is_text()) | ||||
|         return adopt(*new LayoutText(static_cast<const Text&>(*this))); | ||||
| 
 | ||||
|     ASSERT(is_element()); | ||||
| 
 | ||||
|     auto style_properties = resolver.resolve_style(static_cast<const Element&>(*this), parent_properties); | ||||
| 
 | ||||
|     auto display_property = style_properties->property("display"); | ||||
|  |  | |||
|  | @ -58,9 +58,15 @@ public: | |||
|     virtual void inserted_into(Node&) {} | ||||
|     virtual void removed_from(Node&) {} | ||||
| 
 | ||||
|     const LayoutNode* layout_node() const { return m_layout_node; } | ||||
|     LayoutNode* layout_node() { return m_layout_node; } | ||||
| 
 | ||||
|     void set_layout_node(Badge<LayoutNode>, LayoutNode* layout_node) const { m_layout_node = layout_node; } | ||||
| 
 | ||||
| protected: | ||||
|     Node(Document&, NodeType); | ||||
| 
 | ||||
|     Document& m_document; | ||||
|     mutable LayoutNode* m_layout_node { nullptr }; | ||||
|     NodeType m_type { NodeType::INVALID }; | ||||
| }; | ||||
|  |  | |||
|  | @ -78,13 +78,15 @@ void HtmlView::paint_event(GPaintEvent& event) | |||
|     painter.add_clip_rect(widget_inner_rect()); | ||||
|     painter.add_clip_rect(event.rect()); | ||||
| 
 | ||||
|     painter.fill_rect(event.rect(), background_color()); | ||||
|     if (!m_layout_root) { | ||||
|         painter.fill_rect(event.rect(), background_color()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     painter.translate(frame_thickness(), frame_thickness()); | ||||
|     painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); | ||||
| 
 | ||||
|     if (!m_layout_root) | ||||
|         return; | ||||
|     painter.fill_rect(rect(), m_document->background_color()); | ||||
| 
 | ||||
|     RenderingContext context { painter }; | ||||
|     m_layout_root->render(context); | ||||
|  |  | |||
|  | @ -11,10 +11,14 @@ LayoutNode::LayoutNode(const Node* node, RefPtr<StyleProperties> style_propertie | |||
|     : m_node(node) | ||||
|     , m_style_properties(move(style_properties)) | ||||
| { | ||||
|     if (m_node) | ||||
|         m_node->set_layout_node({}, this); | ||||
| } | ||||
| 
 | ||||
| LayoutNode::~LayoutNode() | ||||
| { | ||||
|     if (m_node) | ||||
|         m_node->set_layout_node({}, nullptr); | ||||
| } | ||||
| 
 | ||||
| void LayoutNode::layout() | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ LIBHTML_OBJS = \ | |||
|     DOM/HTMLHtmlElement.o \ | ||||
|     DOM/HTMLStyleElement.o \ | ||||
|     DOM/HTMLTitleElement.o \ | ||||
|     DOM/HTMLBodyElement.o \ | ||||
|     DOM/Document.o \ | ||||
|     DOM/Text.o \ | ||||
|     CSS/Selector.o \ | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include <LibHTML/DOM/Element.h> | ||||
| #include <LibHTML/DOM/HTMLAnchorElement.h> | ||||
| #include <LibHTML/DOM/HTMLHRElement.h> | ||||
| #include <LibHTML/DOM/HTMLBodyElement.h> | ||||
| #include <LibHTML/DOM/HTMLHeadElement.h> | ||||
| #include <LibHTML/DOM/HTMLHeadingElement.h> | ||||
| #include <LibHTML/DOM/HTMLHtmlElement.h> | ||||
|  | @ -23,6 +24,8 @@ static NonnullRefPtr<Element> create_element(Document& document, const String& t | |||
|         return adopt(*new HTMLHtmlElement(document, tag_name)); | ||||
|     if (lowercase_tag_name == "head") | ||||
|         return adopt(*new HTMLHeadElement(document, tag_name)); | ||||
|     if (lowercase_tag_name == "body") | ||||
|         return adopt(*new HTMLBodyElement(document, tag_name)); | ||||
|     if (lowercase_tag_name == "hr") | ||||
|         return adopt(*new HTMLHRElement(document, tag_name)); | ||||
|     if (lowercase_tag_name == "style") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling