summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-01-20 12:18:25 +0100
committerAndreas Kling <kling@serenityos.org>2022-01-23 01:22:41 +0100
commit67b3f769fbf55b4f2977b9d7938c0cdaaf89b9ab (patch)
treef7555d6949e4d7f9d308231151a6c18873731db9 /Userland/Libraries/LibWeb
parentce8043c6c2c99ab28bcd78887261b7facf668e49 (diff)
downloadserenity-67b3f769fbf55b4f2977b9d7938c0cdaaf89b9ab.zip
LibWeb: Teach InlineLevelIterator to skip across inline-block elements
We don't want to descend into inline-block containers when iterating inline-level items, since that would make the inline-level children of the inline-block bubble up to the containing block of the inline-block.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp19
1 files changed, 18 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
index ef894e4d6d..bf7a1bdf6a 100644
--- a/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
+++ b/Userland/Libraries/LibWeb/Layout/InlineLevelIterator.cpp
@@ -11,11 +11,28 @@
namespace Web::Layout {
+// This is similar to Layout::Node::next_in_pre_order() but will not descend into inline-block nodes.
+static Layout::Node* next_inline_node_in_pre_order(Layout::Node& current, Layout::Node const* stay_within)
+{
+ if (current.first_child() && current.first_child()->is_inline() && !current.is_inline_block())
+ return current.first_child();
+
+ Layout::Node* node = &current;
+ Layout::Node* next = nullptr;
+ while (!(next = node->next_sibling())) {
+ node = node->parent();
+ if (!node || node == stay_within)
+ return nullptr;
+ }
+
+ return next;
+}
+
void InlineLevelIterator::skip_to_next()
{
VERIFY(m_current_node);
do {
- m_current_node = m_current_node->next_in_pre_order(&m_container);
+ m_current_node = next_inline_node_in_pre_order(*m_current_node, &m_container);
} while (m_current_node && !m_current_node->is_inline());
}