mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:12:45 +00:00 
			
		
		
		
	LibWeb: Move border width and color into LayoutStyle
To make this possible, I also had to give each LayoutNode a Document& so it can resolve document-specific colors correctly. There's probably ways to avoid having this extra member by resolving colors later, but this works for now.
This commit is contained in:
		
							parent
							
								
									4b2ac34725
								
							
						
					
					
						commit
						440b4ece22
					
				
					 57 changed files with 173 additions and 190 deletions
				
			
		|  | @ -267,7 +267,7 @@ void Document::update_layout() | |||
|     layout(); | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> Document::create_layout_node(const StyleProperties*) const | ||||
| RefPtr<LayoutNode> Document::create_layout_node(const StyleProperties*) | ||||
| { | ||||
|     return adopt(*new LayoutDocument(*this, StyleProperties::create())); | ||||
| } | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ public: | |||
|     void set_quirks_mode(bool mode) { m_quirks_mode = mode; } | ||||
| 
 | ||||
| private: | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     OwnPtr<StyleResolver> m_style_resolver; | ||||
|     RefPtr<CSS::StyleSheetList> m_style_sheets; | ||||
|  |  | |||
|  | @ -107,7 +107,7 @@ bool Element::has_class(const FlyString& class_name) const | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     auto style = document().style_resolver().resolve_style(*this, parent_style); | ||||
|     const_cast<Element&>(*this).m_resolved_style = style; | ||||
|  | @ -120,21 +120,21 @@ RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_sty | |||
|         return nullptr; | ||||
| 
 | ||||
|     if (display == CSS::Display::Block) | ||||
|         return adopt(*new LayoutBlock(this, move(style))); | ||||
|         return adopt(*new LayoutBlock(document(), this, move(style))); | ||||
|     if (display == CSS::Display::Inline) | ||||
|         return adopt(*new LayoutInline(*this, move(style))); | ||||
|         return adopt(*new LayoutInline(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::ListItem) | ||||
|         return adopt(*new LayoutListItem(*this, move(style))); | ||||
|         return adopt(*new LayoutListItem(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::Table) | ||||
|         return adopt(*new LayoutTable(*this, move(style))); | ||||
|         return adopt(*new LayoutTable(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::TableRow) | ||||
|         return adopt(*new LayoutTableRow(*this, move(style))); | ||||
|         return adopt(*new LayoutTableRow(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::TableCell) | ||||
|         return adopt(*new LayoutTableCell(*this, move(style))); | ||||
|         return adopt(*new LayoutTableCell(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::TableRowGroup) | ||||
|         return adopt(*new LayoutTableRowGroup(*this, move(style))); | ||||
|         return adopt(*new LayoutTableRowGroup(document(), *this, move(style))); | ||||
|     if (display == CSS::Display::InlineBlock) { | ||||
|         auto inline_block = adopt(*new LayoutBlock(this, move(style))); | ||||
|         auto inline_block = adopt(*new LayoutBlock(document(), this, move(style))); | ||||
|         inline_block->set_inline(true); | ||||
|         return inline_block; | ||||
|     } | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ public: | |||
|     void set_class_name(const String& value) { set_attribute(HTML::AttributeNames::class_, value); } | ||||
| 
 | ||||
| protected: | ||||
|     RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
| private: | ||||
|     Attribute* find_attribute(const FlyString& name); | ||||
|  |  | |||
|  | @ -38,9 +38,9 @@ HTMLBRElement::~HTMLBRElement() | |||
| { | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLBRElement::create_layout_node(const StyleProperties*) const | ||||
| RefPtr<LayoutNode> HTMLBRElement::create_layout_node(const StyleProperties*) | ||||
| { | ||||
|     return adopt(*new LayoutBreak(*this)); | ||||
|     return adopt(*new LayoutBreak(document(), *this)); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ public: | |||
|     HTMLBRElement(Document&, const FlyString& tag_name); | ||||
|     virtual ~HTMLBRElement() override; | ||||
| 
 | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
|  |  | |||
|  | @ -55,12 +55,12 @@ unsigned HTMLCanvasElement::height() const | |||
|     return attribute(HTML::AttributeNames::height).to_uint().value_or(150); | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLCanvasElement::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> HTMLCanvasElement::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     auto style = document().style_resolver().resolve_style(*this, parent_style); | ||||
|     if (style->display() == CSS::Display::None) | ||||
|         return nullptr; | ||||
|     return adopt(*new LayoutCanvas(*this, move(style))); | ||||
|     return adopt(*new LayoutCanvas(document(), *this, move(style))); | ||||
| } | ||||
| 
 | ||||
| CanvasRenderingContext2D* HTMLCanvasElement::get_context(String type) | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ public: | |||
|     unsigned height() const; | ||||
| 
 | ||||
| private: | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     RefPtr<Gfx::Bitmap> m_bitmap; | ||||
|     RefPtr<CanvasRenderingContext2D> m_context; | ||||
|  |  | |||
|  | @ -50,10 +50,10 @@ HTMLIFrameElement::~HTMLIFrameElement() | |||
| { | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLIFrameElement::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> HTMLIFrameElement::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     auto style = document().style_resolver().resolve_style(*this, parent_style); | ||||
|     return adopt(*new LayoutFrame(*this, move(style))); | ||||
|     return adopt(*new LayoutFrame(document(), *this, move(style))); | ||||
| } | ||||
| 
 | ||||
| void HTMLIFrameElement::document_did_attach_to_frame(Frame& frame) | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ public: | |||
|     HTMLIFrameElement(Document&, const FlyString& tag_name); | ||||
|     virtual ~HTMLIFrameElement() override; | ||||
| 
 | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     Frame* hosted_frame() { return m_hosted_frame; } | ||||
|     const Frame* hosted_frame() const { return m_hosted_frame; } | ||||
|  |  | |||
|  | @ -68,12 +68,12 @@ void HTMLImageElement::parse_attribute(const FlyString& name, const String& valu | |||
|         m_image_loader.load(document().complete_url(value)); | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     auto style = document().style_resolver().resolve_style(*this, parent_style); | ||||
|     if (style->display() == CSS::Display::None) | ||||
|         return nullptr; | ||||
|     return adopt(*new LayoutImage(*this, move(style), m_image_loader)); | ||||
|     return adopt(*new LayoutImage(document(), *this, move(style), m_image_loader)); | ||||
| } | ||||
| 
 | ||||
| const Gfx::Bitmap* HTMLImageElement::bitmap() const | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ public: | |||
| private: | ||||
|     void animate(); | ||||
| 
 | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     ImageLoader m_image_loader; | ||||
| }; | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ HTMLInputElement::~HTMLInputElement() | |||
| { | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     ASSERT(document().frame()); | ||||
|     auto& frame = *document().frame(); | ||||
|  | @ -97,7 +97,7 @@ RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties* p | |||
|         widget = text_box; | ||||
|     } | ||||
| 
 | ||||
|     return adopt(*new LayoutWidget(*this, *widget)); | ||||
|     return adopt(*new LayoutWidget(document(), *this, *widget)); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ public: | |||
|     HTMLInputElement(Document&, const FlyString& tag_name); | ||||
|     virtual ~HTMLInputElement() override; | ||||
| 
 | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     String type() const { return attribute(HTML::AttributeNames::type); } | ||||
|     String value() const { return attribute(HTML::AttributeNames::value); } | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ void HTMLObjectElement::parse_attribute(const FlyString& name, const String& val | |||
|         m_image_loader.load(document().complete_url(value)); | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> HTMLObjectElement::create_layout_node(const StyleProperties* parent_style) const | ||||
| RefPtr<LayoutNode> HTMLObjectElement::create_layout_node(const StyleProperties* parent_style) | ||||
| { | ||||
|     if (m_should_show_fallback_content) | ||||
|         return HTMLElement::create_layout_node(parent_style); | ||||
|  | @ -70,7 +70,7 @@ RefPtr<LayoutNode> HTMLObjectElement::create_layout_node(const StyleProperties* | |||
|     if (style->display() == CSS::Display::None) | ||||
|         return nullptr; | ||||
|     if (m_image_loader.has_image()) | ||||
|         return adopt(*new LayoutImage(*this, move(style), m_image_loader)); | ||||
|         return adopt(*new LayoutImage(document(), *this, move(style), m_image_loader)); | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ public: | |||
|     String type() const { return attribute(HTML::AttributeNames::type); } | ||||
| 
 | ||||
| private: | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| 
 | ||||
|     ImageLoader m_image_loader; | ||||
|     bool m_should_show_fallback_content { false }; | ||||
|  |  | |||
|  | @ -110,7 +110,7 @@ const Element* Node::previous_element_sibling() const | |||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> Node::create_layout_node(const StyleProperties*) const | ||||
| RefPtr<LayoutNode> Node::create_layout_node(const StyleProperties*) | ||||
| { | ||||
|     return nullptr; | ||||
| } | ||||
|  |  | |||
|  | @ -85,7 +85,7 @@ public: | |||
|     RefPtr<Node> append_child(NonnullRefPtr<Node>, bool notify = true); | ||||
|     RefPtr<Node> insert_before(NonnullRefPtr<Node> node, RefPtr<Node> child, bool notify = true); | ||||
| 
 | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style); | ||||
| 
 | ||||
|     virtual FlyString node_name() const = 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,9 +38,9 @@ Text::~Text() | |||
| { | ||||
| } | ||||
| 
 | ||||
| RefPtr<LayoutNode> Text::create_layout_node(const StyleProperties*) const | ||||
| RefPtr<LayoutNode> Text::create_layout_node(const StyleProperties*) | ||||
| { | ||||
|     return adopt(*new LayoutText(*this)); | ||||
|     return adopt(*new LayoutText(document(), *this)); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ public: | |||
|     virtual FlyString node_name() const override { return "#text"; } | ||||
| 
 | ||||
| private: | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; | ||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||
| }; | ||||
| 
 | ||||
| template<> | ||||
|  |  | |||
|  | @ -38,8 +38,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutBlock::LayoutBlock(const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(node, move(style)) | ||||
| LayoutBlock::LayoutBlock(Document& document, const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(document, node, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -50,7 +50,7 @@ LayoutBlock::~LayoutBlock() | |||
| LayoutNode& LayoutBlock::inline_wrapper() | ||||
| { | ||||
|     if (!last_child() || !last_child()->is_block() || last_child()->node() != nullptr) { | ||||
|         append_child(adopt(*new LayoutBlock(nullptr, style_for_anonymous_block()))); | ||||
|         append_child(adopt(*new LayoutBlock(document(), nullptr, style_for_anonymous_block()))); | ||||
|         last_child()->set_children_are_inline(true); | ||||
|     } | ||||
|     return *last_child(); | ||||
|  | @ -275,22 +275,20 @@ void LayoutBlock::layout_inline_children(LayoutMode layout_mode) | |||
| 
 | ||||
| void LayoutBlock::compute_width_for_absolutely_positioned_block() | ||||
| { | ||||
|     auto& specified_style = this->specified_style(); | ||||
|     auto& containing_block = *this->containing_block(); | ||||
|     auto zero_value = Length::make_px(0); | ||||
| 
 | ||||
|     Length margin_left = Length::make_auto(); | ||||
|     Length margin_right = Length::make_auto(); | ||||
|     Length border_left = Length::make_auto(); | ||||
|     Length border_right = Length::make_auto(); | ||||
|     const auto border_left = style().border_left().width; | ||||
|     const auto border_right = style().border_right().width; | ||||
|     Length padding_left = Length::make_auto(); | ||||
|     Length padding_right = Length::make_auto(); | ||||
| 
 | ||||
|     auto try_compute_width = [&](const auto& a_width) { | ||||
|         margin_left = style().margin().left.resolved(zero_value, *this, containing_block.width()); | ||||
|         margin_right = style().margin().right.resolved(zero_value, *this, containing_block.width()); | ||||
|         border_left = specified_style.length_or_fallback(CSS::PropertyID::BorderLeftWidth, zero_value); | ||||
|         border_right = specified_style.length_or_fallback(CSS::PropertyID::BorderRightWidth, zero_value); | ||||
| 
 | ||||
|         padding_left = style().padding().left.resolved(zero_value, *this, containing_block.width()); | ||||
|         padding_right = style().padding().right.resolved(zero_value, *this, containing_block.width()); | ||||
| 
 | ||||
|  | @ -299,15 +297,15 @@ void LayoutBlock::compute_width_for_absolutely_positioned_block() | |||
|         auto width = a_width; | ||||
| 
 | ||||
|         auto solve_for_left = [&] { | ||||
|             return Length(containing_block.width() - margin_left.to_px(*this) - border_left.to_px(*this) - padding_left.to_px(*this) - width.to_px(*this) - padding_right.to_px(*this) - border_right.to_px(*this) - margin_right.to_px(*this) - right.to_px(*this), Length::Type::Px); | ||||
|             return Length(containing_block.width() - margin_left.to_px(*this) - border_left - padding_left.to_px(*this) - width.to_px(*this) - padding_right.to_px(*this) - border_right - margin_right.to_px(*this) - right.to_px(*this), Length::Type::Px); | ||||
|         }; | ||||
| 
 | ||||
|         auto solve_for_width = [&] { | ||||
|             return Length(containing_block.width() - left.to_px(*this) - margin_left.to_px(*this) - border_left.to_px(*this) - padding_left.to_px(*this) - padding_right.to_px(*this) - border_right.to_px(*this) - margin_right.to_px(*this) - right.to_px(*this), Length::Type::Px); | ||||
|             return Length(containing_block.width() - left.to_px(*this) - margin_left.to_px(*this) - border_left - padding_left.to_px(*this) - padding_right.to_px(*this) - border_right - margin_right.to_px(*this) - right.to_px(*this), Length::Type::Px); | ||||
|         }; | ||||
| 
 | ||||
|         auto solve_for_right = [&] { | ||||
|             return Length(containing_block.width() - left.to_px(*this) - margin_left.to_px(*this) - border_left.to_px(*this) - padding_left.to_px(*this) - width.to_px(*this) - padding_right.to_px(*this) - border_right.to_px(*this) - margin_right.to_px(*this), Length::Type::Px); | ||||
|             return Length(containing_block.width() - left.to_px(*this) - margin_left.to_px(*this) - border_left - padding_left.to_px(*this) - width.to_px(*this) - padding_right.to_px(*this) - border_right - margin_right.to_px(*this), Length::Type::Px); | ||||
|         }; | ||||
| 
 | ||||
|         // If all three of 'left', 'width', and 'right' are 'auto':
 | ||||
|  | @ -411,8 +409,8 @@ void LayoutBlock::compute_width_for_absolutely_positioned_block() | |||
| 
 | ||||
|     box_model().margin.left = margin_left; | ||||
|     box_model().margin.right = margin_right; | ||||
|     box_model().border.left = border_left; | ||||
|     box_model().border.right = border_right; | ||||
|     box_model().border.left = Length::make_px(border_left); | ||||
|     box_model().border.right = Length::make_px(border_right); | ||||
|     box_model().padding.left = padding_left; | ||||
|     box_model().padding.right = padding_right; | ||||
| } | ||||
|  | @ -422,13 +420,10 @@ void LayoutBlock::compute_width() | |||
|     if (is_absolutely_positioned()) | ||||
|         return compute_width_for_absolutely_positioned_block(); | ||||
| 
 | ||||
|     auto& specified_style = this->specified_style(); | ||||
|     auto zero_value = Length::make_px(0); | ||||
| 
 | ||||
|     Length margin_left = Length::make_auto(); | ||||
|     Length margin_right = Length::make_auto(); | ||||
|     Length border_left = Length::make_auto(); | ||||
|     Length border_right = Length::make_auto(); | ||||
|     Length padding_left = Length::make_auto(); | ||||
|     Length padding_right = Length::make_auto(); | ||||
| 
 | ||||
|  | @ -438,13 +433,11 @@ void LayoutBlock::compute_width() | |||
|         Length width = a_width; | ||||
|         margin_left = style().margin().left.resolved_or_zero(*this, containing_block.width()); | ||||
|         margin_right = style().margin().right.resolved_or_zero(*this, containing_block.width()); | ||||
|         border_left = specified_style.length_or_fallback(CSS::PropertyID::BorderLeftWidth, zero_value); | ||||
|         border_right = specified_style.length_or_fallback(CSS::PropertyID::BorderRightWidth, zero_value); | ||||
|         padding_left = style().padding().left.resolved_or_zero(*this, containing_block.width()); | ||||
|         padding_right = style().padding().right.resolved_or_zero(*this, containing_block.width()); | ||||
| 
 | ||||
|         float total_px = 0; | ||||
|         for (auto& value : { margin_left, border_left, padding_left, width, padding_right, border_right, margin_right }) { | ||||
|         float total_px = style().border_left().width + style().border_right().width; | ||||
|         for (auto& value : { margin_left, padding_left, width, padding_right, margin_right }) { | ||||
|             total_px += value.to_px(*this); | ||||
|         } | ||||
| 
 | ||||
|  | @ -506,8 +499,8 @@ void LayoutBlock::compute_width() | |||
|                 // block minus the used values of 'margin-left', 'border-left-width', 'padding-left',
 | ||||
|                 // 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
 | ||||
|                 float available_width = containing_block.width() | ||||
|                     - margin_left.to_px(*this) - border_left.to_px(*this) - padding_left.to_px(*this) | ||||
|                     - padding_right.to_px(*this) - border_right.to_px(*this) - margin_right.to_px(*this); | ||||
|                     - margin_left.to_px(*this) - style().border_left().width - padding_left.to_px(*this) | ||||
|                     - padding_right.to_px(*this) - style().border_right().width - margin_right.to_px(*this); | ||||
| 
 | ||||
|                 auto result = calculate_shrink_to_fit_width(); | ||||
| 
 | ||||
|  | @ -545,8 +538,8 @@ void LayoutBlock::compute_width() | |||
|     set_width(used_width.to_px(*this)); | ||||
|     box_model().margin.left = margin_left; | ||||
|     box_model().margin.right = margin_right; | ||||
|     box_model().border.left = border_left; | ||||
|     box_model().border.right = border_right; | ||||
|     box_model().border.left = Length::make_px(style().border_left().width); | ||||
|     box_model().border.right = Length::make_px(style().border_right().width); | ||||
|     box_model().padding.left = padding_left; | ||||
|     box_model().padding.right = padding_right; | ||||
| } | ||||
|  | @ -554,16 +547,15 @@ void LayoutBlock::compute_width() | |||
| void LayoutBlock::place_block_level_replaced_element_in_normal_flow(LayoutReplaced& box) | ||||
| { | ||||
|     ASSERT(!is_absolutely_positioned()); | ||||
|     auto& specified_style = box.specified_style(); | ||||
|     auto& containing_block = *this; | ||||
|     auto& replaced_element_box_model = box.box_model(); | ||||
| 
 | ||||
|     replaced_element_box_model.margin.top = style().margin().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.margin.bottom = style().margin().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.border.top = specified_style.length_or_fallback(CSS::PropertyID::BorderTopWidth, Length::make_px(0)); | ||||
|     replaced_element_box_model.border.bottom = specified_style.length_or_fallback(CSS::PropertyID::BorderBottomWidth, Length::make_px(0)); | ||||
|     replaced_element_box_model.padding.top = style().padding().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.padding.bottom = style().padding().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.margin.top = box.style().margin().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.margin.bottom = box.style().margin().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.border.top = Length::make_px(box.style().border_top().width); | ||||
|     replaced_element_box_model.border.bottom = Length::make_px(box.style().border_bottom().width); | ||||
|     replaced_element_box_model.padding.top = box.style().padding().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     replaced_element_box_model.padding.bottom = box.style().padding().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
| 
 | ||||
|     float x = replaced_element_box_model.margin.left.to_px(*this) | ||||
|         + replaced_element_box_model.border.left.to_px(*this) | ||||
|  | @ -608,7 +600,6 @@ LayoutBlock::ShrinkToFitResult LayoutBlock::calculate_shrink_to_fit_width() | |||
| 
 | ||||
| void LayoutBlock::place_block_level_non_replaced_element_in_normal_flow(LayoutBlock& block) | ||||
| { | ||||
|     auto& specified_style = block.specified_style(); | ||||
|     auto zero_value = Length::make_px(0); | ||||
|     auto& containing_block = *this; | ||||
|     auto& box = block.box_model(); | ||||
|  | @ -616,8 +607,8 @@ void LayoutBlock::place_block_level_non_replaced_element_in_normal_flow(LayoutBl | |||
| 
 | ||||
|     box.margin.top = style.margin().top.resolved(zero_value, *this, containing_block.width()); | ||||
|     box.margin.bottom = style.margin().bottom.resolved(zero_value, *this, containing_block.width()); | ||||
|     box.border.top = specified_style.length_or_fallback(CSS::PropertyID::BorderTopWidth, zero_value); | ||||
|     box.border.bottom = specified_style.length_or_fallback(CSS::PropertyID::BorderBottomWidth, zero_value); | ||||
|     box.border.top = Length::make_px(style.border_top().width); | ||||
|     box.border.bottom = Length::make_px(style.border_bottom().width); | ||||
|     box.padding.top = style.padding().top.resolved(zero_value, *this, containing_block.width()); | ||||
|     box.padding.bottom = style.padding().bottom.resolved(zero_value, *this, containing_block.width()); | ||||
| 
 | ||||
|  | @ -665,7 +656,6 @@ void LayoutBlock::place_block_level_non_replaced_element_in_normal_flow(LayoutBl | |||
| 
 | ||||
| void LayoutBlock::compute_height() | ||||
| { | ||||
|     auto& specified_style = this->specified_style(); | ||||
|     auto& containing_block = *this->containing_block(); | ||||
| 
 | ||||
|     auto specified_height = style().height().resolved_or_auto(*this, containing_block.height()); | ||||
|  | @ -673,8 +663,8 @@ void LayoutBlock::compute_height() | |||
| 
 | ||||
|     box_model().margin.top = style().margin().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     box_model().margin.bottom = style().margin().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
|     box_model().border.top = specified_style.length_or_fallback(CSS::PropertyID::BorderTopWidth, Length::make_px(0)); | ||||
|     box_model().border.bottom = specified_style.length_or_fallback(CSS::PropertyID::BorderBottomWidth, Length::make_px(0)); | ||||
|     box_model().border.top = Length::make_px(style().border_top().width); | ||||
|     box_model().border.bottom = Length::make_px(style().border_bottom().width); | ||||
|     box_model().padding.top = style().padding().top.resolved_or_zero(*this, containing_block.width()); | ||||
|     box_model().padding.bottom = style().padding().bottom.resolved_or_zero(*this, containing_block.width()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ class Element; | |||
| 
 | ||||
| class LayoutBlock : public LayoutBox { | ||||
| public: | ||||
|     LayoutBlock(const Node*, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutBlock(Document&, const Node*, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutBlock() override; | ||||
| 
 | ||||
|     virtual const char* class_name() const override { return "LayoutBlock"; } | ||||
|  |  | |||
|  | @ -33,33 +33,16 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatRect& rect, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id) | ||||
| void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatRect& rect, CSS::PropertyID style_property_id, const BorderData& border_data) | ||||
| { | ||||
|     auto border_width = specified_style().property(width_property_id); | ||||
|     if (!border_width.has_value()) | ||||
|         return; | ||||
| 
 | ||||
|     auto border_style = specified_style().property(style_property_id); | ||||
|     float width = border_width.value()->to_length().to_px(*this); | ||||
|     float width = border_data.width; | ||||
|     if (width <= 0) | ||||
|         return; | ||||
| 
 | ||||
|     auto color = border_data.color; | ||||
|     auto border_style = specified_style().property(style_property_id); | ||||
|     int int_width = max((int)width, 1); | ||||
| 
 | ||||
|     Color color; | ||||
|     auto border_color = specified_style().property(color_property_id); | ||||
|     if (border_color.has_value()) { | ||||
|         color = border_color.value()->to_color(document()); | ||||
|     } else { | ||||
|         // FIXME: This is basically CSS "currentColor" which should be handled elsewhere
 | ||||
|         //        in a much more reusable way.
 | ||||
|         auto current_color = specified_style().property(CSS::PropertyID::Color); | ||||
|         if (current_color.has_value()) | ||||
|             color = current_color.value()->to_color(document()); | ||||
|         else | ||||
|             color = Color::Black; | ||||
|     } | ||||
| 
 | ||||
|     auto first_point_for_edge = [](Edge edge, const Gfx::FloatRect& rect) { | ||||
|         switch (edge) { | ||||
|         case Edge::Top: | ||||
|  | @ -136,20 +119,13 @@ void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatR | |||
|         context.painter().draw_line({ (int)p1.x(), (int)p1.y() }, { (int)p2.x(), (int)p2.y() }, color, 1, line_style); | ||||
|     }; | ||||
| 
 | ||||
|     auto width_for = [&](CSS::PropertyID property_id) -> float { | ||||
|         auto width = specified_style().property(property_id); | ||||
|         if (!width.has_value()) | ||||
|             return 0; | ||||
|         return width.value()->to_length().to_px(*this); | ||||
|     }; | ||||
| 
 | ||||
|     float p1_step = 0; | ||||
|     float p2_step = 0; | ||||
| 
 | ||||
|     switch (edge) { | ||||
|     case Edge::Top: | ||||
|         p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width; | ||||
|         p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width; | ||||
|         p1_step = style().border_left().width / (float)int_width; | ||||
|         p2_step = style().border_right().width / (float)int_width; | ||||
|         for (int i = 0; i < int_width; ++i) { | ||||
|             draw_line(p1, p2); | ||||
|             p1.move_by(p1_step, 1); | ||||
|  | @ -157,8 +133,8 @@ void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatR | |||
|         } | ||||
|         break; | ||||
|     case Edge::Right: | ||||
|         p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width; | ||||
|         p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width; | ||||
|         p1_step = style().border_top().width / (float)int_width; | ||||
|         p2_step = style().border_bottom().width / (float)int_width; | ||||
|         for (int i = int_width - 1; i >= 0; --i) { | ||||
|             draw_line(p1, p2); | ||||
|             p1.move_by(-1, p1_step); | ||||
|  | @ -166,8 +142,8 @@ void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatR | |||
|         } | ||||
|         break; | ||||
|     case Edge::Bottom: | ||||
|         p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width; | ||||
|         p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width; | ||||
|         p1_step = style().border_left().width / (float)int_width; | ||||
|         p2_step = style().border_right().width / (float)int_width; | ||||
|         for (int i = int_width - 1; i >= 0; --i) { | ||||
|             draw_line(p1, p2); | ||||
|             p1.move_by(p1_step, -1); | ||||
|  | @ -175,8 +151,8 @@ void LayoutBox::paint_border(PaintContext& context, Edge edge, const Gfx::FloatR | |||
|         } | ||||
|         break; | ||||
|     case Edge::Left: | ||||
|         p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width; | ||||
|         p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width; | ||||
|         p1_step = style().border_top().width / (float)int_width; | ||||
|         p2_step = style().border_bottom().width / (float)int_width; | ||||
|         for (int i = 0; i < int_width; ++i) { | ||||
|             draw_line(p1, p2); | ||||
|             p1.move_by(1, p1_step); | ||||
|  | @ -224,10 +200,10 @@ void LayoutBox::paint(PaintContext& context, PaintPhase phase) | |||
|         bordered_rect.set_y(padded_rect.y() - box_model().border.top.to_px(*this)); | ||||
|         bordered_rect.set_height(padded_rect.height() + box_model().border.top.to_px(*this) + box_model().border.bottom.to_px(*this)); | ||||
| 
 | ||||
|         paint_border(context, Edge::Left, bordered_rect, CSS::PropertyID::BorderLeftStyle, CSS::PropertyID::BorderLeftColor, CSS::PropertyID::BorderLeftWidth); | ||||
|         paint_border(context, Edge::Right, bordered_rect, CSS::PropertyID::BorderRightStyle, CSS::PropertyID::BorderRightColor, CSS::PropertyID::BorderRightWidth); | ||||
|         paint_border(context, Edge::Top, bordered_rect, CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopColor, CSS::PropertyID::BorderTopWidth); | ||||
|         paint_border(context, Edge::Bottom, bordered_rect, CSS::PropertyID::BorderBottomStyle, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomWidth); | ||||
|         paint_border(context, Edge::Left, bordered_rect, CSS::PropertyID::BorderLeftStyle, style().border_left()); | ||||
|         paint_border(context, Edge::Right, bordered_rect, CSS::PropertyID::BorderRightStyle, style().border_right()); | ||||
|         paint_border(context, Edge::Top, bordered_rect, CSS::PropertyID::BorderTopStyle, style().border_top()); | ||||
|         paint_border(context, Edge::Bottom, bordered_rect, CSS::PropertyID::BorderBottomStyle, style().border_bottom()); | ||||
|     } | ||||
| 
 | ||||
|     LayoutNodeWithStyleAndBoxModelMetrics::paint(context, phase); | ||||
|  |  | |||
|  | @ -70,8 +70,8 @@ public: | |||
|     virtual void paint(PaintContext&, PaintPhase) override; | ||||
| 
 | ||||
| protected: | ||||
|     LayoutBox(const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|         : LayoutNodeWithStyleAndBoxModelMetrics(node, move(style)) | ||||
|     LayoutBox(Document& document, const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|         : LayoutNodeWithStyleAndBoxModelMetrics(document, node, move(style)) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|  | @ -86,7 +86,7 @@ private: | |||
|         Bottom, | ||||
|         Left, | ||||
|     }; | ||||
|     void paint_border(PaintContext&, Edge, const Gfx::FloatRect&, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id); | ||||
|     void paint_border(PaintContext&, Edge, const Gfx::FloatRect&, CSS::PropertyID style_property_id, const BorderData&); | ||||
| 
 | ||||
|     Gfx::FloatPoint m_offset; | ||||
|     Gfx::FloatSize m_size; | ||||
|  |  | |||
|  | @ -29,8 +29,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutBreak::LayoutBreak(const HTMLBRElement& element) | ||||
|     : LayoutNodeWithStyleAndBoxModelMetrics(&element, StyleProperties::create()) | ||||
| LayoutBreak::LayoutBreak(Document& document, const HTMLBRElement& element) | ||||
|     : LayoutNodeWithStyleAndBoxModelMetrics(document, &element, StyleProperties::create()) | ||||
| { | ||||
|     set_inline(true); | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutBreak final : public LayoutNodeWithStyleAndBoxModelMetrics { | ||||
| public: | ||||
|     explicit LayoutBreak(const HTMLBRElement&); | ||||
|     LayoutBreak(Document&, const HTMLBRElement&); | ||||
|     virtual ~LayoutBreak() override; | ||||
| 
 | ||||
|     const HTMLBRElement& node() const { return to<HTMLBRElement>(*LayoutNode::node()); } | ||||
|  |  | |||
|  | @ -31,8 +31,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutCanvas::LayoutCanvas(const HTMLCanvasElement& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutReplaced(element, move(style)) | ||||
| LayoutCanvas::LayoutCanvas(Document& document, const HTMLCanvasElement& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutReplaced(document, element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ class HTMLCanvasElement; | |||
| 
 | ||||
| class LayoutCanvas : public LayoutReplaced { | ||||
| public: | ||||
|     LayoutCanvas(const HTMLCanvasElement&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutCanvas(Document&, const HTMLCanvasElement&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutCanvas() override; | ||||
| 
 | ||||
|     virtual void layout(LayoutMode = LayoutMode::Default) override; | ||||
|  |  | |||
|  | @ -33,8 +33,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutDocument::LayoutDocument(const Document& document, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(&document, move(style)) | ||||
| LayoutDocument::LayoutDocument(Document& document, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(document, &document, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutDocument final : public LayoutBlock { | ||||
| public: | ||||
|     explicit LayoutDocument(const Document&, NonnullRefPtr<StyleProperties>); | ||||
|     explicit LayoutDocument(Document&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutDocument() override; | ||||
| 
 | ||||
|     const Document& node() const { return static_cast<const Document&>(*LayoutNode::node()); } | ||||
|  |  | |||
|  | @ -37,8 +37,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutFrame::LayoutFrame(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutReplaced(element, move(style)) | ||||
| LayoutFrame::LayoutFrame(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutReplaced(document, element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutFrame final : public LayoutReplaced { | ||||
| public: | ||||
|     LayoutFrame(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutFrame(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutFrame() override; | ||||
| 
 | ||||
|     virtual void paint(PaintContext&, PaintPhase) override; | ||||
|  |  | |||
|  | @ -32,8 +32,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutImage::LayoutImage(const Element& element, NonnullRefPtr<StyleProperties> style, const ImageLoader& image_loader) | ||||
|     : LayoutReplaced(element, move(style)) | ||||
| LayoutImage::LayoutImage(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style, const ImageLoader& image_loader) | ||||
|     : LayoutReplaced(document, element, move(style)) | ||||
|     , m_image_loader(image_loader) | ||||
| { | ||||
| } | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ class HTMLImageElement; | |||
| 
 | ||||
| class LayoutImage : public LayoutReplaced { | ||||
| public: | ||||
|     LayoutImage(const Element&, NonnullRefPtr<StyleProperties>, const ImageLoader&); | ||||
|     LayoutImage(Document&, const Element&, NonnullRefPtr<StyleProperties>, const ImageLoader&); | ||||
|     virtual ~LayoutImage() override; | ||||
| 
 | ||||
|     virtual void layout(LayoutMode = LayoutMode::Default) override; | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutInline::LayoutInline(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutNodeWithStyleAndBoxModelMetrics(&element, move(style)) | ||||
| LayoutInline::LayoutInline(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutNodeWithStyleAndBoxModelMetrics(document, &element, move(style)) | ||||
| { | ||||
|     set_inline(true); | ||||
| } | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ class LayoutBlock; | |||
| 
 | ||||
| class LayoutInline : public LayoutNodeWithStyleAndBoxModelMetrics { | ||||
| public: | ||||
|     LayoutInline(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutInline(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutInline() override; | ||||
|     virtual const char* class_name() const override { return "LayoutInline"; } | ||||
| }; | ||||
|  |  | |||
|  | @ -29,8 +29,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutListItem::LayoutListItem(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(&element, move(style)) | ||||
| LayoutListItem::LayoutListItem(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(document, &element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -52,7 +52,7 @@ void LayoutListItem::layout(LayoutMode layout_mode) | |||
|     } | ||||
| 
 | ||||
|     if (!m_marker) { | ||||
|         m_marker = adopt(*new LayoutListItemMarker); | ||||
|         m_marker = adopt(*new LayoutListItemMarker(document())); | ||||
|         if (first_child()) | ||||
|             m_marker->set_inline(first_child()->is_inline()); | ||||
|         append_child(*m_marker); | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ class LayoutListItemMarker; | |||
| 
 | ||||
| class LayoutListItem final : public LayoutBlock { | ||||
| public: | ||||
|     LayoutListItem(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutListItem(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutListItem() override; | ||||
| 
 | ||||
|     virtual void layout(LayoutMode = LayoutMode::Default) override; | ||||
|  |  | |||
|  | @ -29,8 +29,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutListItemMarker::LayoutListItemMarker() | ||||
|     : LayoutBox(nullptr, StyleProperties::create()) | ||||
| LayoutListItemMarker::LayoutListItemMarker(Document& document) | ||||
|     : LayoutBox(document, nullptr, StyleProperties::create()) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutListItemMarker final : public LayoutBox { | ||||
| public: | ||||
|     LayoutListItemMarker(); | ||||
|     explicit LayoutListItemMarker(Document&); | ||||
|     virtual ~LayoutListItemMarker() override; | ||||
| 
 | ||||
|     virtual void paint(PaintContext&, PaintPhase) override; | ||||
|  |  | |||
|  | @ -35,8 +35,9 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutNode::LayoutNode(const Node* node) | ||||
|     : m_node(node) | ||||
| LayoutNode::LayoutNode(Document& document, const Node* node) | ||||
|     : m_document(document) | ||||
|     , m_node(node) | ||||
| { | ||||
|     if (m_node) | ||||
|         m_node->set_layout_node({}, this); | ||||
|  | @ -124,21 +125,6 @@ Frame& LayoutNode::frame() | |||
|     return *document().frame(); | ||||
| } | ||||
| 
 | ||||
| const Document& LayoutNode::document() const | ||||
| { | ||||
|     if (is_anonymous()) | ||||
|         return parent()->document(); | ||||
|     return node()->document(); | ||||
| } | ||||
| 
 | ||||
| Document& LayoutNode::document() | ||||
| { | ||||
|     if (is_anonymous()) | ||||
|         return parent()->document(); | ||||
|     // FIXME: Remove this const_cast once we give up on the idea of a const link from layout tree to DOM tree.
 | ||||
|     return const_cast<Node*>(node())->document(); | ||||
| } | ||||
| 
 | ||||
| const LayoutDocument& LayoutNode::root() const | ||||
| { | ||||
|     ASSERT(document().layout_node()); | ||||
|  | @ -211,12 +197,12 @@ bool LayoutNode::is_fixed_position() const | |||
|     return position == CSS::Position::Fixed; | ||||
| } | ||||
| 
 | ||||
| LayoutNodeWithStyle::LayoutNodeWithStyle(const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutNode(node) | ||||
|     , m_specified_style(move(style)) | ||||
| LayoutNodeWithStyle::LayoutNodeWithStyle(Document& document, const Node* node, NonnullRefPtr<StyleProperties> specified_style) | ||||
|     : LayoutNode(document, node) | ||||
|     , m_specified_style(move(specified_style)) | ||||
| { | ||||
|     m_has_style = true; | ||||
|     apply_style(this->specified_style()); | ||||
|     apply_style(*m_specified_style); | ||||
| } | ||||
| 
 | ||||
| void LayoutNodeWithStyle::apply_style(const StyleProperties& specified_style) | ||||
|  | @ -241,6 +227,16 @@ void LayoutNodeWithStyle::apply_style(const StyleProperties& specified_style) | |||
|     style.set_offset(specified_style.length_box(CSS::PropertyID::Left, CSS::PropertyID::Top, CSS::PropertyID::Right, CSS::PropertyID::Bottom)); | ||||
|     style.set_margin(specified_style.length_box(CSS::PropertyID::MarginLeft, CSS::PropertyID::MarginTop, CSS::PropertyID::MarginRight, CSS::PropertyID::MarginBottom)); | ||||
|     style.set_padding(specified_style.length_box(CSS::PropertyID::PaddingLeft, CSS::PropertyID::PaddingTop, CSS::PropertyID::PaddingRight, CSS::PropertyID::PaddingBottom)); | ||||
| 
 | ||||
|     style.border_left().width = specified_style.length_or_fallback(CSS::PropertyID::BorderLeftWidth, {}).resolved_or_zero(*this, 0).to_px(*this); | ||||
|     style.border_top().width = specified_style.length_or_fallback(CSS::PropertyID::BorderTopWidth, {}).resolved_or_zero(*this, 0).to_px(*this); | ||||
|     style.border_right().width = specified_style.length_or_fallback(CSS::PropertyID::BorderRightWidth, {}).resolved_or_zero(*this, 0).to_px(*this); | ||||
|     style.border_bottom().width = specified_style.length_or_fallback(CSS::PropertyID::BorderBottomWidth, {}).resolved_or_zero(*this, 0).to_px(*this); | ||||
| 
 | ||||
|     style.border_left().color = specified_style.color_or_fallback(CSS::PropertyID::BorderLeftColor, document(), Color::Transparent); | ||||
|     style.border_top().color = specified_style.color_or_fallback(CSS::PropertyID::BorderTopColor, document(), Color::Transparent); | ||||
|     style.border_right().color = specified_style.color_or_fallback(CSS::PropertyID::BorderRightColor, document(), Color::Transparent); | ||||
|     style.border_bottom().color = specified_style.color_or_fallback(CSS::PropertyID::BorderBottomColor, document(), Color::Transparent); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -101,8 +101,8 @@ public: | |||
|     const Node* node() const { return m_node; } | ||||
|     Node* node() { return const_cast<Node*>(m_node); } | ||||
| 
 | ||||
|     Document& document(); | ||||
|     const Document& document() const; | ||||
|     Document& document() { return m_document; } | ||||
|     const Document& document() const { return m_document; } | ||||
| 
 | ||||
|     const Frame& frame() const; | ||||
|     Frame& frame(); | ||||
|  | @ -239,11 +239,12 @@ public: | |||
|     float font_size() const; | ||||
| 
 | ||||
| protected: | ||||
|     explicit LayoutNode(const Node*); | ||||
|     LayoutNode(Document&, const Node*); | ||||
| 
 | ||||
| private: | ||||
|     friend class LayoutNodeWithStyle; | ||||
| 
 | ||||
|     Document& m_document; | ||||
|     const Node* m_node { nullptr }; | ||||
| 
 | ||||
|     bool m_inline { false }; | ||||
|  | @ -261,11 +262,12 @@ public: | |||
| 
 | ||||
|     const ImmutableLayoutStyle& style() const { return static_cast<const ImmutableLayoutStyle&>(m_style); } | ||||
| 
 | ||||
|     void apply_style(const StyleProperties&); | ||||
| 
 | ||||
| protected: | ||||
|     explicit LayoutNodeWithStyle(const Node*, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutNodeWithStyle(Document&, const Node*, NonnullRefPtr<StyleProperties>); | ||||
| 
 | ||||
| private: | ||||
|     void apply_style(const StyleProperties&); | ||||
| 
 | ||||
|     LayoutStyle m_style; | ||||
| 
 | ||||
|  | @ -280,8 +282,8 @@ public: | |||
|     const BoxModelMetrics& box_model() const { return m_box_model; } | ||||
| 
 | ||||
| protected: | ||||
|     LayoutNodeWithStyleAndBoxModelMetrics(const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|         : LayoutNodeWithStyle(node, move(style)) | ||||
|     LayoutNodeWithStyleAndBoxModelMetrics(Document& document, const Node* node, NonnullRefPtr<StyleProperties> style) | ||||
|         : LayoutNodeWithStyle(document, node, move(style)) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutReplaced::LayoutReplaced(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(&element, move(style)) | ||||
| LayoutReplaced::LayoutReplaced(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(document, &element, move(style)) | ||||
| { | ||||
|     // FIXME: Allow non-inline replaced elements.
 | ||||
|     set_inline(true); | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutReplaced : public LayoutBox { | ||||
| public: | ||||
|     LayoutReplaced(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutReplaced(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutReplaced() override; | ||||
| 
 | ||||
|     const Element& node() const { return to<Element>(*LayoutNode::node()); } | ||||
|  |  | |||
|  | @ -37,6 +37,12 @@ public: | |||
|     static CSS::WhiteSpace white_space() { return CSS::WhiteSpace::Normal; } | ||||
| }; | ||||
| 
 | ||||
| struct BorderData { | ||||
| public: | ||||
|     Color color { Color::Transparent }; | ||||
|     float width { 0 }; | ||||
| }; | ||||
| 
 | ||||
| class LayoutStyle { | ||||
| public: | ||||
|     Optional<int> z_index() const { return m_z_index; } | ||||
|  | @ -54,6 +60,11 @@ public: | |||
|     const LengthBox& margin() const { return m_margin; } | ||||
|     const LengthBox& padding() const { return m_padding; } | ||||
| 
 | ||||
|     const BorderData& border_left() const { return m_border_left; } | ||||
|     const BorderData& border_top() const { return m_border_top; } | ||||
|     const BorderData& border_right() const { return m_border_right; } | ||||
|     const BorderData& border_bottom() const { return m_border_bottom; } | ||||
| 
 | ||||
| protected: | ||||
|     Optional<int> m_z_index; | ||||
|     CSS::TextAlign m_text_align; | ||||
|  | @ -68,6 +79,10 @@ protected: | |||
|     LengthBox m_offset; | ||||
|     LengthBox m_margin; | ||||
|     LengthBox m_padding; | ||||
|     BorderData m_border_left; | ||||
|     BorderData m_border_top; | ||||
|     BorderData m_border_right; | ||||
|     BorderData m_border_bottom; | ||||
| }; | ||||
| 
 | ||||
| class ImmutableLayoutStyle final : public LayoutStyle { | ||||
|  | @ -88,6 +103,10 @@ public: | |||
|     void set_offset(const LengthBox& offset) { m_offset = offset; } | ||||
|     void set_margin(const LengthBox& margin) { m_margin = margin; } | ||||
|     void set_padding(const LengthBox& padding) { m_padding = padding; } | ||||
|     BorderData& border_left() { return m_border_left; } | ||||
|     BorderData& border_top() { return m_border_top; } | ||||
|     BorderData& border_right() { return m_border_right; } | ||||
|     BorderData& border_bottom() { return m_border_bottom; } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutTable::LayoutTable(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(&element, move(style)) | ||||
| LayoutTable::LayoutTable(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(document, &element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ class LayoutTableRow; | |||
| 
 | ||||
| class LayoutTable final : public LayoutBlock { | ||||
| public: | ||||
|     LayoutTable(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutTable(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutTable() override; | ||||
| 
 | ||||
|     virtual void layout(LayoutMode = LayoutMode::Default) override; | ||||
|  |  | |||
|  | @ -29,8 +29,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutTableCell::LayoutTableCell(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(&element, move(style)) | ||||
| LayoutTableCell::LayoutTableCell(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(document, &element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutTableCell final : public LayoutBlock { | ||||
| public: | ||||
|     LayoutTableCell(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutTableCell(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutTableCell() override; | ||||
| 
 | ||||
|     LayoutTableCell* next_cell() { return next_sibling_of_type<LayoutTableCell>(); } | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutTableRow::LayoutTableRow(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(&element, move(style)) | ||||
| LayoutTableRow::LayoutTableRow(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBox(document, &element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ class LayoutTableCell; | |||
| 
 | ||||
| class LayoutTableRow final : public LayoutBox { | ||||
| public: | ||||
|     LayoutTableRow(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutTableRow(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutTableRow() override; | ||||
| 
 | ||||
|     void layout_row(const Vector<float>& column_widths); | ||||
|  |  | |||
|  | @ -31,8 +31,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutTableRowGroup::LayoutTableRowGroup(const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(&element, move(style)) | ||||
| LayoutTableRowGroup::LayoutTableRowGroup(Document& document, const Element& element, NonnullRefPtr<StyleProperties> style) | ||||
|     : LayoutBlock(document, &element, move(style)) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutTableRowGroup final : public LayoutBlock { | ||||
| public: | ||||
|     LayoutTableRowGroup(const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     LayoutTableRowGroup(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||
|     virtual ~LayoutTableRowGroup() override; | ||||
| 
 | ||||
|     virtual void layout(LayoutMode = LayoutMode::Default) override; | ||||
|  |  | |||
|  | @ -36,8 +36,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutText::LayoutText(const Text& text) | ||||
|     : LayoutNode(&text) | ||||
| LayoutText::LayoutText(Document& document, const Text& text) | ||||
|     : LayoutNode(document, &text) | ||||
| { | ||||
|     set_inline(true); | ||||
| } | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ class LineBoxFragment; | |||
| 
 | ||||
| class LayoutText : public LayoutNode { | ||||
| public: | ||||
|     explicit LayoutText(const Text&); | ||||
|     LayoutText(Document&, const Text&); | ||||
|     virtual ~LayoutText() override; | ||||
| 
 | ||||
|     const Text& node() const { return static_cast<const Text&>(*LayoutNode::node()); } | ||||
|  |  | |||
|  | @ -36,8 +36,8 @@ | |||
| 
 | ||||
| namespace Web { | ||||
| 
 | ||||
| LayoutWidget::LayoutWidget(const Element& element, GUI::Widget& widget) | ||||
|     : LayoutReplaced(element, StyleProperties::create()) | ||||
| LayoutWidget::LayoutWidget(Document& document, const Element& element, GUI::Widget& widget) | ||||
|     : LayoutReplaced(document, element, StyleProperties::create()) | ||||
|     , m_widget(widget) | ||||
| { | ||||
|     set_has_intrinsic_width(true); | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ namespace Web { | |||
| 
 | ||||
| class LayoutWidget final : public LayoutReplaced { | ||||
| public: | ||||
|     LayoutWidget(const Element&, GUI::Widget&); | ||||
|     LayoutWidget(Document&, const Element&, GUI::Widget&); | ||||
|     virtual ~LayoutWidget() override; | ||||
| 
 | ||||
|     GUI::Widget& widget() { return m_widget; } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling