Changeset 177035 in webkit


Ignore:
Timestamp:
Dec 9, 2014 1:03:54 PM (9 years ago)
Author:
mmaxfield@apple.com
Message:

Delete Node::boundingBox()
https://bugs.webkit.org/show_bug.cgi?id=139333

Source/WebCore:

Conceptually, boundingBox() should be on RenderInline. In addition,
Node::boundingBox() is completely broken for inline elements: it
makes a rect from the top left of the first inline child to the
bottom right of the last inline child, disregarding the intermediate
inline children. This breaks with vertical text and with line
breaks.

What makes this problem worse is that some functions actually rely
on this bad behavior. These functions are functions that use the
Node's so-called "bounding box" to scroll to an anchor tag.

This patch goes through all the call sites of Node::boundingBox(),
and segregates them into calls that expect the true bounding box
and calls that need this false bounding box. This patch then moves
this false bounding box into RenderElement, using the name
anchorRect(). Callers what want the correct bounding box have been
updated to use RenderElement::absoluteBoundingBoxRect().

Reviewed by Zalan Bujtas.

No new tests because there should be no behavior change.

  • accessibility/AccessibilitySlider.cpp:

(WebCore::AccessibilitySliderThumb::elementRect): Use
RenderObject::absoluteBoundingBoxRect()

  • dom/ContainerNode.cpp:

(WebCore::ContainerNode::getUpperLeftCorner): Deleted.
(WebCore::ContainerNode::getLowerRightCorner): Deleted.
(WebCore::ContainerNode::boundingBox): Deleted.

  • dom/ContainerNode.h:
  • dom/Element.cpp:

(WebCore::Element::scrollIntoView): Use RenderElement::anchorRect().
(WebCore::Element::scrollIntoViewIfNeeded): Ditto.
(WebCore::Element::updateFocusAppearance): Ditto.

  • dom/Node.cpp:

(WebCore::Node::boundingBox): Deleted.

  • dom/Node.h:

(WebCore::Node::pixelSnappedBoundingBox): Deleted.

  • html/ColorInputType.cpp:

(WebCore::ColorInputType::elementRectRelativeToRootView): Use
RenderObject::absoluteBoundingBoxRect()

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::setupDateTimeChooserParameters): Ditto.

  • html/ValidationMessage.cpp:

(WebCore::ValidationMessage::buildBubbleTree): Ditto.

  • page/FrameView.cpp:

(WebCore::FrameView::scrollElementToRect): Use
RenderElement::anchorRect().
(WebCore::FrameView::scrollToAnchor): Ditto.

  • page/SpatialNavigation.cpp:

(WebCore::nodeRectInAbsoluteCoordinates): Use
RenderObject::absoluteBoundingBoxRect()

  • rendering/RenderElement.cpp:

(WebCore::RenderElement::getUpperLeftCorner): Moved from ContainerNode.
(WebCore::RenderElement::getLowerRightCorner): Moved from
ContainerNode.
(WebCore::RenderElement::anchorRect): Moved from ContainerNode.

  • rendering/RenderObject.h:
  • rendering/RenderText.cpp:

(WebCore::RenderText::topOfFirstText): Helper for
RenderElement::anchorRect()

  • rendering/RenderText.h:

Source/WebKit/mac:

Reviewed by Zalan Bujtas.

  • WebView/WebActionMenuController.mm:

(elementBoundingBoxInWindowCoordinatesFromNode): Use
RenderObject::absoluteBoundingBoxRect().

Source/WebKit2:

Reviewed by Zalan Bujtas.

  • Shared/WebHitTestResult.cpp:

(WebKit::WebHitTestResult::Data::elementBoundingBoxInWindowCoordinates):
Use RenderObject::absoluteBoundingBoxRect().

  • WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp:

(WebKit::WebPage::findZoomableAreaForPoint): Use
RenderObject::absoluteBoundingBoxRect().

Location:
trunk
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/fast/spatial-navigation/snav-container-white-space-expected.txt

    r72880 r177035  
    11This is an element
    22 
     3
    34This is an element
    45This is an element
  • trunk/LayoutTests/fast/spatial-navigation/snav-container-white-space.html

    r155272 r177035  
    7373      </a>
    7474    </div>
    75 
     75    <br/>
    7676    <div>
    7777      <a href="#" id="2">This is an element</a><br>
  • trunk/LayoutTests/fast/spatial-navigation/snav-imagemap-overlapped-areas-expected.txt

    r73452 r177035  
    1  
     1  
    22
    33
  • trunk/LayoutTests/fast/spatial-navigation/snav-imagemap-overlapped-areas.html

    r155272 r177035  
    5858
    5959    <a id="start" href="a"><img src="resources/green.png" width=50px height=50px></a>
     60    <br>
    6061    <div>
    6162      <img src="resources/green.png" width=200px height=200px usemap="#map">
  • trunk/Source/WebCore/ChangeLog

    r177031 r177035  
     12014-12-09  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        Delete Node::boundingBox()
     4        https://bugs.webkit.org/show_bug.cgi?id=139333
     5
     6        Conceptually, boundingBox() should be on RenderInline. In addition,
     7        Node::boundingBox() is completely broken for inline elements: it
     8        makes a rect from the top left of the first inline child to the
     9        bottom right of the last inline child, disregarding the intermediate
     10        inline children. This breaks with vertical text and with line
     11        breaks.
     12
     13        What makes this problem worse is that some functions actually rely
     14        on this bad behavior. These functions are functions that use the
     15        Node's so-called "bounding box" to scroll to an anchor tag.
     16
     17        This patch goes through all the call sites of Node::boundingBox(),
     18        and segregates them into calls that expect the true bounding box
     19        and calls that need this false bounding box. This patch then moves
     20        this false bounding box into RenderElement, using the name
     21        anchorRect(). Callers what want the correct bounding box have been
     22        updated to use RenderElement::absoluteBoundingBoxRect().
     23
     24        Reviewed by Zalan Bujtas.
     25
     26        No new tests because there should be no behavior change.
     27
     28        * accessibility/AccessibilitySlider.cpp:
     29        (WebCore::AccessibilitySliderThumb::elementRect): Use
     30        RenderObject::absoluteBoundingBoxRect()
     31        * dom/ContainerNode.cpp:
     32        (WebCore::ContainerNode::getUpperLeftCorner): Deleted.
     33        (WebCore::ContainerNode::getLowerRightCorner): Deleted.
     34        (WebCore::ContainerNode::boundingBox): Deleted.
     35        * dom/ContainerNode.h:
     36        * dom/Element.cpp:
     37        (WebCore::Element::scrollIntoView): Use RenderElement::anchorRect().
     38        (WebCore::Element::scrollIntoViewIfNeeded): Ditto.
     39        (WebCore::Element::updateFocusAppearance): Ditto.
     40        * dom/Node.cpp:
     41        (WebCore::Node::boundingBox): Deleted.
     42        * dom/Node.h:
     43        (WebCore::Node::pixelSnappedBoundingBox): Deleted.
     44        * html/ColorInputType.cpp:
     45        (WebCore::ColorInputType::elementRectRelativeToRootView): Use
     46        RenderObject::absoluteBoundingBoxRect()
     47        * html/HTMLInputElement.cpp:
     48        (WebCore::HTMLInputElement::setupDateTimeChooserParameters): Ditto.
     49        * html/ValidationMessage.cpp:
     50        (WebCore::ValidationMessage::buildBubbleTree): Ditto.
     51        * page/FrameView.cpp:
     52        (WebCore::FrameView::scrollElementToRect): Use
     53        RenderElement::anchorRect().
     54        (WebCore::FrameView::scrollToAnchor): Ditto.
     55        * page/SpatialNavigation.cpp:
     56        (WebCore::nodeRectInAbsoluteCoordinates): Use
     57        RenderObject::absoluteBoundingBoxRect()
     58        * rendering/RenderElement.cpp:
     59        (WebCore::RenderElement::getUpperLeftCorner): Moved from ContainerNode.
     60        (WebCore::RenderElement::getLowerRightCorner): Moved from
     61        ContainerNode.
     62        (WebCore::RenderElement::anchorRect): Moved from ContainerNode.
     63        * rendering/RenderObject.h:
     64        * rendering/RenderText.cpp:
     65        (WebCore::RenderText::topOfFirstText): Helper for
     66        RenderElement::anchorRect()
     67        * rendering/RenderText.h:
     68
    1692014-12-09  Antti Koivisto  <antti@apple.com>
    270
  • trunk/Source/WebCore/WebCore.exp.in

    r177012 r177035  
    23212321__ZN7WebCore19TextIndicatorWindowD1Ev
    23222322__ZN7WebCore19applicationIsSafariEv
     2323__ZN7WebCore19rendererBoundingBoxERKNS_4NodeE
    23232324__ZN7WebCore20PlatformEventFactory24createPlatformMouseEventEP7NSEventP6NSView
    23242325__ZN7WebCore20PlatformEventFactory27createPlatformKeyboardEventEP7NSEvent
  • trunk/Source/WebCore/accessibility/AccessibilitySlider.cpp

    r174898 r177035  
    160160    if (!sliderRenderer || !sliderRenderer->isSlider())
    161161        return LayoutRect();
    162     return downcast<HTMLInputElement>(sliderRenderer->node())->sliderThumbElement()->boundingBox();
     162    return rendererBoundingBox(*downcast<HTMLInputElement>(sliderRenderer->node())->sliderThumbElement());
    163163}
    164164
  • trunk/Source/WebCore/dom/ContainerNode.cpp

    r176502 r177035  
    778778}
    779779
    780 bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
    781 {
    782     if (!renderer())
    783         return false;
    784     // What is this code really trying to do?
    785     RenderObject* o = renderer();
    786     if (!o->isInline() || o->isReplaced()) {
    787         point = o->localToAbsolute(FloatPoint(), UseTransforms);
    788         return true;
    789     }
    790 
    791     // find the next text/image child, to get a position
    792     while (o) {
    793         RenderObject* p = o;
    794         if (RenderObject* child = o->firstChildSlow())
    795             o = child;
    796         else if (o->nextSibling())
    797             o = o->nextSibling();
    798         else {
    799             RenderObject* next = 0;
    800             while (!next && o->parent()) {
    801                 o = o->parent();
    802                 next = o->nextSibling();
    803             }
    804             o = next;
    805 
    806             if (!o)
    807                 break;
    808         }
    809         ASSERT(o);
    810 
    811         if (!o->isInline() || o->isReplaced()) {
    812             point = o->localToAbsolute(FloatPoint(), UseTransforms);
    813             return true;
    814         }
    815 
    816         if (p->node() && p->node() == this && is<RenderText>(*o) && !downcast<RenderText>(*o).firstTextBox()) {
    817             // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
    818         } else if (is<RenderText>(*o) || o->isReplaced()) {
    819             point = FloatPoint();
    820             if (is<RenderText>(*o) && downcast<RenderText>(*o).firstTextBox())
    821                 point.move(downcast<RenderText>(*o).linesBoundingBox().x(), downcast<RenderText>(*o).firstTextBox()->root().lineTop());
    822             else if (is<RenderBox>(*o))
    823                 point.moveBy(downcast<RenderBox>(*o).location());
    824             point = o->container()->localToAbsolute(point, UseTransforms);
    825             return true;
    826         }
    827     }
    828    
    829     // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
    830     // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
    831     if (!o && document().view()) {
    832         point = FloatPoint(0, document().view()->contentsHeight());
    833         return true;
    834     }
    835     return false;
    836 }
    837 
    838 bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
    839 {
    840     if (!renderer())
    841         return false;
    842 
    843     RenderObject* o = renderer();
    844     if (!o->isInline() || o->isReplaced()) {
    845         point = o->localToAbsolute(LayoutPoint(downcast<RenderBox>(*o).size()), UseTransforms);
    846         return true;
    847     }
    848 
    849     // find the last text/image child, to get a position
    850     while (o) {
    851         if (RenderObject* child = o->lastChildSlow())
    852             o = child;
    853         else if (o->previousSibling())
    854             o = o->previousSibling();
    855         else {
    856             RenderObject* prev = 0;
    857             while (!prev) {
    858                 o = o->parent();
    859                 if (!o)
    860                     return false;
    861                 prev = o->previousSibling();
    862             }
    863             o = prev;
    864         }
    865         ASSERT(o);
    866         if (is<RenderText>(*o) || o->isReplaced()) {
    867             point = FloatPoint();
    868             if (is<RenderText>(*o)) {
    869                 IntRect linesBox = downcast<RenderText>(*o).linesBoundingBox();
    870                 if (!linesBox.maxX() && !linesBox.maxY())
    871                     continue;
    872                 point.moveBy(linesBox.maxXMaxYCorner());
    873             } else
    874                 point.moveBy(downcast<RenderBox>(*o).frameRect().maxXMaxYCorner());
    875             point = o->container()->localToAbsolute(point, UseTransforms);
    876             return true;
    877         }
    878     }
    879     return true;
    880 }
    881 
    882 LayoutRect ContainerNode::boundingBox() const
    883 {
    884     FloatPoint upperLeft, lowerRight;
    885     bool foundUpperLeft = getUpperLeftCorner(upperLeft);
    886     bool foundLowerRight = getLowerRightCorner(lowerRight);
    887    
    888     // If we've found one corner, but not the other,
    889     // then we should just return a point at the corner that we did find.
    890     if (foundUpperLeft != foundLowerRight) {
    891         if (foundUpperLeft)
    892             lowerRight = upperLeft;
    893         else
    894             upperLeft = lowerRight;
    895     }
    896 
    897     return enclosingLayoutRect(FloatRect(upperLeft, lowerRight.expandedTo(upperLeft) - upperLeft));
    898 }
    899 
    900780unsigned ContainerNode::countChildNodes() const
    901781{
     
    1031911}
    1032912
     913LayoutRect rendererAnchorRect(const ContainerNode& node)
     914{
     915    if (RenderElement* renderer = node.renderer())
     916        return renderer->anchorRect();
     917    return LayoutRect();
     918}
     919
    1033920} // namespace WebCore
  • trunk/Source/WebCore/dom/ContainerNode.h

    r176502 r177035  
    113113    void cloneChildNodes(ContainerNode* clone);
    114114
    115     virtual LayoutRect boundingBox() const override;
    116 
    117115    enum ChildChangeType { ElementInserted, ElementRemoved, TextInserted, TextRemoved, TextChanged, AllChildrenRemoved, NonContentsChildChanged };
    118116    enum ChildChangeSource { ChildChangeSourceParser, ChildChangeSourceAPI };
     
    158156    void insertBeforeCommon(Node& nextChild, Node& oldChild);
    159157
    160     bool getUpperLeftCorner(FloatPoint&) const;
    161     bool getLowerRightCorner(FloatPoint&) const;
    162 
    163158    void notifyChildInserted(Node& child, ChildChangeSource);
    164159    void notifyChildRemoved(Node& child, Node* previousSibling, Node* nextSibling, ChildChangeSource);
     
    310305};
    311306
     307LayoutRect rendererAnchorRect(const ContainerNode&);
     308
    312309} // namespace WebCore
    313310
  • trunk/Source/WebCore/dom/Element.cpp

    r176630 r177035  
    573573        return;
    574574
    575     LayoutRect bounds = boundingBox();
     575    LayoutRect bounds = renderer()->anchorRect();
    576576    // Align to the top / bottom and to the closest edge.
    577577    if (alignToTop)
     
    588588        return;
    589589
    590     LayoutRect bounds = boundingBox();
     590    LayoutRect bounds = renderer()->anchorRect();
    591591    if (centerIfNeeded)
    592592        renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
     
    19791979        }
    19801980    } else if (renderer() && !renderer()->isWidget())
    1981         renderer()->scrollRectToVisible(boundingBox());
     1981        renderer()->scrollRectToVisible(renderer()->anchorRect());
    19821982}
    19831983
  • trunk/Source/WebCore/dom/Node.cpp

    r176502 r177035  
    638638    return is<RenderBoxModelObject>(renderer) ? downcast<RenderBoxModelObject>(renderer) : nullptr;
    639639}
    640 
    641 LayoutRect Node::boundingBox() const
    642 {
    643     if (renderer())
    644         return renderer()->absoluteBoundingBoxRect();
    645     return LayoutRect();
    646 }
    647640   
    648641LayoutRect Node::renderRect(bool* isReplaced)
     
    22672260}
    22682261
     2262IntRect rendererBoundingBox(const Node& node)
     2263{
     2264    if (RenderObject* renderer = node.renderer())
     2265        return renderer->absoluteBoundingBoxRect();
     2266    return IntRect();
     2267}
     2268
    22692269} // namespace WebCore
    22702270
  • trunk/Source/WebCore/dom/Node.h

    r176502 r177035  
    378378    }
    379379
    380     virtual LayoutRect boundingBox() const;
    381     IntRect pixelSnappedBoundingBox() const { return snappedIntRect(boundingBox()); }
    382380    WEBCORE_EXPORT LayoutRect renderRect(bool* isReplaced);
    383381    IntRect pixelSnappedRenderRect(bool* isReplaced) { return snappedIntRect(renderRect(isReplaced)); }
     
    740738}
    741739
     740WEBCORE_EXPORT IntRect rendererBoundingBox(const Node&);
     741
    742742} // namespace WebCore
    743743
  • trunk/Source/WebCore/html/ColorInputType.cpp

    r174047 r177035  
    205205IntRect ColorInputType::elementRectRelativeToRootView() const
    206206{
    207     return element().document().view()->contentsToRootView(element().pixelSnappedBoundingBox());
     207    return element().document().view()->contentsToRootView(rendererBoundingBox(element()));
    208208}
    209209
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r176502 r177035  
    18781878    }
    18791879
    1880     parameters.anchorRectInRootView = document().view()->contentsToRootView(pixelSnappedBoundingBox());
     1880    parameters.anchorRectInRootView = document().view()->contentsToRootView(rendererBoundingBox(*this));
    18811881    parameters.currentValue = value();
    18821882    parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
  • trunk/Source/WebCore/html/ValidationMessage.cpp

    r176459 r177035  
    179179    shadowRoot.appendChild(m_bubble.get(), ASSERT_NO_EXCEPTION);
    180180    document.updateLayout();
    181     adjustBubblePosition(m_element->boundingBox(), m_bubble.get());
     181    adjustBubblePosition(rendererBoundingBox(*m_element), m_bubble.get());
    182182
    183183    RefPtr<HTMLDivElement> clipper = HTMLDivElement::create(document);
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r176958 r177035  
    11491149
    11501150    if (m_frame.view())
    1151         m_frame.view()->maintainScrollPositionAtAnchor(0);
     1151        m_frame.view()->maintainScrollPositionAtAnchor(nullptr);
    11521152    m_activityAssertion = nullptr;
    11531153}
  • trunk/Source/WebCore/page/FrameView.cpp

    r176899 r177035  
    19851985        return false;
    19861986
    1987     maintainScrollPositionAtAnchor(anchorElement ? static_cast<Node*>(anchorElement) : frame().document());
     1987    ContainerNode* scrollPositionAnchor = anchorElement;
     1988    if (!scrollPositionAnchor)
     1989        scrollPositionAnchor = frame().document();
     1990    maintainScrollPositionAtAnchor(scrollPositionAnchor);
    19881991   
    19891992    // If the anchor accepts keyboard focus, move focus there to aid users relying on keyboard navigation.
     
    19941997}
    19951998
    1996 void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
     1999void FrameView::maintainScrollPositionAtAnchor(ContainerNode* anchorNode)
    19972000{
    19982001    m_maintainScrollPositionAnchor = anchorNode;
     
    20152018    frame().document()->updateLayoutIgnorePendingStylesheets();
    20162019
    2017     LayoutRect bounds = element->boundingBox();
     2020    LayoutRect bounds = rendererAnchorRect(*element);
    20182021    int centeringOffsetX = (rect.width() - bounds.width()) / 2;
    20192022    int centeringOffsetY = (rect.height() - bounds.height()) / 2;
     
    27762779void FrameView::scrollToAnchor()
    27772780{
    2778     RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
     2781    RefPtr<ContainerNode> anchorNode = m_maintainScrollPositionAnchor;
    27792782    if (!anchorNode)
    27802783        return;
     
    27852788    LayoutRect rect;
    27862789    if (anchorNode != frame().document())
    2787         rect = anchorNode->boundingBox();
     2790        rect = rendererAnchorRect(*anchorNode.get());
    27882791
    27892792    // Scroll nested layers and frames to reveal the anchor.
  • trunk/Source/WebCore/page/FrameView.h

    r176798 r177035  
    2828#include "AdjustViewSizeOrNot.h"
    2929#include "Color.h"
     30#include "ContainerNode.h"
    3031#include "LayoutMilestones.h"
    3132#include "LayoutRect.h"
     
    389390    bool scrollToFragment(const URL&);
    390391    bool scrollToAnchor(const String&);
    391     void maintainScrollPositionAtAnchor(Node*);
     392    void maintainScrollPositionAtAnchor(ContainerNode*);
    392393    WEBCORE_EXPORT void scrollElementToRect(Element*, const IntRect&);
    393394
     
    716717    bool m_firstVisuallyNonEmptyLayoutCallbackPending;
    717718
    718     RefPtr<Node> m_maintainScrollPositionAnchor;
     719    RefPtr<ContainerNode> m_maintainScrollPositionAnchor;
    719720
    720721    // Renderer to hold our custom scroll corner.
  • trunk/Source/WebCore/page/SpatialNavigation.cpp

    r174840 r177035  
    502502}
    503503
     504// FIXME: This is completely broken. This should be deleted and callers should be calling ScrollView::contentsToWindow() instead.
    504505static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
    505506{
     
    522523    if (is<Document>(*node))
    523524        return frameRectInAbsoluteCoordinates(downcast<Document>(*node).frame());
    524     LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), node->boundingBox());
     525
     526    LayoutRect rect = rectToAbsoluteCoordinates(node->document().frame(), rendererBoundingBox(*node));
    525527
    526528    // For authors that use border instead of outline in their CSS, we compensate by ignoring the border when calculating
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r176974 r177035  
    15121512}
    15131513
    1514 }
     1514bool RenderElement::getLeadingCorner(FloatPoint& point) const
     1515{
     1516    if (!isInline() || isReplaced()) {
     1517        point = localToAbsolute(FloatPoint(), UseTransforms);
     1518        return true;
     1519    }
     1520
     1521    // find the next text/image child, to get a position
     1522    const RenderObject* o = this;
     1523    while (o) {
     1524        const RenderObject* p = o;
     1525        if (RenderObject* child = o->firstChildSlow())
     1526            o = child;
     1527        else if (o->nextSibling())
     1528            o = o->nextSibling();
     1529        else {
     1530            RenderObject* next = 0;
     1531            while (!next && o->parent()) {
     1532                o = o->parent();
     1533                next = o->nextSibling();
     1534            }
     1535            o = next;
     1536
     1537            if (!o)
     1538                break;
     1539        }
     1540        ASSERT(o);
     1541
     1542        if (!o->isInline() || o->isReplaced()) {
     1543            point = o->localToAbsolute(FloatPoint(), UseTransforms);
     1544            return true;
     1545        }
     1546
     1547        if (p->node() && p->node() == element() && is<RenderText>(*o) && !downcast<RenderText>(*o).firstTextBox()) {
     1548            // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
     1549        } else if (is<RenderText>(*o) || o->isReplaced()) {
     1550            point = FloatPoint();
     1551            if (is<RenderText>(*o) && downcast<RenderText>(*o).firstTextBox())
     1552                point.move(downcast<RenderText>(*o).linesBoundingBox().x(), downcast<RenderText>(*o).topOfFirstText());
     1553            else if (is<RenderBox>(*o))
     1554                point.moveBy(downcast<RenderBox>(*o).location());
     1555            point = o->container()->localToAbsolute(point, UseTransforms);
     1556            return true;
     1557        }
     1558    }
     1559   
     1560    // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be
     1561    // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling?
     1562    if (!o && document().view()) {
     1563        point = FloatPoint(0, document().view()->contentsHeight());
     1564        return true;
     1565    }
     1566    return false;
     1567}
     1568
     1569bool RenderElement::getTrailingCorner(FloatPoint& point) const
     1570{
     1571    if (!isInline() || isReplaced()) {
     1572        point = localToAbsolute(LayoutPoint(downcast<RenderBox>(*this).size()), UseTransforms);
     1573        return true;
     1574    }
     1575
     1576    // find the last text/image child, to get a position
     1577    const RenderObject* o = this;
     1578    while (o) {
     1579        if (RenderObject* child = o->lastChildSlow())
     1580            o = child;
     1581        else if (o->previousSibling())
     1582            o = o->previousSibling();
     1583        else {
     1584            RenderObject* prev = 0;
     1585            while (!prev) {
     1586                o = o->parent();
     1587                if (!o)
     1588                    return false;
     1589                prev = o->previousSibling();
     1590            }
     1591            o = prev;
     1592        }
     1593        ASSERT(o);
     1594        if (is<RenderText>(*o) || o->isReplaced()) {
     1595            point = FloatPoint();
     1596            if (is<RenderText>(*o)) {
     1597                IntRect linesBox = downcast<RenderText>(*o).linesBoundingBox();
     1598                if (!linesBox.maxX() && !linesBox.maxY())
     1599                    continue;
     1600                point.moveBy(linesBox.maxXMaxYCorner());
     1601            } else
     1602                point.moveBy(downcast<RenderBox>(*o).frameRect().maxXMaxYCorner());
     1603            point = o->container()->localToAbsolute(point, UseTransforms);
     1604            return true;
     1605        }
     1606    }
     1607    return true;
     1608}
     1609
     1610LayoutRect RenderElement::anchorRect() const
     1611{
     1612    FloatPoint leading, trailing;
     1613    bool foundLeading = getLeadingCorner(leading);
     1614    bool foundTrailing = getTrailingCorner(trailing);
     1615   
     1616    // If we've found one corner, but not the other,
     1617    // then we should just return a point at the corner that we did find.
     1618    if (foundLeading != foundTrailing) {
     1619        if (foundLeading)
     1620            foundTrailing = foundLeading;
     1621        else
     1622            foundLeading = foundTrailing;
     1623    }
     1624
     1625    FloatPoint upperLeft = leading;
     1626    FloatPoint lowerRight = trailing;
     1627
     1628    // Vertical writing modes might mean the leading point is not in the top left
     1629    if (!isInline() || isReplaced()) {
     1630        upperLeft = FloatPoint(std::min(leading.x(), trailing.x()), std::min(leading.y(), trailing.y()));
     1631        lowerRight = FloatPoint(std::max(leading.x(), trailing.x()), std::max(leading.y(), trailing.y()));
     1632    } // Otherwise, it's not obvious what to do.
     1633
     1634    return enclosingLayoutRect(FloatRect(upperLeft, lowerRight.expandedTo(upperLeft) - upperLeft));
     1635}
     1636
     1637}
  • trunk/Source/WebCore/rendering/RenderElement.h

    r176478 r177035  
    151151    bool hasHiddenBackface() const { return style().backfaceVisibility() == BackfaceVisibilityHidden; }
    152152
     153    // anchorRect() is conceptually similar to absoluteBoundingBoxRect(), but is intended for scrolling to an anchor.
     154    // It works differently than absoluteBoundingBoxRect() for inline renderers.
     155    LayoutRect anchorRect() const;
     156
    153157    bool hasFilter() const { return style().hasFilter(); }
    154158    bool hasBackdropFilter() const
     
    262266    virtual void newImageAnimationFrameAvailable(CachedImage&) final override;
    263267
     268    bool getLeadingCorner(FloatPoint& output) const;
     269    bool getTrailingCorner(FloatPoint& output) const;
     270
    264271    unsigned m_baseTypeFlags : 6;
    265272    unsigned m_ancestorLineBoxDirty : 1;
  • trunk/Source/WebCore/rendering/RenderText.cpp

    r176790 r177035  
    10071007}
    10081008
     1009LayoutUnit RenderText::topOfFirstText() const
     1010{
     1011    return firstTextBox()->root().lineTop();
     1012}
     1013
    10091014void applyTextTransform(const RenderStyle& style, String& text, UChar previousCharacter)
    10101015{
  • trunk/Source/WebCore/rendering/RenderText.h

    r176473 r177035  
    164164
    165165    StringView stringView(int start = 0, int stop = -1) const;
     166
     167    LayoutUnit topOfFirstText() const;
    166168
    167169protected:
  • trunk/Source/WebKit/mac/ChangeLog

    r177011 r177035  
     12014-12-09  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        Delete Node::boundingBox()
     4        https://bugs.webkit.org/show_bug.cgi?id=139333
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        * WebView/WebActionMenuController.mm:
     9        (elementBoundingBoxInWindowCoordinatesFromNode): Use
     10        RenderObject::absoluteBoundingBoxRect().
     11
    1122014-12-08  Alexey Proskuryakov  <ap@apple.com>
    213
  • trunk/Source/WebKit/mac/WebView/WebActionMenuController.mm

    r176999 r177035  
    263263        return IntRect();
    264264
    265     return view->contentsToWindow(node->pixelSnappedBoundingBox());
     265    return view->contentsToWindow(rendererBoundingBox(*node));
    266266}
    267267
  • trunk/Source/WebKit2/ChangeLog

    r177033 r177035  
     12014-12-09  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        Delete Node::boundingBox()
     4        https://bugs.webkit.org/show_bug.cgi?id=139333
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        * Shared/WebHitTestResult.cpp:
     9        (WebKit::WebHitTestResult::Data::elementBoundingBoxInWindowCoordinates):
     10        Use RenderObject::absoluteBoundingBoxRect().
     11        * WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp:
     12        (WebKit::WebPage::findZoomableAreaForPoint): Use
     13        RenderObject::absoluteBoundingBoxRect().
     14
    1152014-12-09  Chris Dumez  <cdumez@apple.com>
    216
  • trunk/Source/WebKit2/Shared/WebHitTestResult.cpp

    r176999 r177035  
    2626#include <WebCore/FrameView.h>
    2727#include <WebCore/HitTestResult.h>
     28#include <WebCore/RenderObject.h>
    2829#include <WebCore/URL.h>
    2930#include <WebCore/Node.h>
     
    118119        return IntRect();
    119120
    120     return view->contentsToWindow(node->pixelSnappedBoundingBox());
     121    return view->contentsToWindow(rendererBoundingBox(*node));
    121122}
    122123
  • trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp

    r173606 r177035  
    3838#include <WebCore/Frame.h>
    3939#include <WebCore/FrameView.h>
     40#include <WebCore/RenderObject.h>
    4041#include <WebCore/ScrollView.h>
    4142
     
    5556        return;
    5657
    57     IntRect zoomableArea = node->pixelSnappedBoundingBox();
     58    IntRect zoomableArea = rendererBoundingBox(*node);
    5859
    5960    while (true) {
     
    7172
    7273        node = node->parentNode();
    73         zoomableArea.unite(node->pixelSnappedBoundingBox());
     74        zoomableArea.unite(rendererBoundingBox(*node));
    7475    }
    7576
Note: See TracChangeset for help on using the changeset viewer.