Skip to content
Permalink
Browse files
Reset the dirty bit on the inline level renderers when counter is pre…
…sent

https://bugs.webkit.org/show_bug.cgi?id=241534

Reviewed by Antti Koivisto.

While the actual line layout happens in layoutRunsAndFloats, we pre-reset the needsLayout flag as we walk the renderers and prepare them for the inline layout.
Normally this simple DOM order walk clears all the layout bits just fine, but counters can re-dirty any "connected" renderer in a seemingly random order.
This patch ensures that all inline level box renders are marked clean before returning from layoutLineBoxes.

* Source/WebCore/rendering/LegacyLineLayout.cpp:
(WebCore::LegacyLineLayout::layoutLineBoxes):

Canonical link: https://commits.webkit.org/251482@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295477 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbaradlay committed Jun 12, 2022
1 parent f4853ba commit a8ac5e3d8f2f7e97323505859ebcb0ccdcca10f7
Showing 1 changed file with 15 additions and 1 deletion.
@@ -1746,6 +1746,7 @@ void LegacyLineLayout::layoutLineBoxes(bool relayoutChildren, LayoutUnit& repain
// deleted and only dirtied. In that case, we can layout the replaced
// elements at the same time.
bool hasInlineChild = false;
auto hasDirtyRenderCounterWithInlineBoxParent = false;
Vector<RenderBox*> replacedChildren;
for (InlineWalker walker(m_flow); !walker.atEnd(); walker.advance()) {
RenderObject& o = *walker.current();
@@ -1782,15 +1783,28 @@ void LegacyLineLayout::layoutLineBoxes(bool relayoutChildren, LayoutUnit& repain
box.layoutIfNeeded();
}
} else if (o.isTextOrLineBreak() || is<RenderInline>(o)) {
if (layoutState.isFullLayout() || o.selfNeedsLayout())
if (layoutState.isFullLayout() || o.selfNeedsLayout()) {
dirtyLineBoxesForRenderer(o, layoutState.isFullLayout());
hasDirtyRenderCounterWithInlineBoxParent = hasDirtyRenderCounterWithInlineBoxParent || (is<RenderCounter>(o) && is<RenderInline>(o.parent()));
}
o.clearNeedsLayout();
}
}

for (size_t i = 0; i < replacedChildren.size(); i++)
replacedChildren[i]->layoutIfNeeded();

auto clearNeedsLayoutIfNeeded = [&] {
if (!hasDirtyRenderCounterWithInlineBoxParent)
return;
for (InlineWalker walker(m_flow); !walker.atEnd(); walker.advance()) {
auto& renderer = *walker.current();
if (is<RenderCounter>(renderer) || is<RenderInline>(renderer))
renderer.clearNeedsLayout();
}
};
clearNeedsLayoutIfNeeded();

layoutRunsAndFloats(layoutState, hasInlineChild);
}

0 comments on commit a8ac5e3

Please sign in to comment.