[Cocoa] No way for clients to tell whether the content view is in the responder chain...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2018 03:32:06 +0000 (03:32 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Nov 2018 03:32:06 +0000 (03:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169212
<rdar://problem/30899656>

Reviewed by Tim Horton.

Source/WebKit:

Add an SPI hook to allow internal WKWebView clients to determine whether the WKWebView's content view is the
first responder. Intended for use by clients, such as Mail, that embed native text input views and other views
that may become first responder within the view hierarchy of the WKWebView.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _contentViewIsFirstResponder]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Tools:

Add an API test to exercise the behavior of `-_contentViewIsFirstResponder` when an embedded text input becomes
and resigns first responder.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm: Added.
(-[FirstResponderTestingView initWithFrame:]):
(-[FirstResponderTestingView inputField]):
(TestWebKitAPI::TEST):

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm [new file with mode: 0644]

index 77bcad8..7a4ec1b 100644 (file)
@@ -1,3 +1,19 @@
+2018-11-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] No way for clients to tell whether the content view is in the responder chain when the web view is
+        https://bugs.webkit.org/show_bug.cgi?id=169212
+        <rdar://problem/30899656>
+
+        Reviewed by Tim Horton.
+
+        Add an SPI hook to allow internal WKWebView clients to determine whether the WKWebView's content view is the
+        first responder. Intended for use by clients, such as Mail, that embed native text input views and other views
+        that may become first responder within the view hierarchy of the WKWebView.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _contentViewIsFirstResponder]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
 2018-11-26  Tim Horton  <timothy_horton@apple.com>
 
         Insert <attachment> elements under editable images to make their backing data accessible
index d247124..719b409 100644 (file)
@@ -1319,6 +1319,11 @@ static NSDictionary *dictionaryRepresentationForEditorState(const WebKit::Editor
 
 #if PLATFORM(IOS_FAMILY)
 
+- (BOOL)_contentViewIsFirstResponder
+{
+    return self._currentContentView.isFirstResponder;
+}
+
 - (_WKDragInteractionPolicy)_dragInteractionPolicy
 {
     return _dragInteractionPolicy;
index d7c7364..97228ab 100644 (file)
@@ -473,6 +473,7 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 - (void)_accessibilityClearSelection WK_API_AVAILABLE(ios(11.3));
 - (UIView *)_fullScreenPlaceholderView WK_API_AVAILABLE(ios(12.0));
 
+@property (nonatomic, readonly) BOOL _contentViewIsFirstResponder WK_API_AVAILABLE(ios(WK_IOS_TBA));
 #else
 - (void)_dismissContentRelativeChildWindows WK_API_AVAILABLE(macosx(10.13.4));
 - (void)_setFrame:(NSRect)rect andScrollBy:(NSSize)offset WK_API_AVAILABLE(macosx(10.13.4));
index 6b95dff..ed0a4d9 100644 (file)
@@ -1,3 +1,20 @@
+2018-11-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Cocoa] No way for clients to tell whether the content view is in the responder chain when the web view is
+        https://bugs.webkit.org/show_bug.cgi?id=169212
+        <rdar://problem/30899656>
+
+        Reviewed by Tim Horton.
+
+        Add an API test to exercise the behavior of `-_contentViewIsFirstResponder` when an embedded text input becomes
+        and resigns first responder.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm: Added.
+        (-[FirstResponderTestingView initWithFrame:]):
+        (-[FirstResponderTestingView inputField]):
+        (TestWebKitAPI::TEST):
+
 2018-11-26  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [CMake] Remove ENABLE_ACCESSIBILITY CMake variable
index de62df0..b005fc2 100644 (file)
                E5036F78211BC25400BFDBE2 /* color-drop.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E5036F77211BC22800BFDBE2 /* color-drop.html */; };
                ECA680CE1E68CC0900731D20 /* StringUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = ECA680CD1E68CC0900731D20 /* StringUtilities.mm */; };
                F407FE391F1D0DFC0017CF25 /* enormous.svg in Copy Resources */ = {isa = PBXBuildFile; fileRef = F407FE381F1D0DE60017CF25 /* enormous.svg */; };
+               F4106C6921ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */; };
                F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F415086C1DA040C10044BE9B /* play-audio-on-click.html */; };
                F418BE151F71B7DC001970E6 /* RoundedRectTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */; };
                F4194AD11F5A320100ADD83F /* drop-targets.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4194AD01F5A2EA500ADD83F /* drop-targets.html */; };
                ECA680CD1E68CC0900731D20 /* StringUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringUtilities.mm; sourceTree = "<group>"; };
                F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; };
                F407FE381F1D0DE60017CF25 /* enormous.svg */ = {isa = PBXFileReference; lastKnownFileType = text; path = enormous.svg; sourceTree = "<group>"; };
+               F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKWebViewFirstResponderTests.mm; path = Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm; sourceTree = "<group>"; };
                F415086C1DA040C10044BE9B /* play-audio-on-click.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "play-audio-on-click.html"; sourceTree = "<group>"; };
                F418BE141F71B7DC001970E6 /* RoundedRectTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RoundedRectTests.cpp; sourceTree = "<group>"; };
                F4194AD01F5A2EA500ADD83F /* drop-targets.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "drop-targets.html"; sourceTree = "<group>"; };
                                BC131AA8117131FC00B69727 /* TestsController.cpp */,
                                BCB9E7C711234E3A00A137E0 /* TestsController.h */,
                                7C83E0361D0A5F7000FEBCF3 /* Utilities.h */,
+                               F4106C6821ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm */,
                                44A622C114A0E2B60048515B /* WTFStringUtilities.h */,
                        );
                        name = Source;
                                2DB647881F4163D60051A89E /* WKWebViewDoesNotLogDuringInitialization.mm in Sources */,
                                F4811E5921940BDE00A5E0FD /* WKWebViewEditActions.mm in Sources */,
                                0F3B94A71A77267400DE3272 /* WKWebViewEvaluateJavaScript.mm in Sources */,
+                               F4106C6921ACBF84004B89A1 /* WKWebViewFirstResponderTests.mm in Sources */,
                                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */,
                                F4FA91811E61849B007B8C1D /* WKWebViewMacEditingTests.mm in Sources */,
                                37A9DBE9213B4C9300D261A2 /* WKWebViewServerTrustKVC.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewFirstResponderTests.mm
new file mode 100644 (file)
index 0000000..7d257fd
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 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 "PlatformUtilities.h"
+#import "TestInputDelegate.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+
+#if PLATFORM(IOS_FAMILY)
+
+@interface FirstResponderTestingView : TestWKWebView
+@property (nonatomic, readonly) UITextField *inputField;
+@end
+
+@implementation FirstResponderTestingView {
+    RetainPtr<UITextField> _inputField;
+    RetainPtr<TestInputDelegate> _inputDelegate;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+    if (!(self = [super initWithFrame:frame]))
+        return nil;
+
+    bool doneFocusing = false;
+    _inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
+    [_inputDelegate setFocusStartsInputSessionPolicyHandler:[&] (WKWebView *, id <_WKFocusedElementInfo>) {
+        doneFocusing = true;
+        return _WKFocusStartsInputSessionPolicyAllow;
+    }];
+    self._inputDelegate = _inputDelegate.get();
+    _inputField = adoptNS([[UITextField alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(frame), 44)]);
+    [self.scrollView addSubview:_inputField.get()];
+    [self synchronouslyLoadHTMLString:@"<body contenteditable><script>document.body.focus()</script>"];
+    TestWebKitAPI::Util::run(&doneFocusing);
+    return self;
+}
+
+- (UITextField *)inputField
+{
+    return _inputField.get();
+}
+
+@end
+
+namespace TestWebKitAPI {
+
+TEST(WKWebViewFirstResponderTests, ContentViewIsFirstResponder)
+{
+    auto webView = adoptNS([[FirstResponderTestingView alloc] init]);
+    EXPECT_FALSE([webView isFirstResponder]);
+    EXPECT_TRUE([webView _contentViewIsFirstResponder]);
+    EXPECT_FALSE([webView inputField].isFirstResponder);
+
+    [[webView inputField] becomeFirstResponder];
+    EXPECT_FALSE([webView isFirstResponder]);
+    EXPECT_FALSE([webView _contentViewIsFirstResponder]);
+    EXPECT_TRUE([webView inputField].isFirstResponder);
+
+    [webView becomeFirstResponder];
+    EXPECT_FALSE([webView isFirstResponder]);
+    EXPECT_TRUE([webView _contentViewIsFirstResponder]);
+    EXPECT_FALSE([webView inputField].isFirstResponder);
+}
+
+} // namespace TestWebKitAPI
+
+#endif // PLATFORM(IOS_FAMILY)