Changeset 272931 in webkit


Ignore:
Timestamp:
Feb 16, 2021 2:55:52 PM (3 years ago)
Author:
Alan Bujtas
Message:

RenderElement::containingBlockForAbsolutePosition may call RenderObject::containingBlock recursively
https://bugs.webkit.org/show_bug.cgi?id=221976
<rdar://problem/72775667>

Reviewed by Simon Fraser.

When a RenderInline happens to be absolute positioned (this is a highly incorrect state, see webkit.org/b/221994), containingBlockForAbsolutePosition() calls containingBlock()
with |this| and in return containingBlock() calls back on containingBlockForAbsolutePosition() with the same renderer.
This patch ensures that we always call containingBlock() from containingBlockForAbsolutePosition() with an ancestor -mostly with the parent().

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::containingBlockForAbsolutePosition const):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r272928 r272931  
     12021-02-16  Zalan Bujtas  <zalan@apple.com>
     2
     3        RenderElement::containingBlockForAbsolutePosition may call RenderObject::containingBlock recursively
     4        https://bugs.webkit.org/show_bug.cgi?id=221976
     5        <rdar://problem/72775667>
     6
     7        Reviewed by Simon Fraser.
     8
     9        When a RenderInline happens to be absolute positioned (this is a highly incorrect state, see webkit.org/b/221994), containingBlockForAbsolutePosition() calls containingBlock()
     10        with |this| and in return containingBlock() calls back on containingBlockForAbsolutePosition() with the same renderer.
     11        This patch ensures that we always call containingBlock() from containingBlockForAbsolutePosition() with an ancestor -mostly with the parent().
     12
     13        * rendering/RenderElement.cpp:
     14        (WebCore::RenderElement::containingBlockForAbsolutePosition const):
     15
    1162021-02-16  Ryosuke Niwa  <rniwa@webkit.org>
    217
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r272805 r272931  
    602602RenderBlock* RenderElement::containingBlockForAbsolutePosition() const
    603603{
    604     // A relatively positioned RenderInline forwards its absolute positioned descendants to
    605     // its nearest non-anonymous containing block (to avoid having a positioned objects list in all RenderInlines).
    606     auto* renderer = isRenderInline() ? const_cast<RenderElement*>(downcast<RenderElement>(this)) : parent();
    607     while (renderer && !renderer->canContainAbsolutelyPositionedObjects())
    608         renderer = renderer->parent();
     604    auto nearestNonAnonymousContainingBlockIncludingSelf = [&] (auto* renderer) {
     605        while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
     606            renderer = renderer->containingBlock();
     607        return downcast<RenderBlock>(renderer);
     608    };
     609
     610    if (is<RenderInline>(*this) && style().position() == PositionType::Relative) {
     611        // A relatively positioned RenderInline forwards its absolute positioned descendants to
     612        // its nearest non-anonymous containing block (to avoid having positioned objects list in RenderInlines).
     613        return nearestNonAnonymousContainingBlockIncludingSelf(parent());
     614    }
     615    auto* ancestor = parent();
     616    while (ancestor && !ancestor->canContainAbsolutelyPositionedObjects())
     617        ancestor = ancestor->parent();
    609618    // Make sure we only return non-anonymous RenderBlock as containing block.
    610     while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
    611         renderer = renderer->containingBlock();
    612     return downcast<RenderBlock>(renderer);
     619    return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
    613620}
    614621
Note: See TracChangeset for help on using the changeset viewer.