Skip to content

Commit 1b53933

Browse files
committed
[css-lists] content: counter() does not update visually if position: absolute is set
https://bugs.webkit.org/show_bug.cgi?id=254575 Reviewed by Antti Koivisto. 1. In order to update counters in IFC, the containing RenderBlockFlow needs to get invalidated (a new InlineTextBox is created for the text). 2. With in-flow pseudo renderers, where the RenderCounter is nested inside an inline box, invalidation goes through the normal styleDidChange codepath. RenderBlockFlow (A) <- this is where the counter is. <pseudo> RenderInline (B) <- in-flow :after RenderCounter (C) However out-of-flow pseudo content initiates a different type of tree structure where the RenderCounter is not part of the initial RenderBlockFlow anymore RenderBlockFlow (A) <- this is where the counter is <pseudo> RenderBlockFlow (B) <- out-of-flow :after RenderCounter (C) Which means invalidating (A) (where the style change happens) does not trigger an IFC tree re-build at (B) and we end up re-layouting the exact same content over again (C). This patch ensures we always invalidate the block flow where the damage happens (and this should cover some more involved cases with counters in arbitrary number of subtrees). * LayoutTests/fast/dynamic/out-of-flow-counter-do-not-update-expected.html: Added. * LayoutTests/fast/dynamic/out-of-flow-counter-do-not-update.html: Added. * Source/WebCore/rendering/CounterNode.cpp: (WebCore::CounterNode::resetRenderers): This function is called whenever a new counter node is added/removed/updated. This is also where we call setNeedsLayoutAndPrefWidthsRecalc which eventually updates the counter for legacy line layout. Canonical link: https://commits.webkit.org/262269@main
1 parent b7ff1b3 commit 1b53933

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<style>
2+
div {
3+
font-family: Monospace;
4+
}
5+
</style>
6+
<div>PASS if 1: 1</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<style>
2+
div {
3+
counter-reset: test 0;
4+
font-family: Monospace;
5+
}
6+
7+
div:after {
8+
content: counter(test);
9+
position: absolute;
10+
}
11+
</style>
12+
<div id=change_this>PASS if 1:&nbsp</div><script>
13+
document.body.offsetHeight;
14+
change_this.style.counterReset = "test 1";
15+
</script>

Source/WebCore/rendering/CounterNode.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "config.h"
2323
#include "CounterNode.h"
2424

25+
#include "LayoutIntegrationLineLayout.h"
2526
#include "RenderCounter.h"
2627
#include "RenderElement.h"
2728
#include <stdio.h>
@@ -179,8 +180,11 @@ void CounterNode::resetRenderers()
179180
bool skipLayoutAndPerfWidthsRecalc = m_rootRenderer->renderTreeBeingDestroyed();
180181
auto* current = m_rootRenderer;
181182
while (current) {
182-
if (!skipLayoutAndPerfWidthsRecalc)
183+
if (!skipLayoutAndPerfWidthsRecalc) {
183184
current->setNeedsLayoutAndPrefWidthsRecalc();
185+
if (auto* lineLayout = LayoutIntegration::LineLayout::containing(*current))
186+
lineLayout->flow().invalidateLineLayoutPath();
187+
}
184188
auto* next = current->m_nextForSameCounter;
185189
current->m_nextForSameCounter = nullptr;
186190
current->m_counterNode = nullptr;

0 commit comments

Comments
 (0)