8000 Consider overflowX/Y in applyCachedClipAndScrollPosition() · WebKit/WebKit@ba441a1 · GitHub
[go: up one dir, main page]

Skip to content

Commit ba441a1

Browse files
committed
Consider overflowX/Y in applyCachedClipAndScrollPosition()
https://bugs.webkit.org/show_bug.cgi?id=249693 rdar://103734614 Reviewed by Simon Fraser. Up to now, applyCachedClipAndScrollPosition() doesn't take in consideration that the overflow for an axis can be visible when computing the interection with the given target. Now, if overflow is visible in one of the axis, we expand the target within this axis. Imagine a case where a children box with absolute position is placed below its parent. Before, this children box would not be considered visible even if it would have overflow-y : visible, because there would not be intersection between parent and children. For this case, we would now expand the parent into the Y axis when calculating intersection, resulting in the intersecion rect to be the children box itself. * LayoutTests/imported/w3c/web-platform-tests/intersection-observer/v2/position-absolute-overflow-visible-and-not-visible-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/intersection-observer/v2/position-absolute-overflow-visible-and-not-visible.html: Added. * Source/WebCore/platform/graphics/LayoutRect.cpp: (WebCore::LayoutRect::expandToInfiniteY): (WebCore::LayoutRect::expandToInfiniteX): * Source/WebCore/platform/graphics/LayoutRect.h: Functions for expanding the Rect to infinite in each axis. * Source/WebCore/rendering/RenderBox.cpp: (WebCore::RenderBox::applyCachedClipAndScrollPosition const): (WebCore::RenderBox::overflowClipRect const): * Source/WebCore/rendering/svg/RenderSVGModelObject.cpp: (WebCore::RenderSVGModelObject::applyCachedClipAndScrollPosition const): Canonical link: https://commits.webkit.org/259007@main
1 parent 9833f67 commit ba441a1

File tree

6 files changed

+82
-9
lines changed

6 files changed

+82
-9
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
PASS ParentWithOverflowVisibleAndNotVisible
3+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta name="viewport" content="width=device-width,initial-scale=1">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
<script src="../resources/intersection-observer-test-utils.js"></script>
8+
<style>
9+
html, body {
10+
margin: 0;
11+
padding: 0;
12+
height: 200px;
13+
width: 100%;
14+
}
15+
#parent {
16+
position: relative;
17+
height: 200px;
18+
width: 200px;
19+
background-color: rgb(250, 221, 221);
20+
overflow-y: clip;
21+
overflow-x: visible;
22+
}
23+
#child {
24+
background-color: rgb(208, 250, 208);
25+
position: absolute;
26+
left: 100%;
27+
width: 200px;
28+
height: 200px;
29+
}
30+
</style>
31+
</head>
32+
<body>
33+
<div id="parent">
34+
<div id="child"></div>
35+
</div>
36+
</body>
37+
<script>
38+
const test = async_test("ParentWithOverflowVisibleAndNotVisible");
39+
const child = document.getElementById("child");
40+
const observer = new IntersectionObserver((entries) => {
41+
test.step(() => {
42+
assert_true(entries[0].isIntersecting);
43+
assert_equals(entries[0].intersectionRatio, 1.0);
44+
assert_equals(entries[0].intersectionRect.height, 200);
45+
assert_equals(entries[0].intersectionRect.width, 200);
46+
});
47+
test.done();
48+
});
49+
observer.observe(child);
50+
</script>
51+
</html>

Source/WebCore/platform/graphics/LayoutRect.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,20 @@ void LayoutRect::scale(float xScale, float yScale)
164164
m_size.scale(xScale, yScale);
165165
}
166166

167+
void LayoutRect::expandToInfiniteY()
168+
{
169+
LayoutRect infRect = LayoutRect::infiniteRect();
170+
setY(infRect.y());
171+
setHeight(infRect.height());
172+
}
173+
174+
void LayoutRect::expandToInfiniteX()
175+
{
176+
LayoutRect infRect = LayoutRect::infiniteRect();
177+
setX(infRect.x());
178+
setWidth(infRect.width());
179+
}
180+
167181
LayoutRect unionRect(const Vector<LayoutRect>& rects)
168182
{
169183
LayoutRect result;

Source/WebCore/platform/graphics/LayoutRect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class LayoutRect {
9393
m_location.move(-box.left(), -box.top());
9494
m_size.expand(box.left() + box.right(), box.top() + box.bottom());
9595
}
96+
void expandToInfiniteY();
97+
void expandToInfiniteX();
9698
template<typename T, typename U> void expand(T dw, U dh) { m_size.expand(dw, dh); }
9799
void contract(const LayoutSize& size) { m_size -= size; }
98100
void contract(const LayoutBoxExtent& box)

Source/WebCore/rendering/RenderBox.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,10 @@ bool RenderBox::applyCachedClipAndScrollPosition(LayoutRect& rect, const RenderL
11651165
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
11661166
// anyway if its size does change.
11671167
LayoutRect clipRect(LayoutPoint(), cachedSizeForOverflowClip());
1168+
if (effectiveOverflowX() == Overflow::Visible)
1169+
clipRect.expandToInfiniteX();
1170+
if (effectiveOverflowY() == Overflow::Visible)
1171+
clipRect.expandToInfiniteY();
11681172
bool intersects;
11691173
if (context.options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection))
11701174
intersects = rect.edgeInclusiveIntersect(clipRect);
@@ -2109,15 +2113,10 @@ LayoutRect RenderBox::overflowClipRect(const LayoutPoint& location, RenderFragme
21092113
LayoutRect clipRect = borderBoxRectInFragment(fragment);
21102114
clipRect.setLocation(location + clipRect.location() + LayoutSize(borderLeft(), borderTop()));
21112115
clipRect.setSize(clipRect.size() - LayoutSize(borderLeft() + borderRight(), borderTop() + borderBottom()));
2112-
if (style().overflowX() == Overflow::Clip && style().overflowY() == Overflow::Visible) {
2113-
LayoutRect infRect = LayoutRect::infiniteRect();
2114-
clipRect.setY(infRect.y());
2115-
clipRect.setHeight(infRect.height());
2116-
} else if (style().overflowY() == Overflow::Clip && style().overflowX() == Overflow::Visible) {
2117-
LayoutRect infRect = LayoutRect::infiniteRect();
2118-
clipRect.setX(infRect.x());
2119-
clipRect.setWidth(infRect.width());
2120-
}
2116+
if (style().overflowX() == Overflow::Clip && style().overflowY() == Overflow::Visible)
2117+
clipRect.expandToInfiniteY();
2118+
else if (style().overflowY() == Overflow::Clip && style().overflowX() == Overflow::Visible)
2119+
clipRect.expandToInfiniteX();
21212120

21222121
// Subtract out scrollbars if we have them.
21232122
if (auto* scrollableArea = layer() ? layer()->scrollableArea() : nullptr) {

Source/WebCore/rendering/svg/RenderSVGModelObject.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ bool RenderSVGModelObject::applyCachedClipAndScrollPosition(LayoutRect& rect, co
251251
return true;
252252

253253
LayoutRect clipRect(LayoutPoint(), cachedSizeForOverflowClip());
254+
if (effectiveOverflowX() == Overflow::Visible)
255+
clipRect.expandToInfiniteX();
256+
if (effectiveOverflowY() == Overflow::Visible)
257+
clipRect.expandToInfiniteY();
254258
bool intersects;
255259
if (context.options.contains(VisibleRectContextOption::UseEdgeInclusiveIntersection))
256260
intersects = rect.edgeInclusiveIntersect(clipRect);

0 commit comments

Comments
 (0)
0