Changeset 53173 in webkit


Ignore:
Timestamp:
Jan 12, 2010 6:08:10 PM (14 years ago)
Author:
Simon Fraser
Message:

2010-01-12 Simon Fraser <Simon Fraser>

Reviewed by Dan Bernstein.

position:fixed and transform on same element breaks fixed behavior
https://bugs.webkit.org/show_bug.cgi?id=31283

Fix interactions of transforms and fixed positioning, namely that fixed position
elements with a transformed ancestor are positioned relative to that ancestor,
and an element with both a transform and fixed position respects that positioning.

Test: transforms/2d/transform-fixed-container.html

  • rendering/RenderBox.cpp: (WebCore::RenderBox::mapLocalToContainer): (WebCore::RenderBox::mapAbsoluteToLocalPoint): Transforms should not unconditionally stop the propagation of the 'fixed' flag to ancestors, but only if the transformed element is not itself fixed.
  • rendering/RenderLayer.cpp: (WebCore::RenderLayer::convertToLayerCoords): Fix this method to behave correctly for fixed position layers whose container is not the root, but some other (probably transformed) ancestor. In that case, we can fall into the "position: absolute" code path.
Location:
trunk
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r53172 r53173  
     12010-01-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        position:fixed and transform on same element breaks fixed behavior
     6        https://bugs.webkit.org/show_bug.cgi?id=31283
     7
     8        Test for transforms combined with fixed positioning.
     9
     10        * platform/mac/transforms/2d/transform-fixed-container-expected.checksum: Added.
     11        * platform/mac/transforms/2d/transform-fixed-container-expected.png: Added.
     12        * platform/mac/transforms/2d/transform-fixed-container-expected.txt: Added.
     13        * transforms/2d/transform-fixed-container.html: Added.
     14
    1152010-01-12  Dumitru Daniliuc  <dumi@chromium.org>
    216
  • trunk/WebCore/ChangeLog

    r53171 r53173  
     12010-01-12  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        position:fixed and transform on same element breaks fixed behavior
     6        https://bugs.webkit.org/show_bug.cgi?id=31283
     7
     8        Fix interactions of transforms and fixed positioning, namely that fixed position
     9        elements with a transformed ancestor are positioned relative to that ancestor,
     10        and an element with both a transform and fixed position respects that positioning.
     11       
     12        Test: transforms/2d/transform-fixed-container.html
     13
     14        * rendering/RenderBox.cpp:
     15        (WebCore::RenderBox::mapLocalToContainer):
     16        (WebCore::RenderBox::mapAbsoluteToLocalPoint):
     17        Transforms should not unconditionally stop the propagation of the 'fixed' flag to ancestors,
     18        but only if the transformed element is not itself fixed.
     19       
     20        * rendering/RenderLayer.cpp:
     21        (WebCore::RenderLayer::convertToLayerCoords):
     22        Fix this method to behave correctly for fixed position layers whose container is not
     23        the root, but some other (probably transformed) ancestor. In that case, we can fall into
     24        the "position: absolute" code path.
     25
    1262010-01-12  Tony Chang  <tony@chromium.org>
    227
  • trunk/WebCore/rendering/RenderBox.cpp

    r52632 r53173  
    942942    }
    943943
    944     if (style()->position() == FixedPosition)
    945         fixed = true;
    946 
    947944    bool containerSkipped;
    948945    RenderObject* o = container(repaintContainer, &containerSkipped);
     
    950947        return;
    951948
     949    bool isFixedPos = style()->position() == FixedPosition;
    952950    bool hasTransform = hasLayer() && layer()->transform();
    953     if (hasTransform)
    954         fixed = false;  // Elements with transforms act as a containing block for fixed position descendants
    955 
     951    if (hasTransform) {
     952        // If this box has a transform, it acts as a fixed position container for fixed descendants,
     953        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
     954        fixed &= isFixedPos;
     955    } else
     956        fixed |= isFixedPos;
     957   
    956958    IntSize containerOffset = offsetFromContainer(o);
    957959
     
    980982    ASSERT(!view() || !view()->layoutStateEnabled());
    981983   
    982     if (style()->position() == FixedPosition)
    983         fixed = true;
    984 
     984    bool isFixedPos = style()->position() == FixedPosition;
    985985    bool hasTransform = hasLayer() && layer()->transform();
    986     if (hasTransform)
    987         fixed = false;  // Elements with transforms act as a containing block for fixed position descendants
     986    if (hasTransform) {
     987        // If this box has a transform, it acts as a fixed position container for fixed descendants,
     988        // and may itself also be fixed position. So propagate 'fixed' up only if this box is fixed position.
     989        fixed &= isFixedPos;
     990    } else
     991        fixed |= isFixedPos;
    988992   
    989993    RenderObject* o = container();
  • trunk/WebCore/rendering/RenderLayer.cpp

    r53110 r53173  
    987987    if (ancestorLayer == this)
    988988        return;
    989        
    990     if (renderer()->style()->position() == FixedPosition) {
    991         // Add in the offset of the view.  We can obtain this by calling
     989
     990    EPosition position = renderer()->style()->position();
     991    if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer()) {
     992        // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
    992993        // localToAbsolute() on the RenderView.
    993994        FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
     
    998999 
    9991000    RenderLayer* parentLayer;
    1000     if (renderer()->style()->position() == AbsolutePosition) {
    1001         // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way
     1001    // For a fixed layer, if we're asking for coords relative to some other ancestor, then it must be
     1002    // enclosed in a fixed position container (e.g. a transformed element), so it behaves like an absolutely
     1003    // positioned element.
     1004    if (position == AbsolutePosition || position == FixedPosition) {
     1005        // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
    10021006        parentLayer = parent();
    10031007        bool foundAncestorFirst = false;
Note: See TracChangeset for help on using the changeset viewer.