Changeset 150383 in webkit


Ignore:
Timestamp:
May 20, 2013 2:38:37 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[CSSRegions] Fix offsetLeft / offsetTop for elements inside named flow
https://bugs.webkit.org/show_bug.cgi?id=115899

Patch by Radu Stavila <stavila@adobe.com> on 2013-05-20
Reviewed by David Hyatt.

Source/WebCore:

Elements in named flows that have the body as their offsetParent, need to compute their
offsetLeft and offsetTop values relative to the body.

Tests: fast/regions/offsetLeft-offsetTop-in-multiple-regions.html

fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed.html
fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl.html
fast/regions/offsetLeft-offsetTop-in-region-float.html
fast/regions/offsetLeft-offsetTop-inlines-region-in-element.html

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent):

  • rendering/RenderFlowThread.cpp:

(WebCore):
(WebCore::RenderFlowThread::adjustedPositionRelativeToOffsetParent):

  • rendering/RenderFlowThread.h:

LayoutTests:

Added tests for the implementation of offsetLeft and offsetTop for objects inside named flows
for which the offsetParent is the body.

  • fast/regions/offsetLeft-offsetTop-in-multiple-regions-expected.txt: Added.
  • fast/regions/offsetLeft-offsetTop-in-multiple-regions.html: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed-expected.txt: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed.html: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-float-expected.txt: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl-expected.txt: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl.html: Added.
  • fast/regions/offsetLeft-offsetTop-in-region-float.html: Added.
  • fast/regions/offsetLeft-offsetTop-inlines-region-in-element-expected.txt: Added.
  • fast/regions/offsetLeft-offsetTop-inlines-region-in-element.html: Added.
Location:
trunk
Files:
10 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r150382 r150383  
     12013-05-20  Radu Stavila  <stavila@adobe.com>
     2
     3        [CSSRegions] Fix offsetLeft / offsetTop for elements inside named flow
     4        https://bugs.webkit.org/show_bug.cgi?id=115899
     5
     6        Reviewed by David Hyatt.
     7
     8        Added tests for the implementation of offsetLeft and offsetTop for objects inside named flows
     9        for which the offsetParent is the body.
     10
     11        * fast/regions/offsetLeft-offsetTop-in-multiple-regions-expected.txt: Added.
     12        * fast/regions/offsetLeft-offsetTop-in-multiple-regions.html: Added.
     13        * fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed-expected.txt: Added.
     14        * fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed.html: Added.
     15        * fast/regions/offsetLeft-offsetTop-in-region-float-expected.txt: Added.
     16        * fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl-expected.txt: Added.
     17        * fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl.html: Added.
     18        * fast/regions/offsetLeft-offsetTop-in-region-float.html: Added.
     19        * fast/regions/offsetLeft-offsetTop-inlines-region-in-element-expected.txt: Added.
     20        * fast/regions/offsetLeft-offsetTop-inlines-region-in-element.html: Added.
     21
    1222013-05-20  Brent Fulgham  <bfulgham@apple.com>
    223
  • trunk/Source/WebCore/ChangeLog

    r150375 r150383  
     12013-05-20  Radu Stavila  <stavila@adobe.com>
     2
     3        [CSSRegions] Fix offsetLeft / offsetTop for elements inside named flow
     4        https://bugs.webkit.org/show_bug.cgi?id=115899
     5
     6        Reviewed by David Hyatt.
     7
     8        Elements in named flows that have the body as their offsetParent, need to compute their
     9        offsetLeft and offsetTop values relative to the body.
     10
     11        Tests: fast/regions/offsetLeft-offsetTop-in-multiple-regions.html
     12               fast/regions/offsetLeft-offsetTop-in-region-absolute-sticky-fixed.html
     13               fast/regions/offsetLeft-offsetTop-in-region-float-vert-rl.html
     14               fast/regions/offsetLeft-offsetTop-in-region-float.html
     15               fast/regions/offsetLeft-offsetTop-inlines-region-in-element.html
     16
     17        * rendering/RenderBoxModelObject.cpp:
     18        (WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent):
     19        * rendering/RenderFlowThread.cpp:
     20        (WebCore):
     21        (WebCore::RenderFlowThread::adjustedPositionRelativeToOffsetParent):
     22        * rendering/RenderFlowThread.h:
     23
    1242013-05-20  Zoltan Horvath  <zoltan@webkit.org>
    225
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r150108 r150383  
    3636#include "RenderInline.h"
    3737#include "RenderLayer.h"
     38#include "RenderNamedFlowThread.h"
     39#include "RenderRegion.h"
    3840#include "RenderView.h"
    3941#include "ScrollingConstraints.h"
     
    492494        if (offsetParent->isBox() && !offsetParent->isBody())
    493495            referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRenderBox(offsetParent)->borderTop());
    494         if (!isOutOfFlowPositioned()) {
     496        if (!isOutOfFlowPositioned() || flowThreadContainingBlock()) {
    495497            if (isRelPositioned())
    496498                referencePoint.move(relativePositionOffset());
     
    498500                referencePoint.move(stickyPositionOffset());
    499501           
    500             // FIXME: The offset position for elements inside named flow threads is not correctly computed when the offsetParent is body
    501             // See https://bugs.webkit.org/show_bug.cgi?id=115899
    502            
    503502            // CSS regions specification says that region flows should return the body element as their offsetParent.
    504503            // Since we will bypass the body’s renderer anyway, just end the loop if we encounter a region flow (named flow thread).
    505504            // See http://dev.w3.org/csswg/css-regions/#cssomview-offset-attributes
    506             const RenderObject* curr = parent();
     505            RenderObject* curr = parent();
    507506            while (curr != offsetParent && !curr->isRenderNamedFlowThread()) {
    508507                // FIXME: What are we supposed to do inside SVG content?
    509                 if (curr->isBox() && !curr->isTableRow())
    510                     referencePoint.moveBy(toRenderBox(curr)->topLeftLocation());
    511                 referencePoint.move(curr->parent()->offsetForColumns(referencePoint));
     508                if (!isOutOfFlowPositioned()) {
     509                    if (curr->isBox() && !curr->isTableRow())
     510                        referencePoint.moveBy(toRenderBox(curr)->topLeftLocation());
     511                    referencePoint.move(curr->parent()->offsetForColumns(referencePoint));
     512                }
    512513                curr = curr->parent();
    513514            }
    514             if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent->isPositioned())
     515           
     516            // Compute the offset position for elements inside named flow threads for which the offsetParent was the body.
     517            // See https://bugs.webkit.org/show_bug.cgi?id=115899
     518            if (curr->isRenderNamedFlowThread())
     519                referencePoint = toRenderNamedFlowThread(curr)->adjustedPositionRelativeToOffsetParent(*this, referencePoint);
     520            else if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent->isPositioned())
    515521                referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation());
    516522        }
  • trunk/Source/WebCore/rendering/RenderFlowThread.cpp

    r150078 r150383  
    3939#include "PaintInfo.h"
    4040#include "RenderBoxRegionInfo.h"
     41#include "RenderInline.h"
    4142#include "RenderLayer.h"
    4243#include "RenderRegion.h"
     
    390391    return adapter.result();
    391392}
     393   
     394LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject& boxModelObject, const LayoutPoint& startPoint)
     395{
     396    LayoutPoint referencePoint = startPoint;
     397   
     398    // FIXME: This needs to be adapted for different writing modes inside the flow thread.
     399    RenderRegion* startRegion = regionAtBlockOffset(referencePoint.y());
     400    if (startRegion) {
     401        // Take into account the offset coordinates of the region.
     402        RenderBoxModelObject* currObject = startRegion;
     403        RenderBoxModelObject* currOffsetParent;
     404        while ((currOffsetParent = currObject->offsetParent())) {
     405            referencePoint.move(currObject->offsetLeft(), currObject->offsetTop());
     406           
     407            // Since we're looking for the offset relative to the body, we must also
     408            // take into consideration the borders of the region's offsetParent.
     409            if (currOffsetParent->isBox() && !currOffsetParent->isBody())
     410                referencePoint.move(toRenderBox(currOffsetParent)->borderLeft(), toRenderBox(currOffsetParent)->borderTop());
     411           
     412            currObject = currOffsetParent;
     413        }
     414       
     415        // We need to check if any of this box's containing blocks start in a different region
     416        // and if so, drop the object's top position (which was computed relative to its containing block
     417        // and is no longer valid) and recompute it using the region in which it flows as reference.
     418        bool wasComputedRelativeToOtherRegion = false;
     419        const RenderBlock* objContainingBlock = boxModelObject.containingBlock();
     420        while (objContainingBlock && !objContainingBlock->isRenderNamedFlowThread()) {
     421            // Check if this object is in a different region.
     422            RenderRegion* parentStartRegion = 0;
     423            RenderRegion* parentEndRegion = 0;
     424            getRegionRangeForBox(objContainingBlock, parentStartRegion, parentEndRegion);
     425            if (parentStartRegion && parentStartRegion != startRegion) {
     426                wasComputedRelativeToOtherRegion = true;
     427                break;
     428            }
     429            objContainingBlock = objContainingBlock->containingBlock();
     430        }
     431       
     432        if (wasComputedRelativeToOtherRegion) {
     433            if (boxModelObject.isBox()) {
     434                // Use borderBoxRectInRegion to account for variations such as percentage margins.
     435                LayoutRect borderBoxRect = toRenderBox(&boxModelObject)->borderBoxRectInRegion(startRegion, 0, RenderBox::DoNotCacheRenderBoxRegionInfo);
     436                referencePoint.move(borderBoxRect.location().x(), 0);
     437            }
     438           
     439            // Get the logical top coordinate of the current object.
     440            LayoutUnit top = 0;
     441            if (boxModelObject.isRenderBlock())
     442                top = toRenderBlock(&boxModelObject)->offsetFromLogicalTopOfFirstPage();
     443            else {
     444                if (boxModelObject.containingBlock())
     445                    top = boxModelObject.containingBlock()->offsetFromLogicalTopOfFirstPage();
     446               
     447                if (boxModelObject.isBox())
     448                    top += toRenderBox(&boxModelObject)->topLeftLocation().y();
     449                else if (boxModelObject.isRenderInline())
     450                    top -= toRenderInline(&boxModelObject)->borderTop();
     451            }
     452           
     453            // Get the logical top of the region this object starts in
     454            // and compute the object's top, relative to the region's top.
     455            LayoutUnit regionLogicalTop = startRegion->pageLogicalTopForOffset(top);
     456            LayoutUnit topRelativeToRegion = top - regionLogicalTop;
     457            referencePoint.setY(startRegion->offsetTop() + topRelativeToRegion);
     458           
     459            // Since the top has been overriden, check if the
     460            // relative/sticky positioning must be reconsidered.
     461            if (boxModelObject.isRelPositioned())
     462                referencePoint.move(0, boxModelObject.relativePositionOffset().height());
     463            else if (boxModelObject.isStickyPositioned())
     464                referencePoint.move(0, boxModelObject.stickyPositionOffset().height());
     465        }
     466       
     467        // Since we're looking for the offset relative to the body, we must also
     468        // take into consideration the borders of the region.
     469        referencePoint.move(startRegion->borderLeft(), startRegion->borderTop());
     470    }
     471   
     472    return referencePoint;
     473}
    392474
    393475LayoutUnit RenderFlowThread::pageLogicalTopForOffset(LayoutUnit offset)
  • trunk/Source/WebCore/rendering/RenderFlowThread.h

    r150312 r150383  
    9696
    9797    void repaintRectangleInRegions(const LayoutRect&, bool immediate) const;
     98   
     99    LayoutPoint adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject&, const LayoutPoint&);
    98100
    99101    LayoutUnit pageLogicalTopForOffset(LayoutUnit);
Note: See TracChangeset for help on using the changeset viewer.