Changeset 182215 in webkit


Ignore:
Timestamp:
Mar 31, 2015, 4:42:31 PM (10 years ago)
Author:
Simon Fraser
Message:

Make it possible to compute a region for elements on the page that have wheel event handlers
https://bugs.webkit.org/show_bug.cgi?id=142807

Reviewed by David Hyatt.

Source/WebCore:

Make it possible to compute a region that covers the elements on the page that have
a wheel event handler. This region may overestimate, but must not underestimate the area.

Elements with wheel handlers are registered on the document, and when a document gains
its first wheel handler, it registers the ownerElement in the parent document. Thus, on
the main frame, the region encompasses elements with handlers, and iframes whose subdocuments
have handlers.

Element gains some functions that allow it to return a rect which is the bounds of the element's
renderer, and renders for its descendant elements, which is the size or larger than the event
handling region for that element. Some configurations (e.g. position:fixed) require special
treatment.

Document::absoluteRegionForEventTargets() can then iterate over all elements in the given set,
and build a Region for those (short-circuiting if the document itself has a handler).

The new code is exercised for the debug MouseWheelRegionOverlay, and also added to the
non-fast scrollable region, used by threaded scrolling.

Tests: platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html

platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html
platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html

  • dom/ContainerNode.h:

(WebCore::ContainerNode::absoluteEventHandlerBounds): Base class implementation; returns empty rect.

  • dom/Document.cpp:

(WebCore::Document::prepareForDestruction): Unregister from the parent document.
(WebCore::Document::didAddWheelEventHandler): Add to the wheel handler set. Tell the parent
document if we are adding wheel handlers for the first time. Eventually the wheelEventHandlerCountChanged()
code will be removed, now we have the set. Tell debug overlays that we changed.
(WebCore::Document::didRemoveWheelEventHandler): Remove from the set, and unregister with the parent
document if necessary. Tell debug overlays that we changed.
(WebCore::Document::didAddTouchEventHandler): Minor cleanup.
(WebCore::Document::didRemoveTouchEventHandler): Ditto.
(WebCore::Document::didRemoveEventTargetNode): Remove from wheel targets.
(WebCore::Document::absoluteEventHandlerBounds): Implementation of the ContainerNode
function, just return the document bounds.
(WebCore::Document::absoluteRegionForEventTargets): Iterate over the given event targets,
and call absoluteEventHandlerBounds() on each.

  • dom/Document.h:

(WebCore::Document::wheelEventTargets):

  • dom/Element.cpp:

(WebCore::layoutOverflowRectContainsAllDescendants): Return true if we can determine that the
layoutOverflow bounds of the given renderer contains the renderers of all descendant elements.
(WebCore::Element::eventBounds): Get the "event handling" bounds of this element (excluding
descendants), and while doing so, compute whether any descendants are position:fixed, and whether
these bounds are known to include descendants.
(WebCore::Element::eventBoundsOfElementAndDescendants): Recursive function that short-circuits
if it can determine that descendants are enclosed by the bounds.
(WebCore::Element::absoluteEventHandlerBounds):

  • dom/Element.h:
  • page/DebugPageOverlays.cpp:

(WebCore::MouseWheelRegionOverlay::updateRegion): Ask the document for the region of wheel
event handlers.

  • page/scrolling/ScrollingCoordinator.cpp:

(WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Add the wheel handler region
to the non-fast scrollable region.

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::scrollTo): Overflow scrolling needs to dirty event regions.

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::absoluteBoundingBoxRect): Need to pass the "wasFixed" flag out
of this function.
(WebCore::RenderObject::localToAbsolute): Ditto.

  • rendering/RenderObject.h:

LayoutTests:

Tests that dump the non-fast-scrollable region, for various rendering configurations.

  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js: Added.

(rectsAsString):
(dumpRegion):

  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt: Added.
  • platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html: Added.
Location:
trunk
Files:
23 added
12 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/LayoutTests/ChangeLog

    r182201 r182215  
     12015-03-31  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make it possible to compute a region for elements on the page that have wheel event handlers
     4        https://bugs.webkit.org/show_bug.cgi?id=142807
     5
     6        Reviewed by David Hyatt.
     7       
     8        Tests that dump the non-fast-scrollable region, for various rendering configurations.
     9
     10        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes-expected.txt: Added.
     11        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html: Added.
     12        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/gain-wheel-handler.html: Added.
     13        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/lose-wheel-handler.html: Added.
     14        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/resources/wheel-handler-region-helper.js: Added.
     15        (rectsAsString):
     16        (dumpRegion):
     17        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child-expected.txt: Added.
     18        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html: Added.
     19        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html: Added.
     20        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html: Added.
     21        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed-expected.txt: Added.
     22        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html: Added.
     23        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document-expected.txt: Added.
     24        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html: Added.
     25        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed-expected.txt: Added.
     26        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html: Added.
     27        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic-expected.txt: Added.
     28        * platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html: Added.
     29
    1302015-03-31  Dean Jackson  <dino@apple.com>
    231
  • TabularUnified trunk/Source/WebCore/ChangeLog

    r182212 r182215  
     12015-03-31  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Make it possible to compute a region for elements on the page that have wheel event handlers
     4        https://bugs.webkit.org/show_bug.cgi?id=142807
     5
     6        Reviewed by David Hyatt.
     7       
     8        Make it possible to compute a region that covers the elements on the page that have
     9        a wheel event handler. This region may overestimate, but must not underestimate the area.
     10       
     11        Elements with wheel handlers are registered on the document, and when a document gains
     12        its first wheel handler, it registers the ownerElement in the parent document. Thus, on
     13        the main frame, the region encompasses elements with handlers, and iframes whose subdocuments
     14        have handlers.
     15       
     16        Element gains some functions that allow it to return a rect which is the bounds of the element's
     17        renderer, and renders for its descendant elements, which is the size or larger than the event
     18        handling region for that element. Some configurations (e.g. position:fixed) require special
     19        treatment.
     20       
     21        Document::absoluteRegionForEventTargets() can then iterate over all elements in the given set,
     22        and build a Region for those (short-circuiting if the document itself has a handler).
     23       
     24        The new code is exercised for the debug MouseWheelRegionOverlay, and also added to the
     25        non-fast scrollable region, used by threaded scrolling.
     26
     27        Tests: platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/handlers-in-iframes.html
     28               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-fixed-child.html
     29               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-columns.html
     30               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-in-region.html
     31               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-inside-fixed.html
     32               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-document.html
     33               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-on-fixed.html
     34               platform/mac-wk2/tiled-drawing/scrolling/non-fast-region/wheel-handler-region-basic.html
     35
     36        * dom/ContainerNode.h:
     37        (WebCore::ContainerNode::absoluteEventHandlerBounds): Base class implementation; returns empty rect.
     38        * dom/Document.cpp:
     39        (WebCore::Document::prepareForDestruction): Unregister from the parent document.
     40        (WebCore::Document::didAddWheelEventHandler): Add to the wheel handler set. Tell the parent
     41        document if we are adding wheel handlers for the first time. Eventually the wheelEventHandlerCountChanged()
     42        code will be removed, now we have the set. Tell debug overlays that we changed.
     43        (WebCore::Document::didRemoveWheelEventHandler): Remove from the set, and unregister with the parent
     44        document if necessary. Tell debug overlays that we changed.
     45        (WebCore::Document::didAddTouchEventHandler): Minor cleanup.
     46        (WebCore::Document::didRemoveTouchEventHandler): Ditto.
     47        (WebCore::Document::didRemoveEventTargetNode): Remove from wheel targets.
     48        (WebCore::Document::absoluteEventHandlerBounds): Implementation of the ContainerNode
     49        function, just return the document bounds.
     50        (WebCore::Document::absoluteRegionForEventTargets): Iterate over the given event targets,
     51        and call absoluteEventHandlerBounds() on each.
     52        * dom/Document.h:
     53        (WebCore::Document::wheelEventTargets):
     54        * dom/Element.cpp:
     55        (WebCore::layoutOverflowRectContainsAllDescendants): Return true if we can determine that the
     56        layoutOverflow bounds of the given renderer contains the renderers of all descendant elements.
     57        (WebCore::Element::eventBounds): Get the "event handling" bounds of this element (excluding
     58        descendants), and while doing so, compute whether any descendants are position:fixed, and whether
     59        these bounds are known to include descendants.
     60        (WebCore::Element::eventBoundsOfElementAndDescendants): Recursive function that short-circuits
     61        if it can determine that descendants are enclosed by the bounds.
     62        (WebCore::Element::absoluteEventHandlerBounds):
     63        * dom/Element.h:
     64        * page/DebugPageOverlays.cpp:
     65        (WebCore::MouseWheelRegionOverlay::updateRegion): Ask the document for the region of wheel
     66        event handlers.
     67        * page/scrolling/ScrollingCoordinator.cpp:
     68        (WebCore::ScrollingCoordinator::computeNonFastScrollableRegion): Add the wheel handler region
     69        to the non-fast scrollable region.
     70        * rendering/RenderLayer.cpp:
     71        (WebCore::RenderLayer::scrollTo): Overflow scrolling needs to dirty event regions.
     72        * rendering/RenderObject.cpp:
     73        (WebCore::RenderObject::absoluteBoundingBoxRect): Need to pass the "wasFixed" flag out
     74        of this function.
     75        (WebCore::RenderObject::localToAbsolute): Ditto.
     76        * rendering/RenderObject.h:
     77
    1782015-03-31  Alexey Proskuryakov  <ap@apple.com>
    279
  • TabularUnified trunk/Source/WebCore/dom/ContainerNode.h

    r179101 r182215  
    137137    RenderElement* renderer() const;
    138138
     139    // Return a bounding box in absolute coordinates enclosing this node and all its descendants.
     140    // This gives the area within which events may get handled by a hander registered on this node.
     141    virtual LayoutRect absoluteEventHandlerBounds(bool& /* includesFixedPositionElements */) { return LayoutRect(); }
     142
    139143    Element* querySelector(const String& selectors, ExceptionCode&);
    140144    RefPtr<NodeList> querySelectorAll(const String& selectors, ExceptionCode&);
  • TabularUnified trunk/Source/WebCore/dom/Document.cpp

    r182193 r182215  
    4848#include "DOMWindow.h"
    4949#include "DateComponents.h"
     50#include "DebugPageOverlays.h"
    5051#include "Dictionary.h"
    5152#include "DocumentLoader.h"
     
    22462247#endif
    22472248
     2249    if (m_wheelEventTargets && m_wheelEventTargets->size() && parentDocument())
     2250        parentDocument()->didRemoveEventTargetNode(*this);
     2251
    22482252    if (m_mediaQueryMatcher)
    22492253        m_mediaQueryMatcher->documentDestroyed();
     
    59996003}
    60006004
    6001 void Document::didAddWheelEventHandler(Node&)
     6005void Document::didAddWheelEventHandler(Node& node)
    60026006{
    60036007    ++m_wheelEventHandlerCount;
     6008
     6009    if (!m_wheelEventTargets)
     6010        m_wheelEventTargets = std::make_unique<EventTargetSet>();
     6011
     6012    m_wheelEventTargets->add(&node);
     6013
     6014    if (Document* parent = parentDocument()) {
     6015        parent->didAddWheelEventHandler(*this);
     6016        return;
     6017    }
     6018
    60046019    wheelEventHandlerCountChanged(this);
    6005 }
    6006 
    6007 void Document::didRemoveWheelEventHandler(Node&)
     6020
     6021    if (Frame* frame = this->frame())
     6022        DebugPageOverlays::didChangeEventHandlers(*frame);
     6023}
     6024
     6025void Document::didRemoveWheelEventHandler(Node& node)
    60086026{
    60096027    ASSERT(m_wheelEventHandlerCount > 0);
    60106028    --m_wheelEventHandlerCount;
     6029
     6030    if (!m_wheelEventTargets)
     6031        return;
     6032
     6033    ASSERT(m_wheelEventTargets->contains(&node));
     6034    m_wheelEventTargets->remove(&node);
     6035
     6036    if (Document* parent = parentDocument()) {
     6037        parent->didRemoveWheelEventHandler(*this);
     6038        return;
     6039    }
     6040
    60116041    wheelEventHandlerCountChanged(this);
     6042
     6043    if (Frame* frame = this->frame())
     6044        DebugPageOverlays::didChangeEventHandlers(*frame);
    60126045}
    60136046
     
    60156048{
    60166049#if ENABLE(TOUCH_EVENTS)
    6017     if (!m_touchEventTargets.get())
     6050    if (!m_touchEventTargets)
    60186051        m_touchEventTargets = std::make_unique<EventTargetSet>();
     6052
    60196053    m_touchEventTargets->add(&handler);
     6054
    60206055    if (Document* parent = parentDocument()) {
    60216056        parent->didAddTouchEventHandler(*this);
    60226057        return;
    60236058    }
     6059
    60246060    if (Page* page = this->page()) {
    60256061        if (m_touchEventTargets->size() == 1)
     
    60346070{
    60356071#if ENABLE(TOUCH_EVENTS)
    6036     if (!m_touchEventTargets.get())
    6037         return;
     6072    if (!m_touchEventTargets)
     6073        return;
     6074
    60386075    ASSERT(m_touchEventTargets->contains(&handler));
    60396076    m_touchEventTargets->remove(&handler);
     6077
    60406078    if (Document* parent = parentDocument()) {
    60416079        parent->didRemoveTouchEventHandler(*this);
     
    60486086    if (m_touchEventTargets->size())
    60496087        return;
     6088
     6089    // FIXME: why can't we trust m_touchEventTargets?
    60506090    for (const Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    60516091        if (frame->document() && frame->document()->hasTouchEventHandlers())
     
    60666106            parentDocument()->didRemoveEventTargetNode(*this);
    60676107    }
    6068 #else
    6069     UNUSED_PARAM(handler);
    6070 #endif
     6108#endif
     6109
     6110    if (m_wheelEventTargets) {
     6111        m_wheelEventTargets->removeAll(&handler);
     6112        if ((&handler == this || m_wheelEventTargets->isEmpty()) && parentDocument())
     6113            parentDocument()->didRemoveEventTargetNode(*this);
     6114    }
     6115}
     6116
     6117LayoutRect Document::absoluteEventHandlerBounds(bool& includesFixedPositionElements)
     6118{
     6119    includesFixedPositionElements = false;
     6120    if (RenderView* renderView = this->renderView())
     6121        return renderView->documentRect();
     6122   
     6123    return LayoutRect();
     6124}
     6125
     6126Region Document::absoluteRegionForEventTargets(const EventTargetSet* targets)
     6127{
     6128    if (!targets)
     6129        return Region();
     6130
     6131    Region targetRegion;
     6132    bool insideFixedPosition = false;
     6133
     6134    for (auto it : *targets) {
     6135        LayoutRect rootRelativeBounds;
     6136       
     6137        if (is<Document>(it.key)) {
     6138            Document* document = downcast<Document>(it.key);
     6139            if (document == this)
     6140                rootRelativeBounds = absoluteEventHandlerBounds(insideFixedPosition);
     6141            else if (Element* element = document->ownerElement())
     6142                rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition);
     6143        } else if (is<Element>(it.key)) {
     6144            Element* element = downcast<Element>(it.key);
     6145            rootRelativeBounds = element->absoluteEventHandlerBounds(insideFixedPosition);
     6146        }
     6147       
     6148        if (!rootRelativeBounds.isEmpty())
     6149            targetRegion.unite(Region(enclosingIntRect(rootRelativeBounds)));
     6150    }
     6151
     6152    return targetRegion;
    60716153}
    60726154
  • TabularUnified trunk/Source/WebCore/dom/Document.h

    r182022 r182215  
    4242#include "PlatformScreen.h"
    4343#include "ReferrerPolicy.h"
     44#include "Region.h"
    4445#include "RenderPtr.h"
    4546#include "ScriptExecutionContext.h"
     
    11491150    }
    11501151
     1152    const EventTargetSet* wheelEventTargets() const { return m_wheelEventTargets.get(); }
     1153
     1154    Region absoluteRegionForEventTargets(const EventTargetSet*);
     1155
     1156    LayoutRect absoluteEventHandlerBounds(bool&) override final;
     1157
    11511158    bool visualUpdatesAllowed() const { return m_visualUpdatesAllowed; }
    11521159
     
    15621569    std::unique_ptr<EventTargetSet> m_touchEventTargets;
    15631570#endif
     1571    std::unique_ptr<EventTargetSet> m_wheelEventTargets;
    15641572
    15651573    double m_lastHandledUserGestureTimestamp;
  • TabularUnified trunk/Source/WebCore/dom/Element.cpp

    r182191 r182215  
    6464#include "PlatformWheelEvent.h"
    6565#include "PointerLockController.h"
     66#include "RenderFlowThread.h"
    6667#include "RenderLayer.h"
    6768#include "RenderNamedFlowFragment.h"
     
    926927}
    927928
     929static bool layoutOverflowRectContainsAllDescendants(const RenderElement& renderer)
     930{
     931    if (renderer.isRenderView())
     932        return true;
     933
     934    if (!renderer.element())
     935        return false;
     936
     937    // If there are any position:fixed inside of us, game over.
     938    if (auto viewPositionedObjects = renderer.view().positionedObjects()) {
     939        for (RenderBox* it : *viewPositionedObjects) {
     940            if (it != &renderer && it->style().position() == FixedPosition && renderer.element()->contains(it->element()))
     941                return false;
     942        }
     943    }
     944
     945    if (renderer.canContainAbsolutelyPositionedObjects()) {
     946        // Our layout overflow will include all descendant positioned elements.
     947        return true;
     948    }
     949
     950    // This renderer may have positioned descendants whose containing block is some ancestor.
     951    if (auto containingBlock = renderer.containingBlockForAbsolutePosition()) {
     952        if (auto positionedObjects = containingBlock->positionedObjects()) {
     953            for (RenderBox* it : *positionedObjects) {
     954                if (it != &renderer && renderer.element()->contains(it->element()))
     955                    return false;
     956            }
     957        }
     958    }
     959   
     960    return false;
     961}
     962
     963LayoutRect Element::absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements)
     964{
     965    boundsIncludeAllDescendantElements = false;
     966    includesFixedPositionElements = false;
     967
     968    if (!renderer())
     969        return LayoutRect();
     970
     971    LayoutRect result;
     972    if (isSVGElement()) {
     973        // Get the bounding rectangle from the SVG model.
     974        SVGElement& svgElement = downcast<SVGElement>(*this);
     975        FloatRect localRect;
     976        if (svgElement.getBoundingBox(localRect))
     977            result = LayoutRect(renderer()->localToAbsoluteQuad(localRect, UseTransforms, &includesFixedPositionElements).boundingBox());
     978    } else {
     979        if (is<RenderBox>(renderer())) {
     980            RenderBox& box = *downcast<RenderBox>(renderer());
     981
     982            bool computedBounds = false;
     983           
     984            if (RenderFlowThread* flowThread = box.flowThreadContainingBlock()) {
     985                bool wasFixed = false;
     986                Vector<FloatQuad> quads;
     987                FloatRect localRect(0, 0, box.width(), box.height());
     988                if (flowThread->absoluteQuadsForBox(quads, &wasFixed, &box, localRect.y(), localRect.maxY())) {
     989                    FloatRect quadBounds = quads[0].boundingBox();
     990                    for (size_t i = 1; i < quads.size(); ++i)
     991                        quadBounds.unite(quads[i].boundingBox());
     992                   
     993                    result = LayoutRect(quadBounds);
     994                    computedBounds = true;
     995                } else {
     996                    // Probably columns. Just return the bounds of the multicol block for now.
     997                    // FIXME: this doesn't handle nested columns.
     998                    RenderElement* multicolContainer = flowThread->parent();
     999                    if (multicolContainer && is<RenderBox>(multicolContainer)) {
     1000                        LayoutRect overflowRect = downcast<RenderBox>(multicolContainer)->layoutOverflowRect();
     1001                        result = LayoutRect(multicolContainer->localToAbsoluteQuad(FloatRect(overflowRect), UseTransforms, &includesFixedPositionElements).boundingBox());
     1002                        computedBounds = true;
     1003                    }
     1004                }
     1005            }
     1006
     1007            if (!computedBounds) {
     1008                LayoutRect overflowRect = box.layoutOverflowRect();
     1009                result = LayoutRect(box.localToAbsoluteQuad(FloatRect(overflowRect), UseTransforms, &includesFixedPositionElements).boundingBox());
     1010                boundsIncludeAllDescendantElements = layoutOverflowRectContainsAllDescendants(box);
     1011            }
     1012        } else
     1013            result = LayoutRect(renderer()->absoluteBoundingBoxRect(true /* useTransforms */, &includesFixedPositionElements));
     1014    }
     1015
     1016    return result;
     1017}
     1018
     1019LayoutRect Element::absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements)
     1020{
     1021    bool boundsIncludeDescendants;
     1022    LayoutRect result = absoluteEventBounds(boundsIncludeDescendants, includesFixedPositionElements);
     1023    if (boundsIncludeDescendants)
     1024        return result;
     1025
     1026    for (auto& child : childrenOfType<Element>(*this)) {
     1027        bool includesFixedPosition = false;
     1028        LayoutRect childBounds = child.absoluteEventBoundsOfElementAndDescendants(includesFixedPosition);
     1029        includesFixedPositionElements |= includesFixedPosition;
     1030        result.unite(childBounds);
     1031    }
     1032
     1033    return result;
     1034}
     1035
     1036LayoutRect Element::absoluteEventHandlerBounds(bool& includesFixedPositionElements)
     1037{
     1038    // This is not web-exposed, so don't call the FOUC-inducing updateLayoutIgnorePendingStylesheets().
     1039    FrameView* frameView = document().view();
     1040    if (!frameView)
     1041        return LayoutRect();
     1042
     1043    if (frameView->needsLayout())
     1044        frameView->layout();
     1045
     1046    return absoluteEventBoundsOfElementAndDescendants(includesFixedPositionElements);
     1047}
     1048
    9281049Ref<ClientRectList> Element::getClientRects()
    9291050{
  • TabularUnified trunk/Source/WebCore/dom/Element.h

    r181907 r182215  
    485485    virtual RefPtr<RenderStyle> customStyleForRenderer(RenderStyle& parentStyle);
    486486
     487    LayoutRect absoluteEventHandlerBounds(bool& includesFixedPositionElements) override;
     488
    487489    void setBeforePseudoElement(Ref<PseudoElement>&&);
    488490    void setAfterPseudoElement(Ref<PseudoElement>&&);
     
    563565    void removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute);
    564566
     567    LayoutRect absoluteEventBounds(bool& boundsIncludeAllDescendantElements, bool& includesFixedPositionElements);
     568    LayoutRect absoluteEventBoundsOfElementAndDescendants(bool& includesFixedPositionElements);
     569   
    565570#if ENABLE(TREE_DEBUGGING)
    566571    virtual void formatForDebugger(char* buffer, unsigned length) const override;
  • TabularUnified trunk/Source/WebCore/page/DebugPageOverlays.cpp

    r182132 r182215  
    9191bool MouseWheelRegionOverlay::updateRegion()
    9292{
    93     std::unique_ptr<Region> region = std::make_unique<Region>();
    94 
    95     for (auto& element : descendantsOfType<Element>(*m_frame.document())) {
    96         if (element.hasEventListeners(eventNames().mousewheelEvent) || element.hasEventListeners(eventNames().wheelEvent)) {
    97             IntRect elementRect = element.boundsInRootViewSpace();
    98             elementRect = m_frame.view()->rootViewToContents(elementRect);
    99             region->unite(Region(elementRect));
    100         }
    101     }
     93    std::unique_ptr<Region> region = std::make_unique<Region>(m_frame.document()->absoluteRegionForEventTargets(m_frame.document()->wheelEventTargets()));
    10294
    10395    bool regionChanged = !m_region || !(*m_region == *region);
  • TabularUnified trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp

    r182143 r182215  
    9999Region ScrollingCoordinator::computeNonFastScrollableRegion(const Frame& frame, const IntPoint& frameLocation) const
    100100{
     101    RenderView* renderView = frame.contentRenderer();
     102    if (!renderView || renderView->documentBeingDestroyed())
     103        return Region();
     104
    101105#if ENABLE(IOS_TOUCH_EVENTS)
    102106    // On iOS, we use nonFastScrollableRegion to represent the region covered by elements with touch event handlers.
     
    115119        touchRegion.unite(rect);
    116120
     121    // FIXME: use absoluteRegionForEventTargets().
    117122    return touchRegion;
    118123#else
     
    149154        nonFastScrollableRegion.unite(computeNonFastScrollableRegion(*subframe, offset));
    150155
     156    // Include wheel event handler region for the main frame.
     157    Region wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
     158    wheelHandlerRegion.translate(toIntSize(offset));
     159    nonFastScrollableRegion.unite(wheelHandlerRegion);
     160
    151161    return nonFastScrollableRegion;
    152162#endif
  • TabularUnified trunk/Source/WebCore/rendering/RenderLayer.cpp

    r182132 r182215  
    4949#include "CSSPropertyNames.h"
    5050#include "Chrome.h"
     51#include "DebugPageOverlays.h"
    5152#include "Document.h"
    5253#include "DocumentEventQueue.h"
     
    23922393        renderer().document().dirtyTouchEventRects();
    23932394#endif
     2395        DebugPageOverlays::didLayout(renderer().frame());
    23942396    }
    23952397
  • TabularUnified trunk/Source/WebCore/rendering/RenderObject.cpp

    r181654 r182215  
    10861086#endif
    10871087
    1088 IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
     1088IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms, bool* wasFixed) const
    10891089{
    10901090    if (useTransforms) {
    10911091        Vector<FloatQuad> quads;
    1092         absoluteQuads(quads);
     1092        absoluteQuads(quads, wasFixed);
    10931093
    10941094        size_t n = quads.size();
     
    11021102    }
    11031103
    1104     FloatPoint absPos = localToAbsolute();
     1104    FloatPoint absPos = localToAbsolute(FloatPoint(), 0 /* ignore transforms */, wasFixed);
    11051105    Vector<IntRect> rects;
    11061106    absoluteRects(rects, flooredLayoutPoint(absPos));
     
    15801580}
    15811581
    1582 FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode) const
     1582FloatPoint RenderObject::localToAbsolute(const FloatPoint& localPoint, MapCoordinatesFlags mode, bool* wasFixed) const
    15831583{
    15841584    TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
    1585     mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip);
     1585    mapLocalToContainer(nullptr, transformState, mode | ApplyContainerFlip, wasFixed);
    15861586    transformState.flatten();
    15871587   
  • TabularUnified trunk/Source/WebCore/rendering/RenderObject.h

    r182146 r182215  
    653653
    654654    // Convert the given local point to absolute coordinates. If MapCoordinatesFlags includes UseTransforms, take transforms into account.
    655     WEBCORE_EXPORT FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0) const;
     655    WEBCORE_EXPORT FloatPoint localToAbsolute(const FloatPoint& localPoint = FloatPoint(), MapCoordinatesFlags = 0, bool* wasFixed = nullptr) const;
    656656    FloatPoint absoluteToLocal(const FloatPoint&, MapCoordinatesFlags = 0) const;
    657657
     
    682682
    683683    // FIXME: useTransforms should go away eventually
    684     WEBCORE_EXPORT IntRect absoluteBoundingBoxRect(bool useTransform = true) const;
     684    WEBCORE_EXPORT IntRect absoluteBoundingBoxRect(bool useTransform = true, bool* wasFixed = nullptr) const;
    685685    IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); }
    686686
Note: See TracChangeset for help on using the changeset viewer.