Changeset 116446 in webkit


Ignore:
Timestamp:
May 8, 2012 12:11:14 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

offsetLeft broken within CSS3 columns
https://bugs.webkit.org/show_bug.cgi?id=34875

Patch by Shezan Baig <shezbaig.wk@gmail.com> on 2012-05-08
Reviewed by Julien Chaffraix.

Source/WebCore:

Reimplement offsetLeft and offsetTop in terms of a new method called
'offsetTopLeft'. The new method starts from a reference point (the
top-left coordinate of a box or inline) and adjusts this reference
point for columns as we traverse each parent. Note that the reference
point needs to be adjusted in both dimensions, even though offsetLeft
and offsetTop return only one of them.

A new method called 'offsetForColumns' was added to RenderObject. This
method is similar to adjustForColumns, except that it returns the
offset instead of modifying a reference. This method is necessary to
simplify the implementation of offsetTopLeft.

Tests: fast/block/positioning/offsetLeft-offsetTop-multicolumn-expected.txt

fast/block/positioning/offsetLeft-offsetTop-multicolumn.html

  • rendering/RenderBox.h:

(RenderBox):
Override offsetLeft and offsetTop.

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::offsetLeft):
Implemented in terms of RenderBoxModelObject::offsetTopLeft, using
topLeftLocation as startPoint.
(WebCore::RenderBox::offsetTop):
Implemented in terms of RenderBoxModelObject::offsetTopLeft, using
topLeftLocation as startPoint.

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::offsetTopLeft):
New method to compute offsetLeft and offsetTop simultaneously, and
adjusting for columns at each parent.
(WebCore::RenderBoxModelObject::offsetLeft):
Reimplemented in terms of offsetTopLeft.
(WebCore::RenderBoxModelObject::offsetTop):
Reimplemented in terms of offsetTopLeft.

  • rendering/RenderBoxModelObject.h:

(RenderBoxModelObject):
Declare new offsetTopLeft method.

  • rendering/RenderInline.cpp:

(WebCore::RenderInline::offsetLeft):
Reimplemented in terms of RenderBoxModelObject::offsetTopLeft.
(WebCore::RenderInline::offsetTop):
Reimplemented in terms of RenderBoxModelObject::offsetTopLeft.

  • rendering/RenderObject.h:

(RenderObject):
(WebCore::RenderObject::offsetForColumns):
New helper method to simplify implementation of offsetTopLeft.

LayoutTests:

Add test for offsetLeft and offsetTop within multi-columns.

  • fast/block/positioning/offsetLeft-offsetTop-multicolumn-expected.txt: Added.
  • fast/block/positioning/offsetLeft-offsetTop-multicolumn.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r116445 r116446  
     12012-05-08  Shezan Baig  <shezbaig.wk@gmail.com>
     2
     3        offsetLeft broken within CSS3 columns
     4        https://bugs.webkit.org/show_bug.cgi?id=34875
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        Add test for offsetLeft and offsetTop within multi-columns.
     9
     10        * fast/block/positioning/offsetLeft-offsetTop-multicolumn-expected.txt: Added.
     11        * fast/block/positioning/offsetLeft-offsetTop-multicolumn.html: Added.
     12
    1132012-05-08  Christophe Dumez  <christophe.dumez@intel.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r116438 r116446  
     12012-05-08  Shezan Baig  <shezbaig.wk@gmail.com>
     2
     3        offsetLeft broken within CSS3 columns
     4        https://bugs.webkit.org/show_bug.cgi?id=34875
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        Reimplement offsetLeft and offsetTop in terms of a new method called
     9        'offsetTopLeft'. The new method starts from a reference point (the
     10        top-left coordinate of a box or inline) and adjusts this reference
     11        point for columns as we traverse each parent. Note that the reference
     12        point needs to be adjusted in both dimensions, even though offsetLeft
     13        and offsetTop return only one of them.
     14
     15        A new method called 'offsetForColumns' was added to RenderObject. This
     16        method is similar to adjustForColumns, except that it returns the
     17        offset instead of modifying a reference. This method is necessary to
     18        simplify the implementation of offsetTopLeft.
     19
     20        Tests: fast/block/positioning/offsetLeft-offsetTop-multicolumn-expected.txt
     21               fast/block/positioning/offsetLeft-offsetTop-multicolumn.html
     22
     23        * rendering/RenderBox.h:
     24        (RenderBox):
     25        Override offsetLeft and offsetTop.
     26        * rendering/RenderBox.cpp:
     27        (WebCore::RenderBox::offsetLeft):
     28        Implemented in terms of RenderBoxModelObject::offsetTopLeft, using
     29        topLeftLocation as startPoint.
     30        (WebCore::RenderBox::offsetTop):
     31        Implemented in terms of RenderBoxModelObject::offsetTopLeft, using
     32        topLeftLocation as startPoint.
     33        * rendering/RenderBoxModelObject.cpp:
     34        (WebCore::RenderBoxModelObject::offsetTopLeft):
     35        New method to compute offsetLeft and offsetTop simultaneously, and
     36        adjusting for columns at each parent.
     37        (WebCore::RenderBoxModelObject::offsetLeft):
     38        Reimplemented in terms of offsetTopLeft.
     39        (WebCore::RenderBoxModelObject::offsetTop):
     40        Reimplemented in terms of offsetTopLeft.
     41        * rendering/RenderBoxModelObject.h:
     42        (RenderBoxModelObject):
     43        Declare new offsetTopLeft method.
     44        * rendering/RenderInline.cpp:
     45        (WebCore::RenderInline::offsetLeft):
     46        Reimplemented in terms of RenderBoxModelObject::offsetTopLeft.
     47        (WebCore::RenderInline::offsetTop):
     48        Reimplemented in terms of RenderBoxModelObject::offsetTopLeft.
     49        * rendering/RenderObject.h:
     50        (RenderObject):
     51        (WebCore::RenderObject::offsetForColumns):
     52        New helper method to simplify implementation of offsetTopLeft.
     53
    1542012-03-31  Robert Hogan  <robert@webkit.org>
    255
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r115981 r116446  
    39133913}
    39143914
     3915LayoutUnit RenderBox::offsetLeft() const
     3916{
     3917    return offsetTopLeft(topLeftLocation()).x();
     3918}
     3919
     3920LayoutUnit RenderBox::offsetTop() const
     3921{
     3922    return offsetTopLeft(topLeftLocation()).y();
     3923}
     3924
    39153925LayoutPoint RenderBox::flipForWritingModeForChild(const RenderBox* child, const LayoutPoint& point) const
    39163926{
  • trunk/Source/WebCore/rendering/RenderBox.h

    r115981 r116446  
    434434    virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
    435435
     436    virtual LayoutUnit offsetLeft() const OVERRIDE;
     437    virtual LayoutUnit offsetTop() const OVERRIDE;
     438
    436439    LayoutPoint flipForWritingModeForChild(const RenderBox* child, const LayoutPoint&) const;
    437440    LayoutUnit flipForWritingMode(LayoutUnit position) const; // The offset is in the block direction (y for horizontal writing modes, x for vertical writing modes).
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r116392 r116446  
    536536}
    537537
    538 LayoutUnit RenderBoxModelObject::offsetLeft() const
     538LayoutPoint RenderBoxModelObject::offsetTopLeft(const LayoutPoint& startPoint) const
    539539{
    540540    // If the element is the HTML body element or does not have an associated box
    541541    // return 0 and stop this algorithm.
    542542    if (isBody())
    543         return ZERO_LAYOUT_UNIT;
     543        return LayoutPoint();
    544544   
    545     RenderBoxModelObject* offsetPar = offsetParent();
    546     LayoutUnit xPos = (isBox() ? toRenderBox(this)->left() : ZERO_LAYOUT_UNIT);
     545    LayoutPoint referencePoint = startPoint;
     546    referencePoint.move(parent()->offsetForColumns(referencePoint));
    547547   
    548548    // If the offsetParent of the element is null, or is the HTML body element,
    549549    // return the distance between the canvas origin and the left border edge
    550550    // of the element and stop this algorithm.
    551     if (offsetPar) {
    552         if (offsetPar->isBox() && !offsetPar->isBody())
    553             xPos -= toRenderBox(offsetPar)->borderLeft();
     551    if (const RenderBoxModelObject* offsetParent = this->offsetParent()) {
     552        if (offsetParent->isBox() && !offsetParent->isBody())
     553            referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRenderBox(offsetParent)->borderTop());
    554554        if (!isPositioned()) {
    555555            if (isRelPositioned())
    556                 xPos += relativePositionOffsetX();
    557             RenderObject* curr = parent();
    558             while (curr && curr != offsetPar) {
     556                referencePoint.move(relativePositionOffset());
     557            const RenderObject* curr = parent();
     558            while (curr != offsetParent) {
    559559                // FIXME: What are we supposed to do inside SVG content?
    560560                if (curr->isBox() && !curr->isTableRow())
    561                     xPos += toRenderBox(curr)->left();
     561                    referencePoint.moveBy(toRenderBox(curr)->topLeftLocation());
     562                referencePoint.move(curr->parent()->offsetForColumns(referencePoint));
    562563                curr = curr->parent();
    563564            }
    564             if (offsetPar->isBox() && offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
    565                 xPos += toRenderBox(offsetPar)->left();
    566         }
    567     }
    568 
    569     return xPos;
     565            if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent->isRelPositioned() && !offsetParent->isPositioned())
     566                referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation());
     567        }
     568    }
     569
     570    return referencePoint;
     571}
     572
     573LayoutUnit RenderBoxModelObject::offsetLeft() const
     574{
     575    // Note that RenderInline and RenderBox override this to pass a different
     576    // startPoint to offsetTopLeft.
     577    return offsetTopLeft(LayoutPoint()).x();
    570578}
    571579
    572580LayoutUnit RenderBoxModelObject::offsetTop() const
    573581{
    574     // If the element is the HTML body element or does not have an associated box
    575     // return 0 and stop this algorithm.
    576     if (isBody())
    577         return ZERO_LAYOUT_UNIT;
    578    
    579     RenderBoxModelObject* offsetPar = offsetParent();
    580     LayoutUnit yPos = (isBox() ? toRenderBox(this)->top() : ZERO_LAYOUT_UNIT);
    581    
    582     // If the offsetParent of the element is null, or is the HTML body element,
    583     // return the distance between the canvas origin and the top border edge
    584     // of the element and stop this algorithm.
    585     if (offsetPar) {
    586         if (offsetPar->isBox() && !offsetPar->isBody())
    587             yPos -= toRenderBox(offsetPar)->borderTop();
    588         if (!isPositioned()) {
    589             if (isRelPositioned())
    590                 yPos += relativePositionOffsetY();
    591             RenderObject* curr = parent();
    592             while (curr && curr != offsetPar) {
    593                 // FIXME: What are we supposed to do inside SVG content?
    594                 if (curr->isBox() && !curr->isTableRow())
    595                     yPos += toRenderBox(curr)->top();
    596                 curr = curr->parent();
    597             }
    598             if (offsetPar->isBox() && offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
    599                 yPos += toRenderBox(offsetPar)->top();
    600         }
    601     }
    602     return yPos;
     582    // Note that RenderInline and RenderBox override this to pass a different
     583    // startPoint to offsetTopLeft.
     584    return offsetTopLeft(LayoutPoint()).y();
    603585}
    604586
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.h

    r115846 r116446  
    228228    };
    229229
     230    LayoutPoint offsetTopLeft(const LayoutPoint&) const;
     231
    230232    void calculateBackgroundImageGeometry(const FillLayer*, const LayoutRect& paintRect, BackgroundImageGeometry&);
    231233    void getBorderEdgeInfo(class BorderEdge[], const RenderStyle*, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
  • trunk/Source/WebCore/rendering/RenderInline.cpp

    r116174 r116446  
    679679LayoutUnit RenderInline::offsetLeft() const
    680680{
    681     LayoutUnit x = RenderBoxModelObject::offsetLeft();
     681    LayoutPoint topLeft;
    682682    if (InlineBox* firstBox = firstLineBoxIncludingCulling())
    683         x += firstBox->x();
    684     return x;
     683        topLeft = flooredLayoutPoint(firstBox->topLeft());
     684    return offsetTopLeft(topLeft).x();
    685685}
    686686
    687687LayoutUnit RenderInline::offsetTop() const
    688688{
    689     LayoutUnit y = RenderBoxModelObject::offsetTop();
     689    LayoutPoint topLeft;
    690690    if (InlineBox* firstBox = firstLineBoxIncludingCulling())
    691         y += firstBox->y();
    692     return y;
     691        topLeft = flooredLayoutPoint(firstBox->topLeft());
     692    return offsetTopLeft(topLeft).y();
    693693}
    694694
  • trunk/Source/WebCore/rendering/RenderObject.h

    r116373 r116446  
    766766    // offset to the given size.
    767767    virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const { }
     768    LayoutSize offsetForColumns(const LayoutPoint& point) const
     769    {
     770        LayoutSize offset;
     771        adjustForColumns(offset, point);
     772        return offset;
     773    }
    768774
    769775    virtual unsigned int length() const { return 1; }
Note: See TracChangeset for help on using the changeset viewer.