Changeset 145126 in webkit


Ignore:
Timestamp:
Mar 7, 2013 1:24:18 PM (11 years ago)
Author:
mkwst@chromium.org
Message:

Move side-effects on hover/active state out of hit-testing
https://bugs.webkit.org/show_bug.cgi?id=98168

Reviewed by Julien Chaffraix.

Original patch by Allan Sandfeld Jensen; I'm just tweaking things.

Document::updateHoverActiveState is currently called during hit testing
to update the hover and active states of elements effected by mouse
movements (or their keyboard equivalents). This conflates the hit test
algorithm itself with side-effects associated with specific use-cases.

This conflation makes it very difficult to reuse the hover/active logic
for things other than hit testing. 'mouseenter'/'mouseleave' events[1]
are one example of a feature that would be simple to implement on top of
this existing logic if we split it out from the hit testing path, and
instead call it explicitly when necessary. An explicit split between
hit testing and its side-effects will also enable us to simplify the
logic in future patches with well-named parameters, rather than relying
on stuffing properties into HitTestRequest.

This patch drops the call to Document::updateHoverActiveState from
RenderView::hitTest, and adjusts the three call-sites in EventHandler
to explicitly call out to it rather than Document::updateStyleIfNeeded.
The latter call is still necessary but has been folded into
updateHoverActiveState, as the former is never called without calling
the latter.

[1]: http://wkbug.com/18930

  • dom/Document.h:
  • dom/Document.cpp:

(WebCore::Document::updateHoverActiveState):

First, this function must now only be called from contexts that were
performing a read/write hit-test: the code asserts this
precondition.

Second, rather than accepting a HitTestResult, the function accepts
an Element* from which to begin the hover/active chain changes.

Third, we have to explicitly update the hover/active states for
documents between the updated element and the top-level document.
The hit-testing logic was taking care of this for us, now we need to
take care of it ourselves.

Fourth, call out to updateStyleIfNeeded rather than making our
caller do so. The calls were always paired; now that's explicit.

(WebCore::Document::prepareMouseEvent):

  • page/EventHandler.cpp:

(WebCore::EventHandler::hitTestResultAtPoint):
(WebCore::EventHandler::sendContextMenuEventForKey):
(WebCore::EventHandler::hoverTimerFired):

Call out to updateHoverActiveState rather than updateStyleIfNeeded.

  • rendering/RenderView.cpp:

(WebCore::RenderView::hitTest):

Drop the call to updateHoverActiveState.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r145123 r145126  
     12013-03-07  Mike West  <mkwst@chromium.org>
     2
     3        Move side-effects on hover/active state out of hit-testing
     4        https://bugs.webkit.org/show_bug.cgi?id=98168
     5
     6        Reviewed by Julien Chaffraix.
     7
     8        Original patch by Allan Sandfeld Jensen; I'm just tweaking things.
     9
     10        Document::updateHoverActiveState is currently called during hit testing
     11        to update the hover and active states of elements effected by mouse
     12        movements (or their keyboard equivalents). This conflates the hit test
     13        algorithm itself with side-effects associated with specific use-cases.
     14
     15        This conflation makes it very difficult to reuse the hover/active logic
     16        for things other than hit testing. 'mouseenter'/'mouseleave' events[1]
     17        are one example of a feature that would be simple to implement on top of
     18        this existing logic if we split it out from the hit testing path, and
     19        instead call it explicitly when necessary. An explicit split between
     20        hit testing and its side-effects will also enable us to simplify the
     21        logic in future patches with well-named parameters, rather than relying
     22        on stuffing properties into HitTestRequest.
     23
     24        This patch drops the call to Document::updateHoverActiveState from
     25        RenderView::hitTest, and adjusts the three call-sites in EventHandler
     26        to explicitly call out to it rather than Document::updateStyleIfNeeded.
     27        The latter call is still necessary but has been folded into
     28        updateHoverActiveState, as the former is never called without calling
     29        the latter.
     30
     31        [1]: http://wkbug.com/18930
     32
     33        * dom/Document.h:
     34        * dom/Document.cpp:
     35        (WebCore::Document::updateHoverActiveState):
     36            First, this function must now only be called from contexts that were
     37            performing a read/write hit-test: the code asserts this
     38            precondition.
     39
     40            Second, rather than accepting a HitTestResult, the function accepts
     41            an Element* from which to begin the hover/active chain changes.
     42
     43            Third, we have to explicitly update the hover/active states for
     44            documents between the updated element and the top-level document.
     45            The hit-testing logic was taking care of this for us, now we need to
     46            take care of it ourselves.
     47
     48            Fourth, call out to updateStyleIfNeeded rather than making our
     49            caller do so. The calls were always paired; now that's explicit.
     50        (WebCore::Document::prepareMouseEvent):
     51        * page/EventHandler.cpp:
     52        (WebCore::EventHandler::hitTestResultAtPoint):
     53        (WebCore::EventHandler::sendContextMenuEventForKey):
     54        (WebCore::EventHandler::hoverTimerFired):
     55            Call out to updateHoverActiveState rather than updateStyleIfNeeded.
     56        * rendering/RenderView.cpp:
     57        (WebCore::RenderView::hitTest):
     58            Drop the call to updateHoverActiveState.
     59
    1602013-03-07  Sheriff Bot  <webkit.review.bot@gmail.com>
    261
  • trunk/Source/WebCore/dom/Document.cpp

    r145040 r145126  
    29982998
    29992999    if (!request.readOnly())
    3000         updateStyleIfNeeded();
     3000        updateHoverActiveState(request, result.innerElement());
    30013001
    30023002    return MouseEventWithHitTestResults(event, result);
     
    58315831}
    58325832
    5833 void Document::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
    5834 {
    5835     // We don't update :hover/:active state when the result is marked as readOnly.
    5836     if (request.readOnly())
    5837         return;
    5838 
    5839     Element* innerElementInDocument = result.innerElement();
    5840     while (innerElementInDocument && innerElementInDocument->document() != this)
     5833void Document::updateHoverActiveState(const HitTestRequest& request, Element* innerElement)
     5834{
     5835    ASSERT(!request.readOnly());
     5836
     5837    Element* innerElementInDocument = innerElement;
     5838    while (innerElementInDocument && innerElementInDocument->document() != this) {
     5839        innerElementInDocument->document()->updateHoverActiveState(request, innerElementInDocument);
    58415840        innerElementInDocument = innerElementInDocument->document()->ownerElement();
     5841    }
    58425842
    58435843    Element* oldActiveElement = activeElement();
     
    59245924        nodesToAddToChain[i]->setHovered(true);
    59255925    }
     5926
     5927    updateStyleIfNeeded();
    59265928}
    59275929
  • trunk/Source/WebCore/dom/Document.h

    r144735 r145126  
    690690    void activeChainNodeDetached(Node*);
    691691
    692     void updateHoverActiveState(const HitTestRequest&, HitTestResult&);
     692    void updateHoverActiveState(const HitTestRequest&, Element*);
    693693
    694694    // Updates for :target (CSS3 selector).
  • trunk/Source/WebCore/page/EventHandler.cpp

    r145003 r145126  
    10401040    HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
    10411041    m_frame->contentRenderer()->hitTest(request, result);
     1042    if (!request.readOnly())
     1043        m_frame->document()->updateHoverActiveState(request, result.innerElement());
    10421044
    10431045    if (!request.allowsShadowContent())
     
    29362938    HitTestResult result(position);
    29372939    result.setInnerNode(targetNode);
    2938     HitTestRequest request(HitTestRequest::Active);
    2939     doc->updateHoverActiveState(request, result);
    2940     doc->updateStyleIfNeeded();
    2941    
     2940    doc->updateHoverActiveState(HitTestRequest::Active, result.innerElement());
     2941
    29422942    // The contextmenu event is a mouse event even when invoked using the keyboard.
    29432943    // This is required for web compatibility.
     
    30753075            HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
    30763076            renderer->hitTest(request, result);
    3077             m_frame->document()->updateStyleIfNeeded();
     3077            m_frame->document()->updateHoverActiveState(request, result.innerElement());
    30783078        }
    30793079    }
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r144744 r145126  
    9393bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
    9494{
    95     bool inside = layer()->hitTest(request, location, result);
    96 
    97     // Next set up the correct :hover/:active state along the new chain.
    98     document()->updateHoverActiveState(request, result);
    99 
    100     return inside;
     95    return layer()->hitTest(request, location, result);
    10196}
    10297
Note: See TracChangeset for help on using the changeset viewer.