Title: [195659] trunk/Source/WebCore
Revision
195659
Author
[email protected]
Date
2016-01-27 02:24:57 -0800 (Wed, 27 Jan 2016)

Log Message

ScrollAnimator is not notified when mouse entered, moved or exited a RenderListBox
https://bugs.webkit.org/show_bug.cgi?id=153398

Reviewed by Michael Catanzaro.

EvenHandler is checking whether the enclosing layer of a node is
registered as scrollable area of its frame view. That doesn't work
for list boxes, because they are the scrollable area
themselves. Also when entering a list box the node under mouse is
not usually the list box itself, but any of its children, a
HTMLOptionElement or a HTMLOptGroupElement. Instead of comparing
layers, we should find the enclosing scrollable area of the target
elements and compare them to decide whether the mouse has entered,
left or moved a scrollable area.

* page/EventHandler.cpp:
(WebCore::enclosingScrollableArea): Return the enclosing
scrollable area of the given node. If the node doesn't have a
renderer, it traverses its parents. If the renderer is a
RenderListBox it is returned, otherwhise the enclosing layer is
returned.
(WebCore::EventHandler::mouseMoved): Use enclosingScrollableArea.
(WebCore::EventHandler::updateMouseEventTargetNode): Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (195658 => 195659)


--- trunk/Source/WebCore/ChangeLog	2016-01-27 07:43:50 UTC (rev 195658)
+++ trunk/Source/WebCore/ChangeLog	2016-01-27 10:24:57 UTC (rev 195659)
@@ -1,3 +1,29 @@
+2016-01-27  Carlos Garcia Campos  <[email protected]>
+
+        ScrollAnimator is not notified when mouse entered, moved or exited a RenderListBox
+        https://bugs.webkit.org/show_bug.cgi?id=153398
+
+        Reviewed by Michael Catanzaro.
+
+        EvenHandler is checking whether the enclosing layer of a node is
+        registered as scrollable area of its frame view. That doesn't work
+        for list boxes, because they are the scrollable area
+        themselves. Also when entering a list box the node under mouse is
+        not usually the list box itself, but any of its children, a
+        HTMLOptionElement or a HTMLOptGroupElement. Instead of comparing
+        layers, we should find the enclosing scrollable area of the target
+        elements and compare them to decide whether the mouse has entered,
+        left or moved a scrollable area.
+
+        * page/EventHandler.cpp:
+        (WebCore::enclosingScrollableArea): Return the enclosing
+        scrollable area of the given node. If the node doesn't have a
+        renderer, it traverses its parents. If the renderer is a
+        RenderListBox it is returned, otherwhise the enclosing layer is
+        returned.
+        (WebCore::EventHandler::mouseMoved): Use enclosingScrollableArea.
+        (WebCore::EventHandler::updateMouseEventTargetNode): Ditto.
+
 2016-01-26  Sam Weinig  <[email protected]>
 
         Try touching DerivedSources.make to force rebuilding.

Modified: trunk/Source/WebCore/page/EventHandler.cpp (195658 => 195659)


--- trunk/Source/WebCore/page/EventHandler.cpp	2016-01-27 07:43:50 UTC (rev 195658)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2016-01-27 10:24:57 UTC (rev 195659)
@@ -1753,20 +1753,26 @@
     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
 }
 
-static RenderLayer* layerForNode(Node* node)
+static ScrollableArea* enclosingScrollableArea(Node* node)
 {
     if (!node)
-        return 0;
+        return nullptr;
 
-    auto renderer = node->renderer();
-    if (!renderer)
-        return 0;
+    for (auto element = node; element; element = element->parentOrShadowHostNode()) {
+        if (is<HTMLIFrameElement>(*element) || is<HTMLHtmlElement>(*element) || is<HTMLDocument>(*element))
+            return nullptr;
 
-    RenderLayer* layer = renderer->enclosingLayer();
-    if (!layer)
-        return 0;
+        auto renderer = element->renderer();
+        if (!renderer)
+            continue;
 
-    return layer;
+        if (is<RenderListBox>(*renderer))
+            return downcast<RenderListBox>(renderer);
+
+        return renderer->enclosingLayer();
+    }
+
+    return nullptr;
 }
 
 bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
@@ -1784,10 +1790,10 @@
     if (!page)
         return result;
 
-    if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
+    if (auto scrolledArea = enclosingScrollableArea(hoveredNode.innerNode())) {
         if (FrameView* frameView = m_frame.view()) {
-            if (frameView->containsScrollableArea(layer))
-                layer->mouseMovedInContentArea();
+            if (frameView->containsScrollableArea(scrolledArea))
+                scrolledArea->mouseMovedInContentArea();
         }
     }
 
@@ -2360,8 +2366,8 @@
 
     // Fire mouseout/mouseover if the mouse has shifted to a different node.
     if (fireMouseOverOut) {
-        RenderLayer* layerForLastNode = layerForNode(m_lastElementUnderMouse.get());
-        RenderLayer* layerForNodeUnderMouse = layerForNode(m_elementUnderMouse.get());
+        auto scrollableAreaForLastNode = enclosingScrollableArea(m_lastElementUnderMouse.get());
+        auto scrollableAreaForNodeUnderMouse = enclosingScrollableArea(m_elementUnderMouse.get());
         Page* page = m_frame.page();
 
         if (m_lastElementUnderMouse && (!m_elementUnderMouse || &m_elementUnderMouse->document() != m_frame.document())) {
@@ -2370,12 +2376,12 @@
                 if (FrameView* frameView = frame->view())
                     frameView->mouseExitedContentArea();
             }
-        } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
+        } else if (page && (scrollableAreaForLastNode && (!scrollableAreaForNodeUnderMouse || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
             // The mouse has moved between layers.
             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
                 if (FrameView* frameView = frame->view()) {
-                    if (frameView->containsScrollableArea(layerForLastNode))
-                        layerForLastNode->mouseExitedContentArea();
+                    if (frameView->containsScrollableArea(scrollableAreaForLastNode))
+                        scrollableAreaForLastNode->mouseExitedContentArea();
                 }
             }
         }
@@ -2386,12 +2392,12 @@
                 if (FrameView* frameView = frame->view())
                     frameView->mouseEnteredContentArea();
             }
-        } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
+        } else if (page && (scrollableAreaForNodeUnderMouse && (!scrollableAreaForLastNode || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
             // The mouse has moved between layers.
             if (Frame* frame = m_elementUnderMouse->document().frame()) {
                 if (FrameView* frameView = frame->view()) {
-                    if (frameView->containsScrollableArea(layerForNodeUnderMouse))
-                        layerForNodeUnderMouse->mouseEnteredContentArea();
+                    if (frameView->containsScrollableArea(scrollableAreaForNodeUnderMouse))
+                        scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
                 }
             }
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to