[Synthetic Click] Dispatch mouseout soon after mouseup
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2019 01:58:17 +0000 (01:58 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Mar 2019 01:58:17 +0000 (01:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195575
<rdar://problem/47093049>

Reviewed by Simon Fraser.

Source/WebCore:

Let's fire a mouseout event when a click is submitted as the result of a tap. It helps to dismiss content which would otherwise require you to move the mouse (cases like control bar on youtube.com).

Test: fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click.html

* page/EventHandler.h:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::dispatchFakeMouseOut):

Source/WebKit:

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::completeSyntheticClick):

LayoutTests:

* fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click-expected.txt: Added.
* fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242763 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/touch/ios/content-observation/visibility-change-happens-while-in-mousemoved.html
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/EventHandler.h
Source/WebCore/page/ios/EventHandlerIOS.mm
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

index b95728b..d9dcaff 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-11  Zalan Bujtas  <zalan@apple.com>
+
+        [Synthetic Click] Dispatch mouseout soon after mouseup
+        https://bugs.webkit.org/show_bug.cgi?id=195575
+        <rdar://problem/47093049>
+
+        Reviewed by Simon Fraser.
+
+        * fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click-expected.txt: Added.
+        * fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click.html: Added.
+
 2019-03-11  Justin Fan  <justin_fan@apple.com>
 
         [Web GPU] Update GPUSwapChainDescriptor, GPUSwapChain and implement GPUCanvasContext
index 2079f1e..2049137 100644 (file)
@@ -45,7 +45,11 @@ tapthis.addEventListener("mouseover", function( event ) {
         testRunner.notifyDone();
 }, false);
 
-becomesVisible.addEventListener("click", function( event ) {   
+tapthis.addEventListener("mouseout", function( event ) {
+    result.innerHTML = result.innerHTML + " mouseout should NOT be triggered ";
+}, false);
+
+becomesVisible.addEventListener("click", function( event ) {
     result.innerHTML = "clicked hidden";
 }, false);
 
index 83813f8..a1ce96e 100644 (file)
@@ -1,3 +1,19 @@
+2019-03-11  Zalan Bujtas  <zalan@apple.com>
+
+        [Synthetic Click] Dispatch mouseout soon after mouseup
+        https://bugs.webkit.org/show_bug.cgi?id=195575
+        <rdar://problem/47093049>
+
+        Reviewed by Simon Fraser.
+
+        Let's fire a mouseout event when a click is submitted as the result of a tap. It helps to dismiss content which would otherwise require you to move the mouse (cases like control bar on youtube.com).
+
+        Test: fast/events/touch/ios/content-observation/mouse-out-event-should-fire-on-click.html
+
+        * page/EventHandler.h:
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::dispatchFakeMouseOut):
+
 2019-03-11  Youenn Fablet  <youenn@apple.com>
 
         REGRESSION: (r242181) API test DragAndDropTests.ExternalSourcePlainTextToIFrame is Timing out
index 8c8490c..9339236 100644 (file)
@@ -1978,7 +1978,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
 #endif
         if (onlyUpdateScrollbars) {
             if (shouldSendMouseEventsToInactiveWindows())
-                updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
+                updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, FireMouseOverOut::Yes);
 
             return true;
         }
@@ -1993,7 +1993,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseE
 
     if (newSubframe) {
         // Update over/out state before passing the event to the subframe.
-        updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
+        updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, FireMouseOverOut::Yes);
         
         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
         // node to be detached from its FrameView, in which case the event should not be passed.
@@ -2476,7 +2476,7 @@ static bool hierarchyHasCapturingEventListeners(Element* element, const AtomicSt
     return false;
 }
 
-void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, bool fireMouseOverOut)
+void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, FireMouseOverOut fireMouseOverOut)
 {
     Ref<Frame> protectedFrame(m_frame);
     Element* targetElement = nullptr;
@@ -2494,7 +2494,7 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
     m_elementUnderMouse = targetElement;
 
     // Fire mouseout/mouseover if the mouse has shifted to a different node.
-    if (fireMouseOverOut) {
+    if (fireMouseOverOut == FireMouseOverOut::Yes) {
         auto scrollableAreaForLastNode = enclosingScrollableArea(m_lastElementUnderMouse.get());
         auto scrollableAreaForNodeUnderMouse = enclosingScrollableArea(m_elementUnderMouse.get());
         Page* page = m_frame.page();
@@ -2588,7 +2588,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
     if (auto* view = m_frame.view())
         view->disableLayerFlushThrottlingTemporarilyForInteraction();
 
-    updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder);
+    updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder ? FireMouseOverOut::Yes : FireMouseOverOut::No);
 
     if (m_elementUnderMouse && !m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventType, clickCount))
         return false;
index 9ea9e0c..57b5947 100644 (file)
@@ -241,6 +241,7 @@ public:
 
 #if PLATFORM(IOS_FAMILY)
     void defaultTouchEventHandler(Node&, TouchEvent&);
+    WEBCORE_EXPORT void dispatchSyntheticMouseOut(const PlatformMouseEvent&);
 #endif
 
 #if ENABLE(CONTEXT_MENUS)
@@ -404,9 +405,9 @@ private:
 
     Node* nodeUnderMouse() const;
     
-    void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
-    void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
-    
+    enum class FireMouseOverOut { No, Yes };
+    void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, FireMouseOverOut);
+
     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
 
     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
index d006d41..bb08a42 100644 (file)
@@ -515,6 +515,11 @@ static bool frameHasPlatformWidget(const Frame& frame)
     return false;
 }
 
+void EventHandler::dispatchSyntheticMouseOut(const PlatformMouseEvent& platformMouseEvent)
+{
+    updateMouseEventTargetNode(nullptr, platformMouseEvent, FireMouseOverOut::Yes);
+}
+
 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
 {
     // WebKit1 code path.
index 3b0472b..75ae618 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-11  Zalan Bujtas  <zalan@apple.com>
+
+        [Synthetic Click] Dispatch mouseout soon after mouseup
+        https://bugs.webkit.org/show_bug.cgi?id=195575
+        <rdar://problem/47093049>
+
+        Reviewed by Simon Fraser.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::completeSyntheticClick):
+
 2019-03-11  Tim Horton  <timothy_horton@apple.com>
 
         API test WebKit.RequestTextInputContext fails on iOS
index db00d2f..0f43ea0 100644 (file)
@@ -640,6 +640,10 @@ void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore:
     if (newFocusedElement && newFocusedElement == oldFocusedElement)
         elementDidRefocus(*newFocusedElement);
 
+    nodeRespondingToClick.document().frame()->eventHandler().dispatchSyntheticMouseOut(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, LeftButton, PlatformEvent::NoType, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), 0, WebCore::NoTap));
+    if (m_isClosed)
+        return;
+
     if (!tapWasHandled || !nodeRespondingToClick.isElementNode())
         send(Messages::WebPageProxy::DidNotHandleTapAsClick(roundedIntPoint(location)));