Skip to content

Commit

Permalink
Special case treatment of out-of-flow RenderLineBreak
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=264631
rdar://114719845

Reviewed by Alan Baradlay.

Out-of-flow RenderLineBreaks have problems when relying on default out-of-flow support of the render
tree, see https://bugs.webkit.org/show_bug.cgi?id=270977.

To fix the problem we change containerForElement and containingBlock to treat RenderLineBreak that are out-of-flow as
if they have position: static.

* LayoutTests/fast/css/line-break-fixed-position-container-expected.txt: Added.
* LayoutTests/fast/css/line-break-fixed-position-container.html: Added.
* Source/WebCore/rendering/RenderObject.cpp:
(WebCore::RenderObject::containingBlock const):
(WebCore::containerForElement):

Originally-landed-as: 274097.12@webkit-2024.2-embargoed (5bd3a1c2b0ac). rdar://128088216
Canonical link: https://commits.webkit.org/278867@main
  • Loading branch information
zdobersek authored and robert-jenner committed May 16, 2024
1 parent fc8a911 commit cfbedad
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This test passes if it doesn't crash.

36 changes: 36 additions & 0 deletions LayoutTests/fast/css/line-break-fixed-position-container.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<html>
<head>
<style>
/* Fixed position for the line break should be ignored. */
br { position: fixed; }

/* Only function of this styling is forcing style invalidation
* on the line break renderer. */
br::first-line { color: blue; }
</style>
<script>
function test() {
if (window.testRunner) {
window.testRunner.dumpAsText();
window.testRunner.waitUntilDone();
}

setTimeout(function() {
// Only function of this event listener is invalidating event regions
// for the Document and subsequently triggering a complete style rebuild
// which is necessary to exhibit the problem.
window.addEventListener('wheel', function() { });

setTimeout(function() {
if (window.testRunner)
window.testRunner.notifyDone();
});
});
}
</script>
</head>
<body onload="test()">
This test passes if it doesn't crash.
<br/>
</body>
</html>
11 changes: 9 additions & 2 deletions Source/WebCore/rendering/RenderObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,8 @@ RenderBlock* RenderObject::containingBlockForPositionType(PositionType positionT

RenderBlock* RenderObject::containingBlock() const
{
if (is<RenderText>(*this))
// FIXME: See https://bugs.webkit.org/show_bug.cgi?id=270977 for RenderLineBreak special treatment.
if (is<RenderText>(*this) || is<RenderLineBreak>(*this))
return containingBlockForPositionType(PositionType::Static, *this);

auto containingBlockForRenderer = [](const auto& renderer) -> RenderBlock* {
Expand Down Expand Up @@ -1702,9 +1703,15 @@ static inline RenderElement* containerForElement(const RenderObject& renderer, c
// (2) For absolute positioned elements, it will return a relative positioned inline, while
// containingBlock() skips to the non-anonymous containing block.
// This does mean that computePositionedLogicalWidth and computePositionedLogicalHeight have to use container().
// FIXME: See https://bugs.webkit.org/show_bug.cgi?id=270977 for RenderLineBreak special treatment.
if (!is<RenderElement>(renderer) || is<RenderText>(renderer) || is<RenderLineBreak>(renderer))
return renderer.parent();

auto* renderElement = dynamicDowncast<RenderElement>(renderer);
if (!renderElement)
if (!renderElement) {
ASSERT_NOT_REACHED();
return renderer.parent();
}
auto updateRepaintContainerSkippedFlagIfApplicable = [&] {
if (!repaintContainerSkipped)
return;
Expand Down

0 comments on commit cfbedad

Please sign in to comment.