⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287744 in webkit


Ignore:
Timestamp:
Jan 7, 2022, 7:08:00 AM (5 years ago)
Author:
Alan Bujtas
Message:

[Cleanup] RenderElement::containingBlockFor*(fixed/absolute/inflow)Position is slightly confusing
https://bugs.webkit.org/show_bug.cgi?id=234939

Reviewed by Antti Koivisto.

These 3 helper functions (containingBlockForFixedPosition/containingBlockForAbsolutePosition/containingBlockForObjectInFlow)
are expected to return an ancestor renderer which would act as the containing block if the renderer was
fixed/absolute/inflow positioned (in their current form they should read as containingBlockIfTheRendererWasFixedPositioned..)

These functions were introduced as part of LogicalSelectionOffsetCaches where we cache all 3 types of
containing blocks (fixed/absolute/inflow) to save containingBlock() calls as the cached object gets propagated
to ancestor renderers (so we really have a "what if" type of use case).

After some refactoring (and moving them out of LogicalSelectionOffsetCaches), we started introducing more and more
callsites of these functions where the "what if" question made less sense.

This patch replaces these 3 functions with a static helper:

static RenderBlock* containingBlockForPositionType(PositionType, const RenderObject&);

While it does not make the callsites look much cleaner, it helps to stop the spread of the special containing block handling for top-layer/backdrop boxes.

  • dom/Element.cpp:

(WebCore::layoutOverflowRectContainsAllDescendants):

  • rendering/LogicalSelectionOffsetCaches.h:

(WebCore::LogicalSelectionOffsetCaches::LogicalSelectionOffsetCaches):

  • rendering/RenderElement.cpp:

(WebCore::nearestNonAnonymousContainingBlockIncludingSelf): Deleted.
(WebCore::RenderElement::containingBlockForFixedPosition const): Deleted.
(WebCore::RenderElement::containingBlockForAbsolutePosition const): Deleted.

  • rendering/RenderElement.h:
  • rendering/RenderInline.cpp:

(WebCore::RenderInline::styleWillChange):

  • rendering/RenderLineBreak.cpp:

(WebCore::RenderLineBreak::collectSelectionGeometries):

  • rendering/RenderObject.cpp:

(WebCore::nearestNonAnonymousContainingBlockIncludingSelf):
(WebCore::RenderObject::containingBlockForPositionType):
(WebCore::RenderObject::containingBlock const):
(WebCore::RenderObject::containingBlockForObjectInFlow const): Deleted.

  • rendering/RenderObject.h:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r287743 r287744  
     12022-01-07  Alan Bujtas  <zalan@apple.com>
     2
     3        [Cleanup] RenderElement::containingBlockFor*(fixed/absolute/inflow)Position is slightly confusing
     4        https://bugs.webkit.org/show_bug.cgi?id=234939
     5
     6        Reviewed by Antti Koivisto.
     7
     8        These 3 helper functions (containingBlockForFixedPosition/containingBlockForAbsolutePosition/containingBlockForObjectInFlow)
     9        are expected to return an ancestor renderer which would act as the containing block if the renderer was
     10        fixed/absolute/inflow positioned (in their current form they should read as containingBlockIfTheRendererWasFixedPositioned..)
     11
     12        These functions were introduced as part of LogicalSelectionOffsetCaches where we cache all 3 types of
     13        containing blocks (fixed/absolute/inflow) to save containingBlock() calls as the cached object gets propagated
     14        to ancestor renderers (so we really have a "what if" type of use case).
     15
     16        After some refactoring (and moving them out of LogicalSelectionOffsetCaches), we started introducing more and more
     17        callsites of these functions where the "what if" question made less sense.
     18
     19        This patch replaces these 3 functions with a static helper:
     20          static RenderBlock* containingBlockForPositionType(PositionType, const RenderObject&);
     21        While it does not make the callsites look much cleaner, it helps to stop the spread of the special containing block handling for top-layer/backdrop boxes.
     22
     23        * dom/Element.cpp:
     24        (WebCore::layoutOverflowRectContainsAllDescendants):
     25        * rendering/LogicalSelectionOffsetCaches.h:
     26        (WebCore::LogicalSelectionOffsetCaches::LogicalSelectionOffsetCaches):
     27        * rendering/RenderElement.cpp:
     28        (WebCore::nearestNonAnonymousContainingBlockIncludingSelf): Deleted.
     29        (WebCore::RenderElement::containingBlockForFixedPosition const): Deleted.
     30        (WebCore::RenderElement::containingBlockForAbsolutePosition const): Deleted.
     31        * rendering/RenderElement.h:
     32        * rendering/RenderInline.cpp:
     33        (WebCore::RenderInline::styleWillChange):
     34        * rendering/RenderLineBreak.cpp:
     35        (WebCore::RenderLineBreak::collectSelectionGeometries):
     36        * rendering/RenderObject.cpp:
     37        (WebCore::nearestNonAnonymousContainingBlockIncludingSelf):
     38        (WebCore::RenderObject::containingBlockForPositionType):
     39        (WebCore::RenderObject::containingBlock const):
     40        (WebCore::RenderObject::containingBlockForObjectInFlow const): Deleted.
     41        * rendering/RenderObject.h:
     42
    1432022-01-06  Nikolas Zimmermann  <nzimmermann@igalia.com>
    244
  • trunk/Source/WebCore/dom/Element.cpp

    r287707 r287744  
    15861586
    15871587    // This renderer may have positioned descendants whose containing block is some ancestor.
    1588     if (auto* containingBlock = renderBox.containingBlockForAbsolutePosition()) {
     1588    if (auto* containingBlock = RenderObject::containingBlockForPositionType(PositionType::Absolute, renderBox)) {
    15891589        if (auto* positionedObjects = containingBlock->positionedObjects()) {
    15901590            for (auto* positionedBox : *positionedObjects) {
  • trunk/Source/WebCore/rendering/LogicalSelectionOffsetCaches.h

    r238463 r287744  
    9090#endif
    9191        // LogicalSelectionOffsetCaches should not be used on an orphaned tree.
    92         m_containingBlockForFixedPosition.setBlock(rootBlock.containingBlockForFixedPosition(), nullptr);
    93         m_containingBlockForAbsolutePosition.setBlock(rootBlock.containingBlockForAbsolutePosition(), nullptr);
    94         m_containingBlockForInflowPosition.setBlock(rootBlock.containingBlockForObjectInFlow(), nullptr);
     92        m_containingBlockForFixedPosition.setBlock(RenderObject::containingBlockForPositionType(PositionType::Fixed, rootBlock), nullptr);
     93        m_containingBlockForAbsolutePosition.setBlock(RenderObject::containingBlockForPositionType(PositionType::Absolute, rootBlock), nullptr);
     94        m_containingBlockForInflowPosition.setBlock(RenderObject::containingBlockForPositionType(PositionType::Static, rootBlock), nullptr);
    9595    }
    9696
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r287567 r287744  
    635635}
    636636
    637 static inline RenderBlock* nearestNonAnonymousContainingBlockIncludingSelf(RenderElement* renderer)
    638 {
    639     while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
    640         renderer = renderer->containingBlock();
    641     return downcast<RenderBlock>(renderer);
    642 }
    643 
    644 RenderBlock* RenderElement::containingBlockForFixedPosition() const
    645 {
    646     auto* ancestor = parent();
    647     while (ancestor && !ancestor->canContainFixedPositionObjects())
    648         ancestor = ancestor->parent();
    649     return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
    650 }
    651 
    652 RenderBlock* RenderElement::containingBlockForAbsolutePosition() const
    653 {
    654     if (is<RenderInline>(*this) && style().position() == PositionType::Relative) {
    655         // A relatively positioned RenderInline forwards its absolute positioned descendants to
    656         // its nearest non-anonymous containing block (to avoid having positioned objects list in RenderInlines).
    657         return nearestNonAnonymousContainingBlockIncludingSelf(parent());
    658     }
    659     auto* ancestor = parent();
    660     while (ancestor && !ancestor->canContainAbsolutelyPositionedObjects())
    661         ancestor = ancestor->parent();
    662     // Make sure we only return non-anonymous RenderBlock as containing block.
    663     return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
    664 }
    665 
    666637static void addLayers(RenderElement& renderer, RenderLayer* parentLayer, RenderElement*& newObject, RenderLayer*& beforeChild)
    667638{
  • trunk/Source/WebCore/rendering/RenderElement.h

    r285885 r287744  
    235235    WEBCORE_EXPORT void resetTextAutosizing();
    236236#endif
    237     RenderBlock* containingBlockForFixedPosition() const;
    238     RenderBlock* containingBlockForAbsolutePosition() const;
    239237
    240238    WEBCORE_EXPORT ImageOrientation imageOrientation() const;
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r287519 r287744  
    160160    // Check if this non-anonymous containing block can hold the absolute positioned elements when the inline is no longer positioned.
    161161    if (canContainAbsolutelyPositionedObjects() && newStyle.position() == PositionType::Static) {
    162         auto* container = containingBlockForAbsolutePosition();
     162        auto* container = RenderObject::containingBlockForPositionType(PositionType::Absolute, *this);
    163163        if (container && !container->canContainAbsolutelyPositionedObjects())
    164164            container->removePositionedObjects(nullptr, NewContainingBlock);
  • trunk/Source/WebCore/rendering/RenderLineBreak.cpp

    r283851 r287744  
    200200    }
    201201
    202     auto* containingBlock = containingBlockForObjectInFlow();
     202    // FIXME: Out-of-flow positioned line breaks do not follow normal containing block chain.
     203    auto* containingBlock = RenderObject::containingBlockForPositionType(PositionType::Static, *this);
    203204    // Map rect, extended left to leftOffset, and right to rightOffset, through transforms to get minX and maxX.
    204205    LogicalSelectionOffsetCaches cache(*containingBlock);
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r287683 r287744  
    657657}
    658658
     659static inline RenderBlock* nearestNonAnonymousContainingBlockIncludingSelf(RenderElement* renderer)
     660{
     661    while (renderer && (!is<RenderBlock>(*renderer) || renderer->isAnonymousBlock()))
     662        renderer = renderer->containingBlock();
     663    return downcast<RenderBlock>(renderer);
     664}
     665
     666RenderBlock* RenderObject::containingBlockForPositionType(PositionType positionType, const RenderObject& renderer)
     667{
     668    if (positionType == PositionType::Static || positionType == PositionType::Relative || positionType == PositionType::Sticky) {
     669        auto containingBlockForObjectInFlow = [&] {
     670            auto* ancestor = renderer.parent();
     671            while (ancestor && ((ancestor->isInline() && !ancestor->isReplaced()) || !ancestor->isRenderBlock()))
     672                ancestor = ancestor->parent();
     673            return downcast<RenderBlock>(ancestor);
     674        };
     675        return containingBlockForObjectInFlow();
     676    }
     677
     678    if (positionType == PositionType::Absolute) {
     679        auto containingBlockForAbsolutePosition = [&] {
     680            if (is<RenderInline>(renderer) && renderer.style().position() == PositionType::Relative) {
     681                // A relatively positioned RenderInline forwards its absolute positioned descendants to
     682                // its nearest non-anonymous containing block (to avoid having positioned objects list in RenderInlines).
     683                return nearestNonAnonymousContainingBlockIncludingSelf(renderer.parent());
     684            }
     685            auto* ancestor = renderer.parent();
     686            while (ancestor && !ancestor->canContainAbsolutelyPositionedObjects())
     687                ancestor = ancestor->parent();
     688            // Make sure we only return non-anonymous RenderBlock as containing block.
     689            return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
     690        };
     691        return containingBlockForAbsolutePosition();
     692    }
     693
     694    if (positionType == PositionType::Fixed) {
     695        auto containingBlockForFixedPosition = [&] {
     696            auto* ancestor = renderer.parent();
     697            while (ancestor && !ancestor->canContainFixedPositionObjects())
     698                ancestor = ancestor->parent();
     699            return nearestNonAnonymousContainingBlockIncludingSelf(ancestor);
     700        };
     701        return containingBlockForFixedPosition();
     702    }
     703
     704    ASSERT_NOT_REACHED();
     705    return nullptr;
     706}
     707
    659708RenderBlock* RenderObject::containingBlock() const
    660709{
     710    if (is<RenderText>(*this))
     711        return containingBlockForPositionType(PositionType::Static, *this);
     712
    661713    auto containingBlockForRenderer = [](const auto& renderer) -> RenderBlock* {
    662714        if (isInTopLayerOrBackdrop(renderer.style(), renderer.element()))
    663715            return &renderer.view();
    664         if (renderer.isAbsolutelyPositioned())
    665             return renderer.containingBlockForAbsolutePosition();
    666         if (renderer.isFixedPositioned())
    667             return renderer.containingBlockForFixedPosition();
    668         return renderer.containingBlockForObjectInFlow();
     716        return containingBlockForPositionType(renderer.style().position(), renderer);
    669717    };
    670 
    671     if (is<RenderText>(*this))
    672         return containingBlockForObjectInFlow();
    673718
    674719    if (!parent() && is<RenderScrollbarPart>(*this)) {
     
    678723    }
    679724    return containingBlockForRenderer(downcast<RenderElement>(*this));
    680 }
    681 
    682 RenderBlock* RenderObject::containingBlockForObjectInFlow() const
    683 {
    684     auto* renderer = parent();
    685     while (renderer && ((renderer->isInline() && !renderer->isReplaced()) || !renderer->isRenderBlock()))
    686         renderer = renderer->parent();
    687     return downcast<RenderBlock>(renderer);
    688725}
    689726
  • trunk/Source/WebCore/rendering/RenderObject.h

    r287677 r287744  
    539539    // Returns the containing block level element for this element.
    540540    WEBCORE_EXPORT RenderBlock* containingBlock() const;
    541     RenderBlock* containingBlockForObjectInFlow() const;
     541    static RenderBlock* containingBlockForPositionType(PositionType, const RenderObject&);
    542542
    543543    // Convert the given local point to absolute coordinates. If OptionSet<MapCoordinatesMode> includes UseTransforms, take transforms into account.
Note: See TracChangeset for help on using the changeset viewer.