Changeset 147395 in webkit


Ignore:
Timestamp:
Apr 1, 2013 11:49:24 PM (11 years ago)
Author:
esprehn@chromium.org
Message:

RenderObject::offsetParent should return Element*
https://bugs.webkit.org/show_bug.cgi?id=113739

Reviewed by Abhishek Arya.

The offsetParent of a node should always be an Element, ensure this
by fixing RenderObject::offsetParent to return an Element* and clean up
the method to match the algorithm in the spec which lets us remove the
comments that were trying to explain what was going on.

This also hardens against badness where RenderObject::offsetParent
could have returned a renderer with a non-Element node which would result
in a bad cast in Element::offsetParent. We fixed all cases of this, but
this patch makes sure such things never happen again.

No new tests, no change in behavior.

  • dom/Element.cpp:

(WebCore::Element::offsetParent):

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::offsetParent): Now returns Element*.

  • rendering/RenderObject.h:

(RenderObject):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r147392 r147395  
     12013-04-01  Elliott Sprehn  <esprehn@chromium.org>
     2
     3        RenderObject::offsetParent should return Element*
     4        https://bugs.webkit.org/show_bug.cgi?id=113739
     5
     6        Reviewed by Abhishek Arya.
     7
     8        The offsetParent of a node should always be an Element, ensure this
     9        by fixing RenderObject::offsetParent to return an Element* and clean up
     10        the method to match the algorithm in the spec which lets us remove the
     11        comments that were trying to explain what was going on.
     12
     13        This also hardens against badness where RenderObject::offsetParent
     14        could have returned a renderer with a non-Element node which would result
     15        in a bad cast in Element::offsetParent. We fixed all cases of this, but
     16        this patch makes sure such things never happen again.
     17
     18        No new tests, no change in behavior.
     19
     20        * dom/Element.cpp:
     21        (WebCore::Element::offsetParent):
     22        * rendering/RenderBoxModelObject.cpp:
     23        (WebCore::RenderBoxModelObject::adjustedPositionRelativeToOffsetParent):
     24        * rendering/RenderObject.cpp:
     25        (WebCore::RenderObject::offsetParent): Now returns Element*.
     26        * rendering/RenderObject.h:
     27        (RenderObject):
     28
    1292013-04-01  Alpha Lam  <hclam@chromium.org>
    230
  • trunk/Source/WebCore/dom/Element.cpp

    r147281 r147395  
    549549{
    550550    document()->updateLayoutIgnorePendingStylesheets();
    551     if (RenderObject* rend = renderer())
    552         if (RenderObject* offsetParent = rend->offsetParent())
    553             return toElement(offsetParent->node());
     551    if (RenderObject* renderer = this->renderer())
     552        return renderer->offsetParent();
    554553    return 0;
    555554}
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r147199 r147395  
    453453    // return the distance between the canvas origin and the left border edge
    454454    // of the element and stop this algorithm.
    455     if (const RenderBoxModelObject* offsetParent = this->offsetParent()) {
     455    Element* element = offsetParent();
     456    if (!element)
     457        return referencePoint;
     458
     459    if (const RenderBoxModelObject* offsetParent = element->renderBoxModelObject()) {
    456460        if (offsetParent->isBox() && !offsetParent->isBody())
    457461            referencePoint.move(-toRenderBox(offsetParent)->borderLeft(), -toRenderBox(offsetParent)->borderTop());
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r147303 r147395  
    30023002}
    30033003
    3004 RenderBoxModelObject* RenderObject::offsetParent() const
    3005 {
    3006     // If any of the following holds true return null and stop this algorithm:
    3007     // A is the root element.
    3008     // A is the HTML body element.
    3009     // The computed value of the position property for element A is fixed.
    3010     if (isRoot() || isBody() || (isOutOfFlowPositioned() && style()->position() == FixedPosition))
     3004Element* RenderObject::offsetParent() const
     3005{
     3006    if (isRoot() || isBody())
     3007        return 0;
     3008
     3009    if (isOutOfFlowPositioned() && style()->position() == FixedPosition)
    30113010        return 0;
    30123011
     
    30153014    // FIXME: Implement!
    30163015
    3017     // FIXME: Stop the search at the flow thread boundary until we figure out the right
    3018     // behavior for elements inside a flow thread.
     3016    // FIXME: Figure out the right behavior for elements inside a flow thread.
    30193017    // https://bugs.webkit.org/show_bug.cgi?id=113276
    3020    
    3021     // Return the nearest ancestor element of A for which at least one of the following is
    3022     // true and stop this algorithm if such an ancestor is found:
    3023     //     * The computed value of the position property is not static.
    3024     //     * It is the HTML body element.
    3025     //     * The computed value of the position property of A is static and the ancestor
    3026     //       is one of the following HTML elements: td, th, or table.
    3027     //     * Our own extension: if there is a difference in the effective zoom
    3028 
    3029     bool skipTables = isPositioned();
    3030     float currZoom = style()->effectiveZoom();
    3031     RenderObject* curr = parent();
    3032     while (curr && (!curr->node() || (!curr->isPositioned() && !curr->isBody())) && !curr->isRenderNamedFlowThread()) {
    3033         Node* element = curr->node();
    3034         if (!skipTables && element && (element->hasTagName(tableTag) || element->hasTagName(tdTag) || element->hasTagName(thTag)))
     3018
     3019    float effectiveZoom = style()->effectiveZoom();
     3020    Node* node = 0;
     3021    for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
     3022        node = ancestor->node();
     3023
     3024        // Spec: http://www.w3.org/TR/cssom-view/#offset-attributes
     3025
     3026        if (!node)
     3027            continue;
     3028
     3029        if (ancestor->isPositioned())
    30353030            break;
    30363031
    3037         float newZoom = curr->style()->effectiveZoom();
    3038         if (currZoom != newZoom)
     3032        if (node->hasTagName(HTMLNames::bodyTag))
    30393033            break;
    3040         currZoom = newZoom;
    3041         curr = curr->parent();
    3042     }
    3043     return curr && curr->isBoxModelObject() && !curr->isRenderNamedFlowThread() ? toRenderBoxModelObject(curr) : 0;
     3034
     3035        if (!isPositioned() && (node->hasTagName(tableTag) || node->hasTagName(tdTag) || node->hasTagName(thTag)))
     3036            break;
     3037
     3038        // Webkit specific extension where offsetParent stops at zoom level changes.
     3039        if (effectiveZoom != ancestor->style()->effectiveZoom())
     3040            break;
     3041    }
     3042
     3043    return node && node->isElementNode() ? toElement(node) : 0;
    30443044}
    30453045
  • trunk/Source/WebCore/rendering/RenderObject.h

    r146533 r147395  
    667667    virtual RenderObject* hoverAncestor() const { return parent(); }
    668668
    669     // IE Extension that can be called on any RenderObject.  See the implementation for the details.
    670     RenderBoxModelObject* offsetParent() const;
     669    Element* offsetParent() const;
    671670
    672671    void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0);
Note: See TracChangeset for help on using the changeset viewer.