Title: [278254] trunk
Revision
278254
Author
[email protected]
Date
2021-05-30 12:18:56 -0700 (Sun, 30 May 2021)

Log Message

[iOS] UI process crashes when deallocating WKWebView in a script message handler during an active touch event
https://bugs.webkit.org/show_bug.cgi?id=226426
rdar://75425319

Reviewed by Darin Adler.

Source/WebKit:

It's possible for the UI process to crash upon being notified that asynchronous, active touch events have been
handled in the web process via the async IPC replay block in `WebPageProxy::handlePreventableTouchEvent()`. This
happens if the client posts a message from the web process to UI process while handling an active touch event
and deallocates the WKWebView currently handling the touch event in the script message handler.

This is because the async replay block inside `WebPageProxy::handlePreventableTouchEvent()` strongly captures a
reference to the `WebPageProxy`, thus keeping it alive; however, the `WebPageProxy`'s weak pointer to the page
client is nulled out, which causes `WebPageProxy::pageClient()` to crash with a null dereference.

To fix this, we weakly capture `WebPageProxy` instead and return early if it has already been destroyed by the
time we process the completion handler, and also add a null check for `m_pageClient` before attempting to call
into it. Note that it's unnecessary to call into `doneDeferringTouch(Start|End)` to unblock any deferred
gestures here, because the process of destroying the content view will call `-cleanUpInteraction` and remove all
deferring gestures from the view, regardless of whether they're still in Possible state.

Test: TouchEventTests.DestroyWebViewWhileHandlingTouchEnd

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handlePreventableTouchEvent):

Tools:

Add a new API test that exercises the crash.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/ios/TouchEventTests.mm: Added.
(-[TouchEventScriptMessageHandler userContentController:didReceiveScriptMessage:]):
(-[WKWebView touchEventGestureRecognizer]):
(TestWebKitAPI::updateSimulatedTouchEvent):
(TestWebKitAPI::simulatedTouchEvent):
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/ios/active-touch-events.html: Added.
* TestWebKitAPI/cocoa/TestWKWebView.h:
* TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[WKWebView textInputContentView]):
(-[TestWKWebView textInputContentView]): Deleted.
* TestWebKitAPI/ios/UIKitSPI.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (278253 => 278254)


--- trunk/Source/WebKit/ChangeLog	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Source/WebKit/ChangeLog	2021-05-30 19:18:56 UTC (rev 278254)
@@ -1,3 +1,31 @@
+2021-05-30  Wenson Hsieh  <[email protected]>
+
+        [iOS] UI process crashes when deallocating WKWebView in a script message handler during an active touch event
+        https://bugs.webkit.org/show_bug.cgi?id=226426
+        rdar://75425319
+
+        Reviewed by Darin Adler.
+
+        It's possible for the UI process to crash upon being notified that asynchronous, active touch events have been
+        handled in the web process via the async IPC replay block in `WebPageProxy::handlePreventableTouchEvent()`. This
+        happens if the client posts a message from the web process to UI process while handling an active touch event
+        and deallocates the WKWebView currently handling the touch event in the script message handler.
+
+        This is because the async replay block inside `WebPageProxy::handlePreventableTouchEvent()` strongly captures a
+        reference to the `WebPageProxy`, thus keeping it alive; however, the `WebPageProxy`'s weak pointer to the page
+        client is nulled out, which causes `WebPageProxy::pageClient()` to crash with a null dereference.
+
+        To fix this, we weakly capture `WebPageProxy` instead and return early if it has already been destroyed by the
+        time we process the completion handler, and also add a null check for `m_pageClient` before attempting to call
+        into it. Note that it's unnecessary to call into `doneDeferringTouch(Start|End)` to unblock any deferred
+        gestures here, because the process of destroying the content view will call `-cleanUpInteraction` and remove all
+        deferring gestures from the view, regardless of whether they're still in Possible state.
+
+        Test: TouchEventTests.DestroyWebViewWhileHandlingTouchEnd
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handlePreventableTouchEvent):
+
 2021-05-30  Darin Adler  <[email protected]>
 
         Remove WTF::Optional synonym for std::optional, using that class template directly instead

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (278253 => 278254)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-05-30 19:18:56 UTC (rev 278254)
@@ -3118,7 +3118,11 @@
         if (isTouchEnd)
             ++m_handlingPreventableTouchEndCount;
 
-        sendWithAsyncReply(Messages::EventDispatcher::TouchEvent(m_webPageID, event), [this, protectedThis = makeRef(*this), event] (bool handled) {
+        sendWithAsyncReply(Messages::EventDispatcher::TouchEvent(m_webPageID, event), [this, weakThis = makeWeakPtr(*this), event] (bool handled) {
+            auto protectedThis = makeRefPtr(weakThis.get());
+            if (!protectedThis)
+                return;
+
             bool didFinishDeferringTouchStart = false;
             ASSERT_IMPLIES(event.type() == WebEvent::TouchStart, m_handlingPreventableTouchStartCount);
             if (event.type() == WebEvent::TouchStart && m_handlingPreventableTouchStartCount)
@@ -3134,6 +3138,9 @@
                 m_handledSynchronousTouchEventWhileDispatchingPreventableTouchStart = false;
 
             didReceiveEvent(event.type(), handledOrFailedWithError);
+            if (!m_pageClient)
+                return;
+
             pageClient().doneWithTouchEvent(event, handledOrFailedWithError);
 
             if (didFinishDeferringTouchStart)

Modified: trunk/Tools/ChangeLog (278253 => 278254)


--- trunk/Tools/ChangeLog	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Tools/ChangeLog	2021-05-30 19:18:56 UTC (rev 278254)
@@ -1,3 +1,27 @@
+2021-05-30  Wenson Hsieh  <[email protected]>
+
+        [iOS] UI process crashes when deallocating WKWebView in a script message handler during an active touch event
+        https://bugs.webkit.org/show_bug.cgi?id=226426
+        rdar://75425319
+
+        Reviewed by Darin Adler.
+
+        Add a new API test that exercises the crash.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/ios/TouchEventTests.mm: Added.
+        (-[TouchEventScriptMessageHandler userContentController:didReceiveScriptMessage:]):
+        (-[WKWebView touchEventGestureRecognizer]):
+        (TestWebKitAPI::updateSimulatedTouchEvent):
+        (TestWebKitAPI::simulatedTouchEvent):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/ios/active-touch-events.html: Added.
+        * TestWebKitAPI/cocoa/TestWKWebView.h:
+        * TestWebKitAPI/cocoa/TestWKWebView.mm:
+        (-[WKWebView textInputContentView]):
+        (-[TestWKWebView textInputContentView]): Deleted.
+        * TestWebKitAPI/ios/UIKitSPI.h:
+
 2021-05-30  Darin Adler  <[email protected]>
 
         Remove WTF::Optional synonym for std::optional, using that class template directly instead

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (278253 => 278254)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-05-30 19:18:56 UTC (rev 278254)
@@ -1229,6 +1229,8 @@
 		F49992C6248DABFD00034167 /* overflow-hidden.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F49992C5248DABE400034167 /* overflow-hidden.html */; };
 		F4A32EC41F05F3850047C544 /* dragstart-change-selection-offscreen.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */; };
 		F4A32ECB1F0643370047C544 /* contenteditable-in-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */; };
+		F4A7CE782662D6E800228685 /* TouchEventTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4A7CE772662D6E800228685 /* TouchEventTests.mm */; };
+		F4A7CE7A2662D86C00228685 /* active-touch-events.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A7CE792662D83E00228685 /* active-touch-events.html */; };
 		F4A9202F1FEE34E900F59590 /* apple-data-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A9202E1FEE34C800F59590 /* apple-data-url.html */; };
 		F4AB578A1F65165400DB0DA1 /* custom-draggable-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */; };
 		F4AD183825ED791500B1A19F /* FloatQuadTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4AD183725ED791500B1A19F /* FloatQuadTests.cpp */; };
@@ -1353,6 +1355,7 @@
 				1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
 				55A81800218102210004A39A /* 400x400-green.png in Copy Resources */,
 				379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
+				F4A7CE7A2662D86C00228685 /* active-touch-events.html in Copy Resources */,
 				725C3EF322058A5B007C36FC /* AdditionalSupportedImageTypes.html in Copy Resources */,
 				1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */,
 				46C1EA9825758820005E409E /* alert.html in Copy Resources */,
@@ -3069,6 +3072,8 @@
 		F49992C5248DABE400034167 /* overflow-hidden.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "overflow-hidden.html"; sourceTree = "<group>"; };
 		F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "dragstart-change-selection-offscreen.html"; sourceTree = "<group>"; };
 		F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "contenteditable-in-iframe.html"; sourceTree = "<group>"; };
+		F4A7CE772662D6E800228685 /* TouchEventTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TouchEventTests.mm; sourceTree = "<group>"; };
+		F4A7CE792662D83E00228685 /* active-touch-events.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "active-touch-events.html"; sourceTree = "<group>"; };
 		F4A9202E1FEE34C800F59590 /* apple-data-url.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "apple-data-url.html"; sourceTree = "<group>"; };
 		F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "custom-draggable-div.html"; sourceTree = "<group>"; };
 		F4AD183725ED791500B1A19F /* FloatQuadTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FloatQuadTests.cpp; sourceTree = "<group>"; };
@@ -3831,6 +3836,7 @@
 				F45033F4206BEC95009351CE /* TextAutosizingBoost.mm */,
 				F494B369263120780060A310 /* TextServicesTests.mm */,
 				1C24DEEC263001DE00450D07 /* TextStyleFontSize.mm */,
+				F4A7CE772662D6E800228685 /* TouchEventTests.mm */,
 				F460F6742614DE2F0064F2B6 /* UIFocusTests.mm */,
 				F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */,
 				F402F56B23ECC2FB00865549 /* UIWKInteractionViewProtocol.mm */,
@@ -4184,6 +4190,7 @@
 		A1C4FB6F1BACCEFA003742D0 /* Resources */ = {
 			isa = PBXGroup;
 			children = (
+				F4A7CE792662D83E00228685 /* active-touch-events.html */,
 				0F16BED72304A1D100B4A167 /* composited.html */,
 				CEDA12402437C9EA00C28A9E /* editable-region-composited-and-non-composited-overlap.html */,
 				71E88C4324B533EC00665160 /* img-with-base64-url.html */,
@@ -5761,6 +5768,7 @@
 				C22FA32B228F8708009D7988 /* TextWidth.mm in Sources */,
 				7CCE7EDD1A411A9200447C4C /* TimeRanges.cpp in Sources */,
 				7C83E0BD1D0A650C00FEBCF3 /* TopContentInset.mm in Sources */,
+				F4A7CE782662D6E800228685 /* TouchEventTests.mm in Sources */,
 				7CCE7ED31A411A7E00447C4C /* TypingStyleCrash.mm in Sources */,
 				57152B7821DD4E8D000C37CA /* U2fCommandConstructorTest.cpp in Sources */,
 				5CB40B4E1F4B98D3007DC7B9 /* UIDelegate.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/ios/TouchEventTests.mm (0 => 278254)


--- trunk/Tools/TestWebKitAPI/Tests/ios/TouchEventTests.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/TouchEventTests.mm	2021-05-30 19:18:56 UTC (rev 278254)
@@ -0,0 +1,148 @@
+/*
+ * 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"
+
+#if ENABLE(IOS_TOUCH_EVENTS)
+
+#import "InstanceMethodSwizzler.h"
+#import "PlatformUtilities.h"
+#import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
+#import "UIKitSPI.h"
+#import <wtf/RetainPtr.h>
+
+@interface UIView (WKContentView)
+- (void)_webTouchEventsRecognized:(UIWebTouchEventsGestureRecognizer *)gestureRecognizer;
+@end
+
+static WKWebView *globalWebView = nil;
+
+@interface TouchEventScriptMessageHandler : NSObject<WKScriptMessageHandler>
+@end
+
+@implementation TouchEventScriptMessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    if ([message.body isEqualToString:@"touchend"]) {
+        @autoreleasepool {
+            // This @autoreleasepool ensures that the content view is also deallocated upon releasing the web view.
+            [globalWebView removeFromSuperview];
+            [globalWebView release];
+            globalWebView = nil;
+        }
+    }
+}
+
+@end
+
+@interface WKWebView (TouchEventTests)
+@property (nonatomic, readonly) UIWebTouchEventsGestureRecognizer *touchEventGestureRecognizer;
+@end
+
+@implementation WKWebView (TouchEventTests)
+
+- (UIWebTouchEventsGestureRecognizer *)touchEventGestureRecognizer
+{
+    for (UIGestureRecognizer *gestureRecognizer in self.textInputContentView.gestureRecognizers) {
+        if ([gestureRecognizer isKindOfClass:UIWebTouchEventsGestureRecognizer.class])
+            return (UIWebTouchEventsGestureRecognizer *)gestureRecognizer;
+    }
+    return nil;
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+static _UIWebTouchPoint globalTouchPoint { CGPointZero, CGPointZero, 100, UITouchPhaseBegan, 1, 0, 0, 0, UIWebTouchPointTypeDirect };
+static _UIWebTouchEvent globalTouchEvent { UIWebTouchEventTouchBegin, CACurrentMediaTime(), CGPointZero, CGPointZero, 1, 0, false, &globalTouchPoint, 1, true };
+static void updateSimulatedTouchEvent(CGPoint location, UITouchPhase phase)
+{
+    globalTouchPoint.locationInScreenCoordinates = location;
+    globalTouchPoint.locationInDocumentCoordinates = location;
+    globalTouchEvent.locationInScreenCoordinates = location;
+    globalTouchEvent.locationInDocumentCoordinates = location;
+    globalTouchPoint.phase = phase;
+    switch (phase) {
+    case UITouchPhaseBegan:
+        globalTouchEvent.type = UIWebTouchEventTouchBegin;
+        break;
+    case UITouchPhaseMoved:
+        globalTouchEvent.type = UIWebTouchEventTouchChange;
+        break;
+    case UITouchPhaseEnded:
+        globalTouchEvent.type = UIWebTouchEventTouchEnd;
+        break;
+    case UITouchPhaseCancelled:
+        globalTouchEvent.type = UIWebTouchEventTouchCancel;
+        break;
+    default:
+        break;
+    }
+}
+
+static const _UIWebTouchEvent* simulatedTouchEvent(id, SEL)
+{
+    return &globalTouchEvent;
+}
+
+TEST(TouchEventTests, DestroyWebViewWhileHandlingTouchEnd)
+{
+    InstanceMethodSwizzler lastTouchEventSwizzler { UIWebTouchEventsGestureRecognizer.class, @selector(lastTouchEvent), reinterpret_cast<IMP>(simulatedTouchEvent) };
+    @autoreleasepool {
+        auto messageHandler = adoptNS([TouchEventScriptMessageHandler new]);
+        auto controller = adoptNS([[WKUserContentController alloc] init]);
+        [controller addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
+
+        auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+        [configuration setUserContentController:controller.get()];
+
+        globalWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get()];
+        auto hostWindow = adoptNS([[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+        [hostWindow setHidden:NO];
+        [hostWindow addSubview:globalWebView];
+
+        [globalWebView loadRequest:[NSURLRequest requestWithURL:[NSBundle.mainBundle URLForResource:@"active-touch-events" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+        [globalWebView _test_waitForDidFinishNavigation];
+
+        updateSimulatedTouchEvent(CGPointMake(100, 100), UITouchPhaseBegan);
+        [[globalWebView textInputContentView] _webTouchEventsRecognized:globalWebView.touchEventGestureRecognizer];
+
+        updateSimulatedTouchEvent(CGPointMake(100, 100), UITouchPhaseEnded);
+        [[globalWebView textInputContentView] _webTouchEventsRecognized:globalWebView.touchEventGestureRecognizer];
+    }
+
+    __block bool done = false;
+    dispatch_async(dispatch_get_main_queue(), ^{
+        done = true;
+    });
+    TestWebKitAPI::Util::run(&done);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // ENABLE(IOS_TOUCH_EVENTS)

Added: trunk/Tools/TestWebKitAPI/Tests/ios/active-touch-events.html (0 => 278254)


--- trunk/Tools/TestWebKitAPI/Tests/ios/active-touch-events.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/active-touch-events.html	2021-05-30 19:18:56 UTC (rev 278254)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<head>
+<style>
+body, html {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+}
+
+#target {
+    width: 100%;
+    height: 100%;
+    background: tomato;
+}
+</style>
+</head>
+<body>
+<div id="target"></div>
+<script>
+function handleTouchEvent(event) {
+    webkit.messageHandlers.testHandler.postMessage(event.type);
+}
+
+let target = document.getElementById("target");
+target.addEventListener("touchstart", handleTouchEvent);
+target.addEventListener("touchmove", handleTouchEvent);
+target.addEventListener("touchcancel", handleTouchEvent);
+target.addEventListener("touchend", handleTouchEvent);
+</script>
+</body>
+</html>

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (278253 => 278254)


--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h	2021-05-30 19:18:56 UTC (rev 278254)
@@ -48,6 +48,9 @@
 @end
 
 @interface WKWebView (TestWebKitAPI)
+#if PLATFORM(IOS_FAMILY)
+@property (nonatomic, readonly) UIView <UITextInputPrivate, UITextInputInternal, UITextInputMultiDocument, UIWKInteractionViewProtocol, UITextInputTokenizer> *textInputContentView;
+#endif
 @property (nonatomic, readonly) NSString *contentsAsString;
 @property (nonatomic, readonly) NSArray<NSString *> *tagsInBody;
 - (void)loadTestPageNamed:(NSString *)pageName;
@@ -112,7 +115,6 @@
 @end
 
 @interface TestWKWebView (IOSOnly)
-@property (nonatomic, readonly) UIView <UITextInputPrivate, UITextInputInternal, UITextInputMultiDocument, UIWKInteractionViewProtocol, UITextInputTokenizer> *textInputContentView;
 @property (nonatomic, readonly) RetainPtr<NSArray> selectionRectsAfterPresentationUpdate;
 @property (nonatomic, readonly) CGRect caretViewRectInContentCoordinates;
 @property (nonatomic, readonly) NSArray<NSValue *> *selectionViewRectsInContentCoordinates;

Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (278253 => 278254)


--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm	2021-05-30 19:18:56 UTC (rev 278254)
@@ -131,6 +131,15 @@
     return success;
 }
 
+#if PLATFORM(IOS_FAMILY)
+
+- (UIView <UITextInputPrivate, UITextInputMultiDocument> *)textInputContentView
+{
+    return (UIView <UITextInputPrivate, UITextInputMultiDocument> *)[self valueForKey:@"_currentContentView"];
+}
+
+#endif // PLATFORM(IOS_FAMILY)
+
 - (NSString *)contentsAsString
 {
     __block bool done = false;
@@ -685,11 +694,6 @@
     }
 }
 
-- (UIView <UITextInputPrivate, UITextInputMultiDocument> *)textInputContentView
-{
-    return (UIView <UITextInputPrivate, UITextInputMultiDocument> *)[self valueForKey:@"_currentContentView"];
-}
-
 - (RetainPtr<NSArray>)selectionRectsAfterPresentationUpdate
 {
     RetainPtr<TestWKWebView> retainedSelf = self;

Modified: trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h (278253 => 278254)


--- trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h	2021-05-30 16:11:40 UTC (rev 278253)
+++ trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h	2021-05-30 19:18:56 UTC (rev 278254)
@@ -47,6 +47,7 @@
 #import <UIKit/UIViewController_Private.h>
 #import <UIKit/UIWKTextInteractionAssistant.h>
 #import <UIKit/UIWebFormAccessory.h>
+#import <UIKit/UIWebTouchEventsGestureRecognizer.h>
 #import <UIKit/_UINavigationInteractiveTransition.h>
 
 IGNORE_WARNINGS_BEGIN("deprecated-implementations")
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to