Title: [277316] trunk
Revision
277316
Author
[email protected]
Date
2021-05-10 21:31:16 -0700 (Mon, 10 May 2021)

Log Message

[macOS] Allow immediate action gestures to begin when force clicking text inside image overlays
https://bugs.webkit.org/show_bug.cgi?id=225600
<rdar://problem/77792365>

Reviewed by Tim Horton.

Source/WebCore:

Allow immediate action hit-testing to descend into image overlay content. Currently, this uses the
`DisallowsUserAgentShadowContent` hit-testing option, causing us to ignore image overlays (which exist inside
the UA shadow root). To fix this, we introduce a `DisallowsUserAgentShadowContentExceptForImageOverlays` option
that behaves like the existing `DisallowsUserAgentShadowContent` option, with the exception that we allow hit-
testing to pierce the UA shadow root to find nodes inside image overlays.

Tests:  ImmediateActionTests.ImmediateActionOverText
        ImmediateActionTests.ImmediateActionOverBody
        ImmediateActionTests.ImmediateActionOverImageOverlay

* page/EventHandler.cpp:
(WebCore::EventHandler::hitTestResultAtPoint const):
* rendering/HitTestRequest.h:

Add support for the new hit-test option, which allows hit-testing to descend into image overlays (and is
intended to be mutually exclusive with the existing `DisallowsUserAgentShadowContent` option). Specifying both
options will lead to an assertion on debug builds, and `DisallowsUserAgentShadowContent` takes precedence on
release builds.

(WebCore::HitTestRequest::disallowsUserAgentShadowContentExceptForImageOverlays const):
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::addNodeToListBasedTestResultCommon):

Source/WebCore/PAL:

* pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h:

Source/WebKit:

Adopt the new hit-test option. See WebCore/ChangeLog for more details.

* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::performImmediateActionHitTestAtLocation):
(WebKit::WebPage::lookupTextAtLocation):

Tools:

Add new API tests to exercise these changes by grabbing the immediate action `NSGestureRecognizer` from
`WKWebView` and calling into its delegate. This patch adds two basic immediate action tests by simulating the
immediate action over text and the body element, and includes a third test that installs an image overlay using
an injected `internals` object, and verifies that the immediate action in an image overlay matches that of
regular text on the page.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/ImmediateActionTests.mm: Added.
(swizzledImmediateActionLocationInView):
(-[WKWebViewForTestingImmediateActions _immediateActionAnimationControllerForHitTestResult:withType:userData:]):
(-[WKWebViewForTestingImmediateActions immediateActionGesture]):
(-[WKWebViewForTestingImmediateActions simulateImmediateAction:]):
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277315 => 277316)


--- trunk/Source/WebCore/ChangeLog	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/ChangeLog	2021-05-11 04:31:16 UTC (rev 277316)
@@ -1,3 +1,34 @@
+2021-05-10  Wenson Hsieh  <[email protected]>
+
+        [macOS] Allow immediate action gestures to begin when force clicking text inside image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225600
+        <rdar://problem/77792365>
+
+        Reviewed by Tim Horton.
+
+        Allow immediate action hit-testing to descend into image overlay content. Currently, this uses the
+        `DisallowsUserAgentShadowContent` hit-testing option, causing us to ignore image overlays (which exist inside
+        the UA shadow root). To fix this, we introduce a `DisallowsUserAgentShadowContentExceptForImageOverlays` option
+        that behaves like the existing `DisallowsUserAgentShadowContent` option, with the exception that we allow hit-
+        testing to pierce the UA shadow root to find nodes inside image overlays.
+
+        Tests:  ImmediateActionTests.ImmediateActionOverText
+                ImmediateActionTests.ImmediateActionOverBody
+                ImmediateActionTests.ImmediateActionOverImageOverlay
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::hitTestResultAtPoint const):
+        * rendering/HitTestRequest.h:
+
+        Add support for the new hit-test option, which allows hit-testing to descend into image overlays (and is
+        intended to be mutually exclusive with the existing `DisallowsUserAgentShadowContent` option). Specifying both
+        options will lead to an assertion on debug builds, and `DisallowsUserAgentShadowContent` takes precedence on
+        release builds.
+
+        (WebCore::HitTestRequest::disallowsUserAgentShadowContentExceptForImageOverlays const):
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestResult::addNodeToListBasedTestResultCommon):
+
 2021-05-10  Sam Weinig  <[email protected]>
 
         Use PixelBuffer rather than ImageData in platform/ code to fix layering violation

Modified: trunk/Source/WebCore/PAL/ChangeLog (277315 => 277316)


--- trunk/Source/WebCore/PAL/ChangeLog	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/PAL/ChangeLog	2021-05-11 04:31:16 UTC (rev 277316)
@@ -1,3 +1,13 @@
+2021-05-10  Wenson Hsieh  <[email protected]>
+
+        [macOS] Allow immediate action gestures to begin when force clicking text inside image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225600
+        <rdar://problem/77792365>
+
+        Reviewed by Tim Horton.
+
+        * pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h:
+
 2021-04-29  Jean-Yves Avenard  <[email protected]>
 
         Adopt AVSampleBufferAudioRendererWasFlushedAutomaticallyNotification

Modified: trunk/Source/WebCore/PAL/pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h (277315 => 277316)


--- trunk/Source/WebCore/PAL/pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/PAL/pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h	2021-05-11 04:31:16 UTC (rev 277316)
@@ -56,6 +56,7 @@
 
 @interface NSImmediateActionGestureRecognizer : NSGestureRecognizer
 
+@property (weak) id <NSImmediateActionGestureRecognizerDelegate> delegate;
 @property (strong) id<NSImmediateActionAnimationController> animationController;
 @property (readonly) CGFloat animationProgress;
 

Modified: trunk/Source/WebCore/page/EventHandler.cpp (277315 => 277316)


--- trunk/Source/WebCore/page/EventHandler.cpp	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2021-05-11 04:31:16 UTC (rev 277316)
@@ -1190,7 +1190,9 @@
     if (!request.readOnly())
         m_frame.document()->updateHoverActiveState(request, result.targetElement());
 
-    if (request.disallowsUserAgentShadowContent())
+    auto innerNode = makeRefPtr(result.innerNode());
+    if (request.disallowsUserAgentShadowContent()
+        || (request.disallowsUserAgentShadowContentExceptForImageOverlays() && innerNode && !HTMLElement::isInsideImageOverlay(*innerNode)))
         result.setToNonUserAgentShadowAncestor();
 
     return result;

Modified: trunk/Source/WebCore/rendering/HitTestRequest.h (277315 => 277316)


--- trunk/Source/WebCore/rendering/HitTestRequest.h	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/rendering/HitTestRequest.h	2021-05-11 04:31:16 UTC (rev 277316)
@@ -39,20 +39,22 @@
         SVGClipContent = 1 << 6,
         TouchEvent = 1 << 7,
         DisallowUserAgentShadowContent = 1 << 8,
-        AllowFrameScrollbars = 1 << 9,
-        AllowChildFrameContent = 1 << 10,
-        AllowVisibleChildFrameContentOnly = 1 << 11,
-        ChildFrameHitTest = 1 << 12,
-        AccessibilityHitTest = 1 << 13,
+        DisallowUserAgentShadowContentExceptForImageOverlays = 1 << 9,
+        AllowFrameScrollbars = 1 << 10,
+        AllowChildFrameContent = 1 << 11,
+        AllowVisibleChildFrameContentOnly = 1 << 12,
+        ChildFrameHitTest = 1 << 13,
+        AccessibilityHitTest = 1 << 14,
         // Collect a list of nodes instead of just one. Used for elementsFromPoint and rect-based tests.
-        CollectMultipleElements = 1 << 14,
+        CollectMultipleElements = 1 << 15,
         // When using list-based testing, continue hit testing even after a hit has been found.
-        IncludeAllElementsUnderPoint = 1 << 15,
+        IncludeAllElementsUnderPoint = 1 << 16,
     };
 
     HitTestRequest(OptionSet<Type> type = { Type::ReadOnly, Type::Active, Type::DisallowUserAgentShadowContent })
         : m_type { type }
     {
+        ASSERT(!type.containsAll({ Type::DisallowUserAgentShadowContentExceptForImageOverlays, Type::DisallowUserAgentShadowContent }));
         ASSERT_IMPLIES(type.contains(Type::IncludeAllElementsUnderPoint), type.contains(Type::CollectMultipleElements));
     }
 
@@ -66,6 +68,7 @@
     bool touchEvent() const { return m_type.contains(Type::TouchEvent); }
     bool mouseEvent() const { return !touchEvent(); }
     bool disallowsUserAgentShadowContent() const { return m_type.contains(Type::DisallowUserAgentShadowContent); }
+    bool disallowsUserAgentShadowContentExceptForImageOverlays() const { return m_type.contains(Type::DisallowUserAgentShadowContentExceptForImageOverlays); }
     bool allowsFrameScrollbars() const { return m_type.contains(Type::AllowFrameScrollbars); }
     bool allowsChildFrameContent() const { return m_type.contains(Type::AllowChildFrameContent); }
     bool allowsVisibleChildFrameContent() const { return m_type.contains(Type::AllowVisibleChildFrameContentOnly); }

Modified: trunk/Source/WebCore/rendering/HitTestResult.cpp (277315 => 277316)


--- trunk/Source/WebCore/rendering/HitTestResult.cpp	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebCore/rendering/HitTestResult.cpp	2021-05-11 04:31:16 UTC (rev 277316)
@@ -656,7 +656,8 @@
     if (!node)
         return HitTestProgress::Continue;
 
-    if (request.disallowsUserAgentShadowContent() && node->isInUserAgentShadowTree())
+    if ((request.disallowsUserAgentShadowContent() && node->isInUserAgentShadowTree())
+        || (request.disallowsUserAgentShadowContentExceptForImageOverlays() && !HTMLElement::isInsideImageOverlay(*node) && node->isInUserAgentShadowTree()))
         node = node->document().ancestorNodeInThisScope(node);
 
     mutableListBasedTestResult().add(*node);

Modified: trunk/Source/WebKit/ChangeLog (277315 => 277316)


--- trunk/Source/WebKit/ChangeLog	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebKit/ChangeLog	2021-05-11 04:31:16 UTC (rev 277316)
@@ -1,3 +1,17 @@
+2021-05-10  Wenson Hsieh  <[email protected]>
+
+        [macOS] Allow immediate action gestures to begin when force clicking text inside image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225600
+        <rdar://problem/77792365>
+
+        Reviewed by Tim Horton.
+
+        Adopt the new hit-test option. See WebCore/ChangeLog for more details.
+
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::performImmediateActionHitTestAtLocation):
+        (WebKit::WebPage::lookupTextAtLocation):
+
 2021-05-10  Sam Weinig  <[email protected]>
 
         Use PixelBuffer rather than ImageData in platform/ code to fix layering violation

Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (277315 => 277316)


--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm	2021-05-11 04:31:16 UTC (rev 277316)
@@ -858,9 +858,13 @@
         return;
     }
 
-    IntPoint locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCoordinates));
-    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
-    HitTestResult hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates, hitType);
+    auto locationInContentCoordinates = mainFrame.view()->rootViewToContents(roundedIntPoint(locationInViewCoordinates));
+    auto hitTestResult = mainFrame.eventHandler().hitTestResultAtPoint(locationInContentCoordinates, {
+        HitTestRequest::Type::ReadOnly,
+        HitTestRequest::Type::Active,
+        HitTestRequest::Type::DisallowUserAgentShadowContentExceptForImageOverlays,
+        HitTestRequest::Type::AllowChildFrameContent,
+    });
 
     bool immediateActionHitTestPreventsDefault = false;
     Element* element = hitTestResult.targetElement();
@@ -958,10 +962,12 @@
     if (!mainFrame.view() || !mainFrame.view()->renderView())
         return WTF::nullopt;
 
-    auto point = roundedIntPoint(locationInViewCoordinates);
-    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
-    auto result = mainFrame.eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(point), hitType);
-    return DictionaryLookup::rangeAtHitTestResult(result);
+    return DictionaryLookup::rangeAtHitTestResult(mainFrame.eventHandler().hitTestResultAtPoint(m_page->mainFrame().view()->windowToContents(roundedIntPoint(locationInViewCoordinates)), {
+        HitTestRequest::Type::ReadOnly,
+        HitTestRequest::Type::Active,
+        HitTestRequest::Type::DisallowUserAgentShadowContentExceptForImageOverlays,
+        HitTestRequest::Type::AllowChildFrameContent,
+    }));
 }
 
 void WebPage::immediateActionDidUpdate()

Modified: trunk/Tools/ChangeLog (277315 => 277316)


--- trunk/Tools/ChangeLog	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Tools/ChangeLog	2021-05-11 04:31:16 UTC (rev 277316)
@@ -1,3 +1,25 @@
+2021-05-10  Wenson Hsieh  <[email protected]>
+
+        [macOS] Allow immediate action gestures to begin when force clicking text inside image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225600
+        <rdar://problem/77792365>
+
+        Reviewed by Tim Horton.
+
+        Add new API tests to exercise these changes by grabbing the immediate action `NSGestureRecognizer` from
+        `WKWebView` and calling into its delegate. This patch adds two basic immediate action tests by simulating the
+        immediate action over text and the body element, and includes a third test that installs an image overlay using
+        an injected `internals` object, and verifies that the immediate action in an image overlay matches that of
+        regular text on the page.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/mac/ImmediateActionTests.mm: Added.
+        (swizzledImmediateActionLocationInView):
+        (-[WKWebViewForTestingImmediateActions _immediateActionAnimationControllerForHitTestResult:withType:userData:]):
+        (-[WKWebViewForTestingImmediateActions immediateActionGesture]):
+        (-[WKWebViewForTestingImmediateActions simulateImmediateAction:]):
+        (TestWebKitAPI::TEST):
+
 2021-05-10  Kate Cheney  <[email protected]>
 
         Preflight requests not properly attributed as app-bound

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (277315 => 277316)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-11 02:14:57 UTC (rev 277315)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-11 04:31:16 UTC (rev 277316)
@@ -868,8 +868,8 @@
 		93F56DA71E5F9174003EDE84 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */; };
 		93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */; };
 		93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; };
+		93FCDB34263631560046DD7D /* SortedArrayMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93FCDB33263631560046DD7D /* SortedArrayMap.cpp */; };
 		95095F20262FFFA50000D920 /* SampledPageTopColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95095F1F262FFFA50000D920 /* SampledPageTopColor.mm */; };
-		93FCDB34263631560046DD7D /* SortedArrayMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93FCDB33263631560046DD7D /* SortedArrayMap.cpp */; };
 		950E4CC1252E75240071659F /* iOSStylusSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = 950E4CC0252E75230071659F /* iOSStylusSupport.mm */; };
 		953ABB3525C0D682004C8B73 /* PageExtendedBackgroundColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */; };
 		95A524952581A10D00461FE9 /* WKWebViewThemeColor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */; };
@@ -1179,6 +1179,7 @@
 		F442851D2140DF2900CCDA22 /* NSFontPanelTesting.mm in Sources */ = {isa = PBXBuildFile; fileRef = F442851C2140DF2900CCDA22 /* NSFontPanelTesting.mm */; };
 		F4451C761EB8FD890020C5DA /* two-paragraph-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4451C751EB8FD7C0020C5DA /* two-paragraph-contenteditable.html */; };
 		F44A531121B8990300DBB99C /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44A531021B8976900DBB99C /* InstanceMethodSwizzler.mm */; };
+		F44A9AF72649BBDD00E7CB16 /* ImmediateActionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */; };
 		F44C79FF20F9E8710014478C /* ParserYieldTokenTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44C79FE20F9E8710014478C /* ParserYieldTokenTests.mm */; };
 		F44C7A0020F9EEBF0014478C /* ParserYieldTokenPlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = F44C79FB20F9E50C0014478C /* ParserYieldTokenPlugIn.mm */; };
 		F44C7A0520FAAE3C0014478C /* text-with-deferred-script.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F44C7A0420FAAE320014478C /* text-with-deferred-script.html */; };
@@ -2565,8 +2566,8 @@
 		93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewSnapshot.mm; sourceTree = "<group>"; };
 		93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames.cpp; sourceTree = "<group>"; };
 		93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp; sourceTree = "<group>"; };
+		93FCDB33263631560046DD7D /* SortedArrayMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SortedArrayMap.cpp; sourceTree = "<group>"; };
 		95095F1F262FFFA50000D920 /* SampledPageTopColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SampledPageTopColor.mm; sourceTree = "<group>"; };
-		93FCDB33263631560046DD7D /* SortedArrayMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SortedArrayMap.cpp; sourceTree = "<group>"; };
 		950E4CC0252E75230071659F /* iOSStylusSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSStylusSupport.mm; sourceTree = "<group>"; };
 		953ABB3425C0D681004C8B73 /* PageExtendedBackgroundColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageExtendedBackgroundColor.mm; sourceTree = "<group>"; };
 		95A524942581A10D00461FE9 /* WKWebViewThemeColor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewThemeColor.mm; sourceTree = "<group>"; };
@@ -2997,6 +2998,8 @@
 		F44A530E21B8976900DBB99C /* ClassMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ClassMethodSwizzler.mm; path = ../TestRunnerShared/cocoa/ClassMethodSwizzler.mm; sourceTree = "<group>"; };
 		F44A530F21B8976900DBB99C /* ClassMethodSwizzler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClassMethodSwizzler.h; path = ../TestRunnerShared/cocoa/ClassMethodSwizzler.h; sourceTree = "<group>"; };
 		F44A531021B8976900DBB99C /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InstanceMethodSwizzler.mm; path = ../TestRunnerShared/cocoa/InstanceMethodSwizzler.mm; sourceTree = "<group>"; };
+		F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImmediateActionTests.h; sourceTree = "<group>"; };
+		F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImmediateActionTests.mm; sourceTree = "<group>"; };
 		F44C79FB20F9E50C0014478C /* ParserYieldTokenPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ParserYieldTokenPlugIn.mm; sourceTree = "<group>"; };
 		F44C79FD20F9E8710014478C /* ParserYieldTokenTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParserYieldTokenTests.h; sourceTree = "<group>"; };
 		F44C79FE20F9E8710014478C /* ParserYieldTokenTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ParserYieldTokenTests.mm; sourceTree = "<group>"; };
@@ -4680,6 +4683,8 @@
 				51EB125824C68589000CB030 /* HIDGamepads.mm */,
 				9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */,
 				9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */,
+				F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */,
+				F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */,
 				C507E8A614C6545B005D6B3B /* InspectorBar.mm */,
 				57F10D921C7E7B3800ECDF30 /* IsNavigationActionTrusted.mm */,
 				51820A4C22F4EE7700DF0A01 /* _javascript_URLNavigation.mm */,
@@ -5467,6 +5472,7 @@
 				510477781D29923B009747EB /* IDBDeleteRecovery.mm in Sources */,
 				5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */,
 				93BCBC8323CC6F2A00CA2221 /* IDBObjectStoreInfoUpgradeToV2.mm in Sources */,
+				F44A9AF72649BBDD00E7CB16 /* ImmediateActionTests.mm in Sources */,
 				49AEEF6D2407359D00C87E4C /* InAppBrowserPrivacy.mm in Sources */,
 				51A587861D273AA9004BA9AF /* IndexedDBDatabaseProcessKill.mm in Sources */,
 				CAB0FF5522332C57006CA5B0 /* IndexedDBFileName.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/mac/ImmediateActionTests.mm (0 => 277316)


--- trunk/Tools/TestWebKitAPI/Tests/mac/ImmediateActionTests.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/ImmediateActionTests.mm	2021-05-11 04:31:16 UTC (rev 277316)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "Test.h"
+
+#if PLATFORM(MAC)
+
+#import "InstanceMethodSwizzler.h"
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import "WKWebViewConfigurationExtras.h"
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKHitTestResult.h>
+#import <pal/spi/mac/NSImmediateActionGestureRecognizerSPI.h>
+#import <wtf/RetainPtr.h>
+
+static NSPoint gSwizzledImmediateActionLocation = NSZeroPoint;
+static NSPoint swizzledImmediateActionLocationInView(id, SEL, NSView *)
+{
+    return gSwizzledImmediateActionLocation;
+}
+
+using ImmediateActionHitTestResult = std::pair<RetainPtr<_WKHitTestResult>, _WKImmediateActionType>;
+
+@interface WKWebViewForTestingImmediateActions : TestWKWebView
+
+@property (nonatomic, readonly) NSImmediateActionGestureRecognizer *immediateActionGesture;
+
+- (ImmediateActionHitTestResult)simulateImmediateAction:(NSPoint)location;
+
+@end
+
+@implementation WKWebViewForTestingImmediateActions {
+    bool _hasReturnedImmediateActionController;
+    RetainPtr<_WKHitTestResult> _hitTestResult;
+    _WKImmediateActionType _actionType;
+}
+
+- (id)_immediateActionAnimationControllerForHitTestResult:(_WKHitTestResult *)hitTestResult withType:(_WKImmediateActionType)type userData:(id <NSSecureCoding>)userData
+{
+    _hasReturnedImmediateActionController = true;
+    _hitTestResult = hitTestResult;
+    _actionType = type;
+    return [super _immediateActionAnimationControllerForHitTestResult:hitTestResult withType:type userData:userData];
+}
+
+- (NSImmediateActionGestureRecognizer *)immediateActionGesture
+{
+    for (NSGestureRecognizer *gesture in [self gestureRecognizers]) {
+        if ([gesture isKindOfClass:NSImmediateActionGestureRecognizer.class])
+            return static_cast<NSImmediateActionGestureRecognizer *>(gesture);
+    }
+    return nil;
+}
+
+- (ImmediateActionHitTestResult)simulateImmediateAction:(NSPoint)location
+{
+    auto immediateActionGesture = self.immediateActionGesture;
+    if (!immediateActionGesture.delegate)
+        return ImmediateActionHitTestResult { nil, _WKImmediateActionNone };
+
+    _hasReturnedImmediateActionController = false;
+
+    InstanceMethodSwizzler swizzleLocationInView {
+        NSImmediateActionGestureRecognizer.class,
+        @selector(locationInView:),
+        reinterpret_cast<IMP>(swizzledImmediateActionLocationInView),
+    };
+
+    gSwizzledImmediateActionLocation = location;
+    [immediateActionGesture.delegate immediateActionRecognizerWillPrepare:immediateActionGesture];
+
+    TestWebKitAPI::Util::run(&_hasReturnedImmediateActionController);
+
+    _hasReturnedImmediateActionController = false;
+    return { std::exchange(_hitTestResult, nil), std::exchange(_actionType, _WKImmediateActionNone) };
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+TEST(ImmediateActionTests, ImmediateActionOverText)
+{
+    auto webView = adoptNS([[WKWebViewForTestingImmediateActions alloc] initWithFrame:NSMakeRect(0, 0, 500, 500)]);
+    [webView synchronouslyLoadHTMLString:@"<div style='font-size: 32px;'>Foobar</div>"];
+
+    auto [hitTestResult, actionType] = [webView simulateImmediateAction:NSMakePoint(16, 16)];
+    EXPECT_NOT_NULL([webView immediateActionGesture].animationController);
+    EXPECT_EQ(actionType, _WKImmediateActionLookupText);
+    EXPECT_WK_STREQ([hitTestResult lookupText], "Foobar");
+}
+
+TEST(ImmediateActionTests, ImmediateActionOverBody)
+{
+    auto webView = adoptNS([[WKWebViewForTestingImmediateActions alloc] initWithFrame:NSMakeRect(0, 0, 500, 500)]);
+    [webView synchronouslyLoadHTMLString:@"<div style='font-size: 32px;'>Foobar</div>"];
+
+    auto [hitTestResult, actionType] = [webView simulateImmediateAction:NSMakePoint(490, 490)];
+    EXPECT_NULL([webView immediateActionGesture].animationController);
+    EXPECT_EQ(actionType, _WKImmediateActionNone);
+    EXPECT_EQ([hitTestResult lookupText].length, 0U);
+}
+
+#if ENABLE(IMAGE_EXTRACTION)
+
+TEST(ImmediateActionTests, ImmediateActionOverImageOverlay)
+{
+    auto configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    auto webView = adoptNS([[WKWebViewForTestingImmediateActions alloc] initWithFrame:NSMakeRect(0, 0, 500, 500) configuration:configuration]);
+    [webView synchronouslyLoadTestPageNamed:@"simple-image-overlay"];
+
+    auto [hitTestResult, actionType] = [webView simulateImmediateAction:NSMakePoint(50, 50)];
+    EXPECT_NOT_NULL([webView immediateActionGesture].animationController);
+    EXPECT_EQ(actionType, _WKImmediateActionLookupText);
+    EXPECT_WK_STREQ([hitTestResult lookupText], "foobar");
+}
+
+#endif // ENABLE(IMAGE_EXTRACTION)
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(MAC)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to