Changeset 140024 in webkit


Ignore:
Timestamp:
Jan 17, 2013 12:20:11 PM (11 years ago)
Author:
robert@webkit.org
Message:

Nested fixed position element not staying with parent
https://bugs.webkit.org/show_bug.cgi?id=65477

Reviewed by David Hyatt.

Source/WebCore:

Tests: fast/inline/fixed-pos-moves-with-abspos-inline-parent.html

fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor.html
fast/inline/fixed-pos-moves-with-abspos-parent.html
fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent.html

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::simplifiedLayout):
If an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
child, neither the container nor the fixed element learn of the movement since posChildNeedsLayout() is only marked as far as the
relative positioned container. So if our positioned objects list can contain fixed position elements perform the
checks in markFixedPositionObjectForLayoutIfNeeded for each fixed pos object in the container's positioned object list.
(WebCore::RenderBlock::markFixedPositionObjectForLayoutIfNeeded):
For a fixed position element in the positioned objects list that has a static x or y position check for an absolute positioned ancestor
and if we find one, see if the static x or y position of the fixed pos element has changed. If it has, mark it for layout.
(WebCore):
(WebCore::RenderBlock::layoutPositionedObjects):
A fixed position element with an absolute position ancestor has no way of learning if the latter has changed position. So perform the
checks in markFixedPositionObjectForLayoutIfNeeded for each fixed pos object in the container's positioned object list.

  • rendering/RenderBlock.h:

(RenderBlock):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::containingBlock): Use new helper function canContainFixedPositionObjects().

  • rendering/RenderObject.h:

(WebCore::RenderObject::canContainFixedPositionObjects):
(RenderObject):

LayoutTests:

  • fast/inline/fixed-pos-moves-with-abspos-inline-parent-expected.txt: Added.
  • fast/inline/fixed-pos-moves-with-abspos-inline-parent.html: Added.
  • fast/inline/fixed-pos-moves-with-abspos-parent-expected.txt: Added.
  • fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor-expected.txt: Added.
  • fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor.html: Added.
  • fast/inline/fixed-pos-moves-with-abspos-parent.html: Added.
  • fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent-expected.txt: Added.
  • fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent.html: Added.
Location:
trunk
Files:
8 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r140014 r140024  
     12013-01-17  Robert Hogan  <robert@webkit.org>
     2
     3        Nested fixed position element not staying with parent
     4        https://bugs.webkit.org/show_bug.cgi?id=65477
     5
     6        Reviewed by David Hyatt.
     7
     8        * fast/inline/fixed-pos-moves-with-abspos-inline-parent-expected.txt: Added.
     9        * fast/inline/fixed-pos-moves-with-abspos-inline-parent.html: Added.
     10        * fast/inline/fixed-pos-moves-with-abspos-parent-expected.txt: Added.
     11        * fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor-expected.txt: Added.
     12        * fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor.html: Added.
     13        * fast/inline/fixed-pos-moves-with-abspos-parent.html: Added.
     14        * fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent-expected.txt: Added.
     15        * fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent.html: Added.
     16
    1172013-01-17  Andrei Bucur  <abucur@adobe.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r140023 r140024  
     12013-01-17  Robert Hogan  <robert@webkit.org>
     2
     3        Nested fixed position element not staying with parent
     4        https://bugs.webkit.org/show_bug.cgi?id=65477
     5
     6        Reviewed by David Hyatt.
     7
     8        Tests: fast/inline/fixed-pos-moves-with-abspos-inline-parent.html
     9               fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor.html
     10               fast/inline/fixed-pos-moves-with-abspos-parent.html
     11               fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent.html
     12
     13        * rendering/RenderBlock.cpp:
     14        (WebCore::RenderBlock::simplifiedLayout):
     15        If an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
     16        child, neither the container nor the fixed element learn of the movement since posChildNeedsLayout() is only marked as far as the
     17        relative positioned container. So if our positioned objects list can contain fixed position elements perform the
     18        checks in markFixedPositionObjectForLayoutIfNeeded for each fixed pos object in the container's positioned object list.
     19        (WebCore::RenderBlock::markFixedPositionObjectForLayoutIfNeeded):
     20        For a fixed position element in the positioned objects list that has a static x or y position check for an absolute positioned ancestor
     21        and if we find one, see if the static x or y position of the fixed pos element has changed. If it has, mark it for layout.
     22        (WebCore):
     23        (WebCore::RenderBlock::layoutPositionedObjects):
     24        A fixed position element with an absolute position ancestor has no way of learning if the latter has changed position. So perform the
     25        checks in markFixedPositionObjectForLayoutIfNeeded for each fixed pos object in the container's positioned object list.
     26        * rendering/RenderBlock.h:
     27        (RenderBlock):
     28        * rendering/RenderObject.cpp:
     29        (WebCore::RenderObject::containingBlock): Use new helper function canContainFixedPositionObjects().
     30        * rendering/RenderObject.h:
     31        (WebCore::RenderObject::canContainFixedPositionObjects):
     32        (RenderObject):
     33
    1342013-01-17  Antti Koivisto  <antti@apple.com>
    235
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r140023 r140024  
    25902590
    25912591    // Lay out our positioned objects if our positioned child bit is set.
    2592     if (posChildNeedsLayout())
    2593         layoutPositionedObjects(false);
     2592    // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
     2593    // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
     2594    // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
     2595    // are statically positioned and thus need to move with their absolute ancestors.
     2596    bool canContainFixedPosObjects = canContainFixedPositionObjects();
     2597    if (posChildNeedsLayout() || canContainFixedPosObjects)
     2598        layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
    25942599
    25952600    // Recompute our overflow information.
     
    26112616}
    26122617
    2613 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
     2618void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child)
     2619{
     2620    if (child->style()->position() != FixedPosition)
     2621        return;
     2622
     2623    bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
     2624    bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
     2625    if (!hasStaticBlockPosition && !hasStaticInlinePosition)
     2626        return;
     2627
     2628    RenderObject* o = child->parent();
     2629    while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
     2630        o = o->parent();
     2631    if (o->style()->position() != AbsolutePosition)
     2632        return;
     2633
     2634    RenderBox* box = toRenderBox(child);
     2635    if (hasStaticInlinePosition) {
     2636        LayoutUnit oldLeft = box->logicalLeft();
     2637        box->updateLogicalWidth();
     2638        if (box->logicalLeft() != oldLeft)
     2639            child->setChildNeedsLayout(true, MarkOnlyThis);
     2640    } else if (hasStaticBlockPosition) {
     2641        LayoutUnit oldTop = box->logicalTop();
     2642        box->updateLogicalHeight();
     2643        if (box->logicalTop() != oldTop)
     2644            child->setChildNeedsLayout(true, MarkOnlyThis);
     2645    }
     2646}
     2647
     2648void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
    26142649{
    26152650    TrackedRendererListHashSet* positionedDescendants = positionedObjects();
     
    26242659    for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
    26252660        r = *it;
     2661
     2662        // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
     2663        // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
     2664        // it has static position.
     2665        markFixedPositionObjectForLayoutIfNeeded(r);
     2666        if (fixedPositionObjectsOnly)
     2667            continue;
     2668
    26262669        // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
    26272670        // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r140023 r140024  
    466466    virtual void layout();
    467467
    468     void layoutPositionedObjects(bool relayoutChildren);
     468    void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
     469    void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child);
    469470
    470471    virtual void paint(PaintInfo&, const LayoutPoint&);
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r140023 r140024  
    754754    if (!isText() && m_style->position() == FixedPosition) {
    755755        while (o) {
    756             if (o->isRenderView())
     756            if (o->canContainFixedPositionObjects())
    757757                break;
    758             if (o->hasTransform() && o->isRenderBlock())
    759                 break;
    760             // The render flow thread is the top most containing block
    761             // for the fixed positioned elements.
    762             if (o->isRenderFlowThread())
    763                 break;
    764 #if ENABLE(SVG)
    765             // foreignObject is the containing block for its contents.
    766             if (o->isSVGForeignObject())
    767                 break;
    768 #endif
    769758            o = o->parent();
    770759        }
  • trunk/Source/WebCore/rendering/RenderObject.h

    r140023 r140024  
    712712    // returns the containing block level element for this element.
    713713    RenderBlock* containingBlock() const;
     714
     715    bool canContainFixedPositionObjects() const
     716    {
     717        return isRenderView() || (hasTransform() && isRenderBlock())
     718#if ENABLE(SVG)
     719                || isSVGForeignObject()
     720#endif
     721                || isRenderFlowThread();
     722    }
    714723
    715724    // Convert the given local point to absolute coordinates
Note: See TracChangeset for help on using the changeset viewer.