Title: [276351] trunk
Revision
276351
Author
timothy_hor...@apple.com
Date
2021-04-21 00:38:21 -0700 (Wed, 21 Apr 2021)

Log Message

Long-pressing a data detectors link causes the link to be followed
https://bugs.webkit.org/show_bug.cgi?id=224847
<rdar://problem/72889738>

Reviewed by Wenson Hsieh.

Source/WebCore:

New API tests: iOSMouseSupport.{EndedTouchesTriggerClick,CancelledTouchesDoNotTriggerClick}

* page/EventHandler.h:

Source/WebKit:

On iOS, it is possible for a gesture to be externally cancelled (in this case,
when a data detectors context menu is presented by long pressing a link).
This is reported to WKMouseGestureRecognizer as "touches cancelled".
Currently, WKMouseGestureRecognizer just runs with that as a normal
"mouse button release" event, which then causes the link that you're long
pressing to also be followed.

* Shared/NativeWebMouseEvent.h:
* Shared/WebMouseEvent.cpp:
(WebKit::WebMouseEvent::WebMouseEvent):
(WebKit::WebMouseEvent::encode const):
(WebKit::WebMouseEvent::decode):
* Shared/WebMouseEvent.h:
(WebKit::WebMouseEvent::gestureCancelled const):
* Shared/ios/NativeWebMouseEventIOS.mm:
(WebKit::NativeWebMouseEvent::NativeWebMouseEvent):
* UIProcess/ios/WKMouseGestureRecognizer.mm:
(-[WKMouseGestureRecognizer createMouseEventWithType:wasCancelled:]):
(-[WKMouseGestureRecognizer touchesBegan:withEvent:]):
(-[WKMouseGestureRecognizer touchesMoved:withEvent:]):
(-[WKMouseGestureRecognizer touchesEnded:withEvent:]):
(-[WKMouseGestureRecognizer touchesCancelled:withEvent:]):
(-[WKMouseGestureRecognizer _hoverEntered:withEvent:]):
(-[WKMouseGestureRecognizer _hoverMoved:withEvent:]):
(-[WKMouseGestureRecognizer _hoverExited:withEvent:]):
(-[WKMouseGestureRecognizer createMouseEventWithType:]): Deleted.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::handleMouseEvent):
Add a bit to WebKit::WebMouseEvent indicating that the gesture it is a part of
was cancelled. This will only be set on the mouse release event dispatched from
touchesCancelled from WKMouseGestureRecognizer, and will cause WebCore to
avoid dispatching the click event, as you would on macOS if you e.g.
moved the mouse too far from its origin during the press.

Plumb the bit all the way from WKMouseGestureRecognizer, through the
NativeWebMouseEvent constructor, to WebMouseEvent, and then check it
and call invalidateClick() immediately before handing WebCore the
mouse release event, to avoid the click event.

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm:
(TEST):
Add tests ensuring that we get a click event for completed touches, and not for cancelled touches.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (276350 => 276351)


--- trunk/Source/WebCore/ChangeLog	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebCore/ChangeLog	2021-04-21 07:38:21 UTC (rev 276351)
@@ -1,3 +1,15 @@
+2021-04-21  Tim Horton  <timothy_hor...@apple.com>
+
+        Long-pressing a data detectors link causes the link to be followed
+        https://bugs.webkit.org/show_bug.cgi?id=224847
+        <rdar://problem/72889738>
+
+        Reviewed by Wenson Hsieh.
+
+        New API tests: iOSMouseSupport.{EndedTouchesTriggerClick,CancelledTouchesDoNotTriggerClick}
+
+        * page/EventHandler.h:
+
 2021-04-21  Youenn Fablet  <you...@apple.com>
 
         [ BigSur wk2 ARM64 ] http/wpt/webrtc/change-encoded-transform.html is a flakey crash

Modified: trunk/Source/WebCore/page/EventHandler.h (276350 => 276351)


--- trunk/Source/WebCore/page/EventHandler.h	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebCore/page/EventHandler.h	2021-04-21 07:38:21 UTC (rev 276351)
@@ -316,8 +316,6 @@
 
 #if PLATFORM(IOS_FAMILY)
     static WebEvent *currentEvent();
-
-    void invalidateClick();
 #endif
 
 #if ENABLE(TOUCH_EVENTS)
@@ -353,6 +351,9 @@
 #if ENABLE(DRAG_SUPPORT)
     Element* draggingElement() const;
 #endif
+
+    WEBCORE_EXPORT void invalidateClick();
+
 private:
 #if ENABLE(DRAG_SUPPORT)
     static DragState& dragState();
@@ -409,10 +410,6 @@
     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
 #endif
 
-#if !PLATFORM(IOS_FAMILY)
-    void invalidateClick();
-#endif
-
     Node* nodeUnderMouse() const;
     
     enum class FireMouseOverOut { No, Yes };

Modified: trunk/Source/WebKit/ChangeLog (276350 => 276351)


--- trunk/Source/WebKit/ChangeLog	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/ChangeLog	2021-04-21 07:38:21 UTC (rev 276351)
@@ -1,3 +1,50 @@
+2021-04-21  Tim Horton  <timothy_hor...@apple.com>
+
+        Long-pressing a data detectors link causes the link to be followed
+        https://bugs.webkit.org/show_bug.cgi?id=224847
+        <rdar://problem/72889738>
+
+        Reviewed by Wenson Hsieh.
+
+        On iOS, it is possible for a gesture to be externally cancelled (in this case,
+        when a data detectors context menu is presented by long pressing a link).
+        This is reported to WKMouseGestureRecognizer as "touches cancelled".
+        Currently, WKMouseGestureRecognizer just runs with that as a normal
+        "mouse button release" event, which then causes the link that you're long
+        pressing to also be followed.
+
+        * Shared/NativeWebMouseEvent.h:
+        * Shared/WebMouseEvent.cpp:
+        (WebKit::WebMouseEvent::WebMouseEvent):
+        (WebKit::WebMouseEvent::encode const):
+        (WebKit::WebMouseEvent::decode):
+        * Shared/WebMouseEvent.h:
+        (WebKit::WebMouseEvent::gestureCancelled const):
+        * Shared/ios/NativeWebMouseEventIOS.mm:
+        (WebKit::NativeWebMouseEvent::NativeWebMouseEvent):
+        * UIProcess/ios/WKMouseGestureRecognizer.mm:
+        (-[WKMouseGestureRecognizer createMouseEventWithType:wasCancelled:]):
+        (-[WKMouseGestureRecognizer touchesBegan:withEvent:]):
+        (-[WKMouseGestureRecognizer touchesMoved:withEvent:]):
+        (-[WKMouseGestureRecognizer touchesEnded:withEvent:]):
+        (-[WKMouseGestureRecognizer touchesCancelled:withEvent:]):
+        (-[WKMouseGestureRecognizer _hoverEntered:withEvent:]):
+        (-[WKMouseGestureRecognizer _hoverMoved:withEvent:]):
+        (-[WKMouseGestureRecognizer _hoverExited:withEvent:]):
+        (-[WKMouseGestureRecognizer createMouseEventWithType:]): Deleted.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::handleMouseEvent):
+        Add a bit to WebKit::WebMouseEvent indicating that the gesture it is a part of
+        was cancelled. This will only be set on the mouse release event dispatched from
+        touchesCancelled from WKMouseGestureRecognizer, and will cause WebCore to
+        avoid dispatching the click event, as you would on macOS if you e.g.
+        moved the mouse too far from its origin during the press.
+
+        Plumb the bit all the way from WKMouseGestureRecognizer, through the
+        NativeWebMouseEvent constructor, to WebMouseEvent, and then check it
+        and call invalidateClick() immediately before handing WebCore the
+        mouse release event, to avoid the click event.
+
 2021-04-21  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [macOS] Avoid triggering image extraction for animated images

Modified: trunk/Source/WebKit/Shared/NativeWebMouseEvent.h (276350 => 276351)


--- trunk/Source/WebKit/Shared/NativeWebMouseEvent.h	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/Shared/NativeWebMouseEvent.h	2021-04-21 07:38:21 UTC (rev 276351)
@@ -70,7 +70,7 @@
     explicit NativeWebMouseEvent(const WebCore::IntPoint&);
 #elif PLATFORM(IOS_FAMILY)
     NativeWebMouseEvent(::WebEvent *);
-    NativeWebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force);
+    NativeWebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force, GestureWasCancelled);
 #elif USE(LIBWPE)
     NativeWebMouseEvent(struct wpe_input_pointer_event*, float deviceScaleFactor);
 #elif PLATFORM(WIN)

Modified: trunk/Source/WebKit/Shared/WebMouseEvent.cpp (276350 => 276351)


--- trunk/Source/WebKit/Shared/WebMouseEvent.cpp	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/Shared/WebMouseEvent.cpp	2021-04-21 07:38:21 UTC (rev 276351)
@@ -34,9 +34,9 @@
 WebMouseEvent::WebMouseEvent() = default;
 
 #if PLATFORM(MAC)
-WebMouseEvent::WebMouseEvent(Type type, Button button, unsigned short buttons, const IntPoint& positionInView, const IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force, SyntheticClickType syntheticClickType, int eventNumber, int menuType)
+WebMouseEvent::WebMouseEvent(Type type, Button button, unsigned short buttons, const IntPoint& positionInView, const IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force, SyntheticClickType syntheticClickType, int eventNumber, int menuType, GestureWasCancelled gestureWasCancelled)
 #else
-WebMouseEvent::WebMouseEvent(Type type, Button button, unsigned short buttons, const IntPoint& positionInView, const IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force, SyntheticClickType syntheticClickType, WebCore::PointerID pointerId, const String& pointerType)
+WebMouseEvent::WebMouseEvent(Type type, Button button, unsigned short buttons, const IntPoint& positionInView, const IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force, SyntheticClickType syntheticClickType, WebCore::PointerID pointerId, const String& pointerType, GestureWasCancelled gestureWasCancelled)
 #endif
     : WebEvent(type, modifiers, timestamp)
     , m_button(button)
@@ -57,6 +57,7 @@
     , m_pointerId(pointerId)
     , m_pointerType(pointerType)
 #endif
+    , m_gestureWasCancelled(gestureWasCancelled)
 {
     ASSERT(isMouseEventType(type));
 }
@@ -81,6 +82,7 @@
     encoder << m_syntheticClickType;
     encoder << m_pointerId;
     encoder << m_pointerType;
+    encoder << m_gestureWasCancelled;
 }
 
 bool WebMouseEvent::decode(IPC::Decoder& decoder, WebMouseEvent& result)
@@ -119,6 +121,8 @@
         return false;
     if (!decoder.decode(result.m_pointerType))
         return false;
+    if (!decoder.decode(result.m_gestureWasCancelled))
+        return false;
 
     return true;
 }

Modified: trunk/Source/WebKit/Shared/WebMouseEvent.h (276350 => 276351)


--- trunk/Source/WebKit/Shared/WebMouseEvent.h	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/Shared/WebMouseEvent.h	2021-04-21 07:38:21 UTC (rev 276351)
@@ -26,7 +26,7 @@
 
 #pragma once
 
-// FIXME: We should probably move to makeing the WebCore/PlatformFooEvents trivial classes so that
+// FIXME: We should probably move to making the WebCore/PlatformFooEvents trivial classes so that
 // we can use them as the event type.
 
 #include "WebEvent.h"
@@ -36,6 +36,8 @@
 
 namespace WebKit {
 
+enum class GestureWasCancelled : bool { No, Yes };
+
 class WebMouseEvent : public WebEvent {
 public:
     enum Button {
@@ -50,9 +52,9 @@
     WebMouseEvent();
 
 #if PLATFORM(MAC)
-    WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& positionInView, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force, SyntheticClickType = NoTap, int eventNumber = -1, int menuType = 0);
+    WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& positionInView, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force, SyntheticClickType = NoTap, int eventNumber = -1, int menuType = 0, GestureWasCancelled = GestureWasCancelled::No);
 #else
-    WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& positionInView, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force = 0, SyntheticClickType = NoTap, WebCore::PointerID = WebCore::mousePointerID, const String& pointerType = WebCore::mousePointerEventType());
+    WebMouseEvent(Type, Button, unsigned short buttons, const WebCore::IntPoint& positionInView, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier>, WallTime timestamp, double force = 0, SyntheticClickType = NoTap, WebCore::PointerID = WebCore::mousePointerID, const String& pointerType = WebCore::mousePointerEventType(), GestureWasCancelled = GestureWasCancelled::No);
 #endif
 
     Button button() const { return static_cast<Button>(m_button); }
@@ -71,6 +73,7 @@
     SyntheticClickType syntheticClickType() const { return static_cast<SyntheticClickType>(m_syntheticClickType); }
     WebCore::PointerID pointerId() const { return m_pointerId; }
     const String& pointerType() const { return m_pointerType; }
+    GestureWasCancelled gestureWasCancelled() const { return m_gestureWasCancelled; }
 
     void encode(IPC::Encoder&) const;
     static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, WebMouseEvent&);
@@ -94,6 +97,7 @@
     uint32_t m_syntheticClickType { NoTap };
     WebCore::PointerID m_pointerId { WebCore::mousePointerID };
     String m_pointerType { WebCore::mousePointerEventType() };
+    GestureWasCancelled m_gestureWasCancelled { GestureWasCancelled::No };
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm (276350 => 276351)


--- trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/Shared/ios/NativeWebMouseEventIOS.mm	2021-04-21 07:38:21 UTC (rev 276351)
@@ -38,8 +38,8 @@
 {
 }
 
-NativeWebMouseEvent::NativeWebMouseEvent(Type type, Button button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force)
-    : WebMouseEvent(type, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp, force)
+NativeWebMouseEvent::NativeWebMouseEvent(Type type, Button button, unsigned short buttons, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, float deltaX, float deltaY, float deltaZ, int clickCount, OptionSet<Modifier> modifiers, WallTime timestamp, double force, GestureWasCancelled gestureWasCancelled)
+    : WebMouseEvent(type, button, buttons, position, globalPosition, deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp, force, NoTap, WebCore::mousePointerID, WebCore::mousePointerEventType(), gestureWasCancelled)
 {
 }
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.mm (276350 => 276351)


--- trunk/Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.mm	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/UIProcess/ios/WKMouseGestureRecognizer.mm	2021-04-21 07:38:21 UTC (rev 276351)
@@ -119,7 +119,7 @@
     return NO;
 }
 
-- (std::unique_ptr<WebKit::NativeWebMouseEvent>)createMouseEventWithType:(WebKit::WebEvent::Type)type
+- (std::unique_ptr<WebKit::NativeWebMouseEvent>)createMouseEventWithType:(WebKit::WebEvent::Type)type wasCancelled:(BOOL)cancelled
 {
     auto modifiers = webEventModifiersForUIKeyModifierFlags(self.modifierFlags);
     BOOL isRightButton = modifiers.contains(WebKit::WebEvent::Modifier::ControlKey) || (_pressedButtonMask && (*_pressedButtonMask & UIEventButtonMaskSecondary));
@@ -145,7 +145,7 @@
 
     // UITouch's timestamp uses mach_absolute_time as its timebase, same as MonotonicTime.
     auto timestamp = MonotonicTime::fromRawSeconds([_currentTouch timestamp]).approximateWallTime();
-    return WTF::makeUnique<WebKit::NativeWebMouseEvent>(type, button, buttons, point, point, 0, 0, 0, [_currentTouch tapCount], modifiers, timestamp, 0);
+    return WTF::makeUnique<WebKit::NativeWebMouseEvent>(type, button, buttons, point, point, 0, 0, 0, [_currentTouch tapCount], modifiers, timestamp, 0, cancelled ? WebKit::GestureWasCancelled::Yes : WebKit::GestureWasCancelled::No);
 }
 
 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
@@ -153,7 +153,7 @@
     _touching = YES;
     _pressedButtonMask = [event _buttonMask];
 
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseDown];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseDown wasCancelled:NO];
     _lastLocation = [self locationInView:self.view];
 
     self.state = UIGestureRecognizerStateChanged;
@@ -161,7 +161,7 @@
 
 - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 {
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove wasCancelled:NO];
     _lastLocation = [self locationInView:self.view];
 
     self.state = UIGestureRecognizerStateChanged;
@@ -169,7 +169,7 @@
 
 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 {
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseUp];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseUp wasCancelled:NO];
     _lastLocation = [self locationInView:self.view];
 
     _touching = NO;
@@ -180,12 +180,18 @@
 
 - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 {
-    [self touchesEnded:touches withEvent:event];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseUp wasCancelled:YES];
+    _lastLocation = [self locationInView:self.view];
+
+    _touching = NO;
+    _pressedButtonMask = WTF::nullopt;
+
+    self.state = UIGestureRecognizerStateChanged;
 }
 
 - (void)_hoverEntered:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 {
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove wasCancelled:NO];
 
     if (_currentHoverEvent == nil && touches.count == 1 && [event isKindOfClass:NSClassFromString(@"UIHoverEvent")]) {
         _currentHoverEvent = event;
@@ -202,7 +208,7 @@
         return;
     }
 
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove wasCancelled:NO];
     _lastLocation = [self locationInView:self.view];
 
     if (_currentHoverEvent == event && [touches containsObject:_currentTouch.get()])
@@ -211,7 +217,7 @@
 
 - (void)_hoverExited:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
 {
-    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove];
+    _lastEvent = [self createMouseEventWithType:WebKit::WebEvent::MouseMove wasCancelled:NO];
     _lastLocation = [self locationInView:self.view];
 
     if (_currentHoverEvent == event) {

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (276350 => 276351)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-21 07:38:21 UTC (rev 276351)
@@ -2903,6 +2903,8 @@
             return handled;
         }
         case PlatformEvent::MouseReleased:
+            if (mouseEvent.gestureWasCancelled() == GestureWasCancelled::Yes)
+                frame.eventHandler().invalidateClick();
             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
 
         case PlatformEvent::MouseMoved:

Modified: trunk/Tools/ChangeLog (276350 => 276351)


--- trunk/Tools/ChangeLog	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Tools/ChangeLog	2021-04-21 07:38:21 UTC (rev 276351)
@@ -1,3 +1,15 @@
+2021-04-21  Tim Horton  <timothy_hor...@apple.com>
+
+        Long-pressing a data detectors link causes the link to be followed
+        https://bugs.webkit.org/show_bug.cgi?id=224847
+        <rdar://problem/72889738>
+
+        Reviewed by Wenson Hsieh.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm:
+        (TEST):
+        Add tests ensuring that we get a click event for completed touches, and not for cancelled touches.
+
 2021-04-21  Megan Gardner  <megan_gard...@apple.com>
 
         Support scrolling to a selected AppHighlight

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm (276350 => 276351)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/iOSMouseSupport.mm	2021-04-21 07:38:21 UTC (rev 276351)
@@ -234,6 +234,76 @@
     TestWebKitAPI::Util::run(&done);
 }
 
+TEST(iOSMouseSupport, EndedTouchesTriggerClick)
+{
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    [webView synchronouslyLoadHTMLString:@"<script>"
+    "window.wasClicked = false;"
+    "document.documentElement.addEventListener('click', function (e) {"
+    "    window.wasClicked = true;"
+    "});"
+    "</script>"];
+
+    auto contentView = [webView wkContentView];
+    auto gesture = mouseGesture(contentView);
+
+    auto touch = adoptNS([[WKTestingTouch alloc] init]);
+    RetainPtr<NSSet> touchSet = [NSSet setWithObject:touch.get()];
+
+    auto hoverEvent = adoptNS([[NSClassFromString(@"UIHoverEvent") alloc] init]);
+    auto event = adoptNS([[WKTestingEvent alloc] init]);
+
+    [gesture _hoverEntered:touchSet.get() withEvent:hoverEvent.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+    [touch setTapCount:1];
+    [event _setButtonMask:UIEventButtonMaskPrimary];
+    [gesture touchesBegan:touchSet.get() withEvent:event.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+    [gesture touchesEnded:touchSet.get() withEvent:event.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+
+    [webView waitForPendingMouseEvents];
+
+    bool wasClicked = [[webView objectByEvaluatingJavaScript:@"window.wasClicked"] boolValue];
+    EXPECT_TRUE(wasClicked);
+}
+
+TEST(iOSMouseSupport, CancelledTouchesDoNotTriggerClick)
+{
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    [webView synchronouslyLoadHTMLString:@"<script>"
+    "window.wasClicked = false;"
+    "document.documentElement.addEventListener('click', function (e) {"
+    "    window.wasClicked = true;"
+    "});"
+    "</script>"];
+
+    auto contentView = [webView wkContentView];
+    auto gesture = mouseGesture(contentView);
+
+    auto touch = adoptNS([[WKTestingTouch alloc] init]);
+    RetainPtr<NSSet> touchSet = [NSSet setWithObject:touch.get()];
+
+    auto hoverEvent = adoptNS([[NSClassFromString(@"UIHoverEvent") alloc] init]);
+    auto event = adoptNS([[WKTestingEvent alloc] init]);
+
+    [gesture _hoverEntered:touchSet.get() withEvent:hoverEvent.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+    [touch setTapCount:1];
+    [event _setButtonMask:UIEventButtonMaskPrimary];
+    [gesture touchesBegan:touchSet.get() withEvent:event.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+    [gesture touchesCancelled:touchSet.get() withEvent:event.get()];
+    [contentView mouseGestureRecognizerChanged:gesture];
+
+    [webView waitForPendingMouseEvents];
+
+    bool wasClicked = [[webView objectByEvaluatingJavaScript:@"window.wasClicked"] boolValue];
+    EXPECT_FALSE(wasClicked);
+}
+
 #if ENABLE(IOS_TOUCH_EVENTS)
 
 TEST(iOSMouseSupport, WebsiteMouseEventPolicies)

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (276350 => 276351)


--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2021-04-21 07:38:21 UTC (rev 276351)
@@ -97,6 +97,7 @@
 - (void)addToTestWindow;
 - (BOOL)selectionRangeHasStartOffset:(int)start endOffset:(int)end;
 - (void)clickOnElementID:(NSString *)elementID;
+- (void)waitForPendingMouseEvents;
 @end
 
 #if PLATFORM(IOS_FAMILY)
@@ -135,7 +136,6 @@
 - (void)sendClickAtPoint:(NSPoint)pointInWindow;
 - (NSWindow *)hostWindow;
 - (void)typeCharacter:(char)character;
-- (void)waitForPendingMouseEvents;
 - (void)setEventTimestampOffset:(NSTimeInterval)offset;
 @property (nonatomic, readonly) NSTimeInterval eventTimestamp;
 @end

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (276350 => 276351)


--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm	2021-04-21 07:33:17 UTC (rev 276350)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm	2021-04-21 07:38:21 UTC (rev 276351)
@@ -636,6 +636,15 @@
     [self evaluateJavaScript:[NSString stringWithFormat:@"document.getElementById('%@').click();", elementID] completionHandler:nil];
 }
 
+- (void)waitForPendingMouseEvents
+{
+    __block bool doneProcessingMouseEvents = false;
+    [self _doAfterProcessingAllPendingMouseEvents:^{
+        doneProcessingMouseEvents = true;
+    }];
+    TestWebKitAPI::Util::run(&doneProcessingMouseEvents);
+}
+
 #if PLATFORM(IOS_FAMILY)
 
 - (void)didStartFormControlInteraction
@@ -840,15 +849,6 @@
     [self keyUp:[NSEvent keyEventWithType:keyUpEventType location:NSZeroPoint modifierFlags:0 timestamp:self.eventTimestamp windowNumber:[_hostWindow windowNumber] context:nil characters:characterAsString charactersIgnoringModifiers:characterAsString isARepeat:NO keyCode:character]];
 }
 
-- (void)waitForPendingMouseEvents
-{
-    __block bool doneProcessingMouseEvents = false;
-    [self _doAfterProcessingAllPendingMouseEvents:^{
-        doneProcessingMouseEvents = true;
-    }];
-    TestWebKitAPI::Util::run(&doneProcessingMouseEvents);
-}
-
 @end
 
 #endif // PLATFORM(MAC)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to