Changeset 187593 in webkit


Ignore:
Timestamp:
Jul 30, 2015 11:32:45 AM (9 years ago)
Author:
Simon Fraser
Message:

Selecting in an iframe can cause main page scrolling
https://bugs.webkit.org/show_bug.cgi?id=147431
rdar://problem/19244589

Reviewed by Zalan Bujtas.

Source/WebCore:

The RenderLayer auatoscroll code walks up the RenderLayer hierarchy, crossing
frame boundaries. However, as it crosses into an ancestor frame it failed to
map the target rect into the coordinate space of the new frame, which caused
us to scroll to an incorrect location in that parent frame.

Test: fast/events/autoscroll-in-iframe.html

  • rendering/RenderLayer.cpp:

(WebCore::parentLayerCrossFrame): Make the layer a reference, and pass in
an optional rect. When crossing frame boundaries, map the rect from the
contents of the child frame to the contents of the parent frame.
(WebCore::RenderLayer::enclosingScrollableLayer): Pass optional rect.
(WebCore::RenderLayer::scrollRectToVisible):
(WebCore::RenderLayer::hasScrollableOrRubberbandableAncestor):

  • rendering/RenderLayer.h:

LayoutTests:

Test that uses eventSender to select in an iframe after scrolling the
main page.

  • fast/events/autoscroll-in-iframe-expected.txt: Added.
  • fast/events/autoscroll-in-iframe.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r187589 r187593  
     12015-07-30  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Selecting in an iframe can cause main page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=147431
     5        rdar://problem/19244589
     6
     7        Reviewed by Zalan Bujtas.
     8       
     9        Test that uses eventSender to select in an iframe after scrolling the
     10        main page.
     11
     12        * fast/events/autoscroll-in-iframe-expected.txt: Added.
     13        * fast/events/autoscroll-in-iframe.html: Added.
     14
    1152015-07-29  Matt Rajca  <mrajca@apple.com>
    216
  • trunk/Source/WebCore/ChangeLog

    r187592 r187593  
     12015-07-30  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Selecting in an iframe can cause main page scrolling
     4        https://bugs.webkit.org/show_bug.cgi?id=147431
     5        rdar://problem/19244589
     6
     7        Reviewed by Zalan Bujtas.
     8       
     9        The RenderLayer auatoscroll code walks up the RenderLayer hierarchy, crossing
     10        frame boundaries. However, as it crosses into an ancestor frame it failed to
     11        map the target rect into the coordinate space of the new frame, which caused
     12        us to scroll to an incorrect location in that parent frame.
     13
     14        Test: fast/events/autoscroll-in-iframe.html
     15
     16        * rendering/RenderLayer.cpp:
     17        (WebCore::parentLayerCrossFrame): Make the layer a reference, and pass in
     18        an optional rect. When crossing frame boundaries, map the rect from the
     19        contents of the child frame to the contents of the parent frame.
     20        (WebCore::RenderLayer::enclosingScrollableLayer): Pass optional rect.
     21        (WebCore::RenderLayer::scrollRectToVisible):
     22        (WebCore::RenderLayer::hasScrollableOrRubberbandableAncestor):
     23        * rendering/RenderLayer.h:
     24
    1252015-07-30  Simon Fraser  <simon.fraser@apple.com>
    226
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r186956 r187593  
    14501450}
    14511451
    1452 static RenderLayer* parentLayerCrossFrame(const RenderLayer* layer)
    1453 {
    1454     ASSERT(layer);
    1455     if (layer->parent())
    1456         return layer->parent();
    1457 
    1458     HTMLFrameOwnerElement* ownerElement = layer->renderer().document().ownerElement();
     1452static RenderLayer* parentLayerCrossFrame(const RenderLayer& layer, LayoutRect* rect = nullptr)
     1453{
     1454    if (layer.parent())
     1455        return layer.parent();
     1456
     1457    HTMLFrameOwnerElement* ownerElement = layer.renderer().document().ownerElement();
    14591458    if (!ownerElement)
    14601459        return nullptr;
     
    14641463        return nullptr;
    14651464
     1465    // Convert the rect into the coordinate space of the parent frame's document.
     1466    if (rect) {
     1467        IntRect viewRect = layer.renderer().frame().view()->convertToContainingView(enclosingIntRect(*rect));
     1468        *rect = ownerRenderer->frame().view()->viewToContents(viewRect);
     1469    }
     1470
    14661471    return ownerRenderer->enclosingLayer();
    14671472}
    14681473
    1469 RenderLayer* RenderLayer::enclosingScrollableLayer() const
    1470 {
    1471     for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
     1474RenderLayer* RenderLayer::enclosingScrollableLayer(LayoutRect* rect) const
     1475{
     1476    for (RenderLayer* nextLayer = parentLayerCrossFrame(*this, rect); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer, rect)) {
    14721477        if (is<RenderBox>(nextLayer->renderer()) && downcast<RenderBox>(nextLayer->renderer()).canBeScrolledAndHasScrollableArea())
    14731478            return nextLayer;
     
    25322537   
    25332538    if (renderer().frame().eventHandler().autoscrollInProgress())
    2534         parentLayer = enclosingScrollableLayer();
     2539        parentLayer = enclosingScrollableLayer(&newRect);
    25352540
    25362541    if (parentLayer)
     
    31833188bool RenderLayer::hasScrollableOrRubberbandableAncestor()
    31843189{
    3185     for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
     3190    for (RenderLayer* nextLayer = parentLayerCrossFrame(*this); nextLayer; nextLayer = parentLayerCrossFrame(*nextLayer)) {
    31863191        if (nextLayer->isScrollableOrRubberbandable())
    31873192            return true;
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r186392 r187593  
    405405
    406406    // Returns the nearest enclosing layer that is scrollable.
    407     RenderLayer* enclosingScrollableLayer() const;
     407    RenderLayer* enclosingScrollableLayer(LayoutRect* = nullptr) const;
    408408
    409409    // The layer relative to which clipping rects for this layer are computed.
Note: See TracChangeset for help on using the changeset viewer.