summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/Forward.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp39
-rw-r--r--Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h4
-rw-r--r--Userland/Libraries/LibWeb/Layout/ListItemBox.cpp27
-rw-r--r--Userland/Libraries/LibWeb/Layout/ListItemBox.h9
-rw-r--r--Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.cpp18
-rw-r--r--Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.h6
-rw-r--r--Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp14
8 files changed, 65 insertions, 54 deletions
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index 6f8628b709..99a6dc760e 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -291,6 +291,8 @@ class Label;
class LabelableNode;
class LineBox;
class LineBoxFragment;
+class ListItemBox;
+class ListItemMarkerBox;
class Node;
class NodeWithStyle;
class NodeWithStyleAndBoxModelMetrics;
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
index 1105aaec00..a1040b4057 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
@@ -405,10 +405,9 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b
if (is<ReplacedBox>(child_box) || is<BlockContainer>(child_box))
place_block_level_element_in_normal_flow_horizontally(child_box, block_container);
- // FIXME: This should be factored differently. It's uncool that we mutate the tree *during* layout!
- // Instead, we should generate the marker box during the tree build.
- if (is<ListItemBox>(child_box))
- verify_cast<ListItemBox>(child_box).layout_marker();
+ if (is<ListItemBox>(child_box)) {
+ layout_list_item_marker(static_cast<ListItemBox const&>(child_box));
+ }
content_height = max(content_height, box_state.offset.y() + box_state.content_height + box_state.margin_box_bottom());
content_width = max(content_width, box_state.content_width);
@@ -663,4 +662,36 @@ void BlockFormattingContext::layout_floating_child(Box const& box, BlockContaine
float_box(FloatSide::Right, m_right_floats);
}
}
+
+void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_item_box)
+{
+ if (!list_item_box.marker())
+ return;
+
+ auto& marker = *list_item_box.marker();
+ auto& marker_state = m_state.ensure(marker);
+ auto& list_item_state = m_state.ensure(list_item_box);
+
+ int image_width = 0;
+ int image_height = 0;
+ if (auto const* list_style_image = marker.list_style_image_bitmap()) {
+ image_width = list_style_image->rect().width();
+ image_height = list_style_image->rect().height();
+ }
+
+ if (marker.text().is_empty()) {
+ marker_state.content_width = image_width + 4;
+ } else {
+ auto text_width = marker.font().width(marker.text());
+ marker_state.content_width = image_width + text_width;
+ }
+
+ marker_state.content_height = max(image_height, marker.line_height());
+
+ marker_state.offset = { -(marker_state.content_width + 4), 0 };
+
+ if (marker_state.content_height > list_item_state.content_height)
+ list_item_state.content_height = marker_state.content_height;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
index ef8371969b..1b8f38f8ba 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -58,6 +58,8 @@ private:
void apply_transformations_to_children(Box const&);
+ void layout_list_item_marker(ListItemBox const&);
+
enum class FloatSide {
Left,
Right,
diff --git a/Userland/Libraries/LibWeb/Layout/ListItemBox.cpp b/Userland/Libraries/LibWeb/Layout/ListItemBox.cpp
index 590873a943..a830b46c1f 100644
--- a/Userland/Libraries/LibWeb/Layout/ListItemBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/ListItemBox.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@@ -19,30 +19,9 @@ ListItemBox::~ListItemBox()
{
}
-void ListItemBox::layout_marker()
+void ListItemBox::set_marker(RefPtr<ListItemMarkerBox> marker)
{
- if (m_marker) {
- remove_child(*m_marker);
- m_marker = nullptr;
- }
-
- if (computed_values().list_style_type() == CSS::ListStyleType::None)
- return;
-
- if (!m_marker) {
- auto* marker_style = dom_node().specified_css_values();
- VERIFY(marker_style);
- int child_index = parent()->index_of_child<ListItemBox>(*this).value();
- m_marker = adopt_ref(*new ListItemMarkerBox(document(), computed_values().list_style_type(), child_index + 1, *marker_style));
- if (first_child())
- m_marker->set_inline(first_child()->is_inline());
- append_child(*m_marker);
- }
-
- m_marker->set_offset(-(m_marker->content_width() + 4), 0);
-
- if (m_marker->content_height() > content_height())
- set_content_height(m_marker->content_height());
+ m_marker = move(marker);
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/ListItemBox.h b/Userland/Libraries/LibWeb/Layout/ListItemBox.h
index 4181b25ec7..eb08aea4fb 100644
--- a/Userland/Libraries/LibWeb/Layout/ListItemBox.h
+++ b/Userland/Libraries/LibWeb/Layout/ListItemBox.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -11,18 +11,17 @@
namespace Web::Layout {
-class ListItemMarkerBox;
-
class ListItemBox final : public BlockContainer {
public:
ListItemBox(DOM::Document&, DOM::Element&, NonnullRefPtr<CSS::StyleProperties>);
virtual ~ListItemBox() override;
- void layout_marker();
-
DOM::Element& dom_node() { return static_cast<DOM::Element&>(*BlockContainer::dom_node()); }
DOM::Element const& dom_node() const { return static_cast<DOM::Element const&>(*BlockContainer::dom_node()); }
+ ListItemMarkerBox const* marker() const { return m_marker; }
+ void set_marker(RefPtr<ListItemMarkerBox>);
+
private:
RefPtr<ListItemMarkerBox> m_marker;
};
diff --git a/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.cpp b/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.cpp
index e9f4bc8720..9525e90f4a 100644
--- a/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@@ -48,22 +48,6 @@ ListItemMarkerBox::ListItemMarkerBox(DOM::Document& document, CSS::ListStyleType
default:
VERIFY_NOT_REACHED();
}
-
- int image_width = 0;
- int image_height = 0;
- if (auto const* list_style_image = list_style_image_bitmap()) {
- image_width = list_style_image->rect().width();
- image_height = list_style_image->rect().height();
- }
-
- if (m_text.is_null()) {
- set_content_width(image_width + 4);
- } else {
- auto text_width = font().width(m_text);
- set_content_width(image_width + text_width);
- }
-
- set_content_height(max(image_height, line_height()));
}
ListItemMarkerBox::~ListItemMarkerBox()
diff --git a/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.h b/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.h
index 85e79ef869..0e2b3d4a2b 100644
--- a/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.h
+++ b/Userland/Libraries/LibWeb/Layout/ListItemMarkerBox.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@@ -18,9 +18,11 @@ public:
virtual void paint(PaintContext&, PaintPhase) override;
+ Gfx::Bitmap const* list_style_image_bitmap() const;
+ String const& text() const { return m_text; }
+
private:
virtual bool can_have_children() const override { return false; }
- Gfx::Bitmap const* list_style_image_bitmap() const;
CSS::ListStyleType m_list_style_type { CSS::ListStyleType::None };
size_t m_index;
diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp
index d5ccbc8ece..aff5847572 100644
--- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp
+++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -12,6 +12,8 @@
#include <LibWeb/DOM/ShadowRoot.h>
#include <LibWeb/Dump.h>
#include <LibWeb/Layout/InitialContainingBlock.h>
+#include <LibWeb/Layout/ListItemBox.h>
+#include <LibWeb/Layout/ListItemMarkerBox.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Layout/TableBox.h>
#include <LibWeb/Layout/TableCellBox.h>
@@ -147,6 +149,16 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
});
pop_parent();
}
+
+ if (is<ListItemBox>(*layout_node)) {
+ int child_index = layout_node->parent()->index_of_child<ListItemBox>(*layout_node).value();
+ auto marker_style = static_cast<DOM::Element const&>(dom_node).specified_css_values();
+ auto list_item_marker = adopt_ref(*new ListItemMarkerBox(document, layout_node->computed_values().list_style_type(), child_index + 1, *marker_style));
+ if (layout_node->first_child())
+ list_item_marker->set_inline(layout_node->first_child()->is_inline());
+ static_cast<ListItemBox&>(*layout_node).set_marker(list_item_marker);
+ layout_node->append_child(move(list_item_marker));
+ }
}
RefPtr<Node> TreeBuilder::build(DOM::Node& dom_node)