Skip to content

Commit 910863b

Browse files
committed
[content-visibility] Column spanner stays visible in skipped subtree
https://bugs.webkit.org/show_bug.cgi?id=293470 Reviewed by Antti Koivisto. 1. In WebKit, column spanners are moved out of their original insertion position and get reparented under the column container. 2. "is this renderer inside a skipped subtree" logic consults parent state. Now the parent of a column spanner (#1) may be completely outside of 'c-v: h' tricking us into believing the spanner is not hidden. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner-expected.html: Added. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner-ref.html: Added. * LayoutTests/imported/w3c/web-platform-tests/css/css-contain/content-visibility/content-visibility-hidden-with-column-spanner.html: Added. * Source/WebCore/rendering/RenderBlock.cpp: (WebCore::RenderBlock::paintChild): * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::layoutBlockChildren): * Source/WebCore/rendering/RenderBox.h: * Source/WebCore/rendering/RenderBoxInlines.h: (WebCore::RenderBox::isColumnSpanner const): * Source/WebCore/rendering/RenderObject.cpp: (WebCore::RenderObject::isSkippedContent const): Canonical link: https://commits.webkit.org/295335@main
1 parent c28b242 commit 910863b

File tree

8 files changed

+81
-2
lines changed

8 files changed

+81
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype HTML>
2+
<html>
3+
<meta charset="utf8">
4+
<title>CSS Content Visibility: hidden column spanner</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
6+
<style>
7+
body {
8+
width: 600px;
9+
overflow: hidden;
10+
}
11+
</style>
12+
Test fails if you can see text below.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype HTML>
2+
<html>
3+
<meta charset="utf8">
4+
<title>CSS Content Visibility: hidden column spanner</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
6+
<style>
7+
body {
8+
width: 600px;
9+
overflow: hidden;
10+
}
11+
</style>
12+
Test fails if you can see text below.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!doctype HTML>
2+
<html>
3+
<meta charset="utf8">
4+
<title>CSS Content Visibility: hidden column spanner</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
6+
<link rel="match" href="content-visibility-hidden-with-spanner-ref.html">
7+
<meta name="assert" content="content-visibility hidden column spanner should stay hidden">
8+
<style>
9+
body {
10+
width: 600px;
11+
overflow: hidden;
12+
}
13+
.container {
14+
column-count: 2;
15+
width: 200px;
16+
height: 100px;
17+
}
18+
.spanner {
19+
column-span: all;
20+
}
21+
</style>
22+
Test fails if you can see text below.
23+
<div class=container>
24+
<div id=hide_this>
25+
XXX
26+
<div class=spanner>PASS if not visible</div>
27+
XXX
28+
</div>
29+
</div>
30+
<script>
31+
document.body.offsetHeight;
32+
hide_this.style.contentVisibility = "hidden";
33+
</script>

Source/WebCore/rendering/RenderBlock.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,11 @@ bool RenderBlock::paintChild(RenderBox& child, PaintInfo& paintInfo, const Layou
11411141
if (child.isExcludedAndPlacedInBorder())
11421142
return true;
11431143

1144+
if (child.isSkippedContent()) {
1145+
ASSERT(child.isColumnSpanner());
1146+
return true;
1147+
}
1148+
11441149
// Check for page-break-before: always, and if it's set, break and bail.
11451150
bool checkBeforeAlways = !childrenInline() && (usePrintRect && alwaysPageBreak(child.style().breakBefore()));
11461151
LayoutUnit absoluteChildY = paintOffset.y() + child.y();

Source/WebCore/rendering/RenderBlockFlow.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,14 +833,20 @@ void RenderBlockFlow::layoutBlockChildren(RelayoutChildren relayoutChildren, Lay
833833
RenderBox* next = firstChildBox();
834834

835835
while (next) {
836-
ASSERT(!layoutContext().isSkippedContentForLayout(*next));
837-
838836
RenderBox& child = *next;
839837
next = child.nextSiblingBox();
840838

841839
if (child.isExcludedFromNormalLayout())
842840
continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
843841

842+
if (layoutContext().isSkippedContentForLayout(child)) {
843+
ASSERT(child.isColumnSpanner());
844+
845+
child.clearNeedsLayout();
846+
child.clearNeedsLayoutForSkippedContent();
847+
continue;
848+
}
849+
844850
updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
845851

846852
if (child.isOutOfFlowPositioned()) {

Source/WebCore/rendering/RenderBox.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,8 @@ class RenderBox : public RenderBoxModelObject {
594594
bool isGridItem() const { return parent() && parent()->isRenderGrid() && !isExcludedFromNormalLayout(); }
595595
bool isFlexItem() const { return parent() && parent()->isRenderFlexibleBox() && !isExcludedFromNormalLayout(); }
596596

597+
inline bool isColumnSpanner() const;
598+
597599
virtual void adjustBorderBoxRectForPainting(LayoutRect&) { };
598600

599601
bool shouldComputeLogicalHeightFromAspectRatio() const;

Source/WebCore/rendering/RenderBoxInlines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ inline void RenderBox::setLogicalLocation(LayoutPoint location) { setLocation(wr
6868
inline void RenderBox::setLogicalSize(LayoutSize size) { setSize(writingMode().isHorizontal() ? size : size.transposedSize()); }
6969
inline bool RenderBox::shouldTrimChildMargin(MarginTrimType type, const RenderBox& child) const { return style().marginTrim().contains(type) && isChildEligibleForMarginTrim(type, child); }
7070
inline bool RenderBox::stretchesToViewport() const { return document().inQuirksMode() && style().logicalHeight().isAuto() && !isFloatingOrOutOfFlowPositioned() && (isDocumentElementRenderer() || isBody()) && !shouldComputeLogicalHeightFromAspectRatio() && !isInline(); }
71+
inline bool RenderBox::isColumnSpanner() const { return style().columnSpan() == ColumnSpan::All; }
7172

7273
inline LayoutPoint RenderBox::topLeftLocation() const
7374
{

Source/WebCore/rendering/RenderObject.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2981,6 +2981,14 @@ String RenderObject::debugDescription() const
29812981

29822982
bool RenderObject::isSkippedContent() const
29832983
{
2984+
if (is<RenderText>(*this))
2985+
return style().isSkippedRootOrSkippedContent();
2986+
2987+
if (CheckedPtr renderBox = dynamicDowncast<RenderBox>(*this); renderBox && renderBox->isColumnSpanner()) {
2988+
// Checking if parent is root or part of a skipped tree does not work in cases when the renderer is
2989+
// moved out of its original position (e.g. column spanners).
2990+
return renderBox->style().isSkippedRootOrSkippedContent() && !isSkippedContentRoot(*renderBox);
2991+
}
29842992
return parent() && parent()->style().isSkippedRootOrSkippedContent();
29852993
}
29862994

0 commit comments

Comments
 (0)