- Revision
- 222654
- Author
- [email protected]
- Date
- 2017-09-29 11:33:32 -0700 (Fri, 29 Sep 2017)
Log Message
[iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
https://bugs.webkit.org/show_bug.cgi?id=177662
<rdar://problem/33410373>
Reviewed by Tim Horton.
Source/WebCore:
Adds a new TextIterator helper function to determine whether a Range has any plain text.
Tests: EditorStateTests.ContentViewHasTextInContentEditableElement
EditorStateTests.ContentViewHasTextInTextarea
* editing/TextIterator.cpp:
(WebCore::hasAnyPlainText):
Add a new helper to determine whether a Range contains any plain text. While inspired by and very similar to the
plainText() helper function, this variant does not create a new string buffer when invoked, and is therefore
more efficient for the purposes of determining whether there is any plain text at all.
* editing/TextIterator.h:
Source/WebKit:
Implements -[WKContentView hasText] by propagating a flag through post-layout editor state.
* Shared/EditorState.cpp:
(WebKit::EditorState::PostLayoutData::encode const):
(WebKit::EditorState::PostLayoutData::decode):
* Shared/EditorState.h:
Add a new flag to EditorState indicating whether or not the current editable root containing the selection has
any plain text. Add IPC support for this new flag.
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView hasText]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::computeEditableRootHasContentAndPlainText):
Add a new helper to compute whether or not the editable root has any content, and any plain text. This
is used as the last cached value for -hasText on WKContentView that we will deliver to UIKit. Some important
things to note here:
- If post layout data already indicates that we have selected some plain text, or that there is a plain text
character near the selection, just set the flags to true and bail, since the editable root necessarily has
content that is plain text.
- If hasContent is false, don't even bother computing hasPlainText, because it must also be false.
- Otherwise, use hasAnyPlainText to compute the value of hasPlainText, which is a faster variant of plainText.
These optimizations help us avoid doing extra work at all when running Speedometer, apart from checking the
values of a few PostLayoutData flags. This also fixes the value of hasContent, which was previously always false
if we had a range selection rather than a caret selection even when the editable root has content, because the
logic to compute the value of hasContent only existed in the branch where we have a caret selection.
(WebKit::WebPage::platformEditorState const):
Tools:
Add EditorState API tests to check that the value of -[WKContentView hasText] is correct when editing both plain
and rich text areas.
* TestWebKitAPI/EditingTestHarness.h:
* TestWebKitAPI/EditingTestHarness.mm:
(-[EditingTestHarness insertParagraph]):
(-[EditingTestHarness insertText:]):
(-[EditingTestHarness insertHTML:]):
(-[EditingTestHarness selectAll]):
(-[EditingTestHarness deleteBackwards]):
* TestWebKitAPI/Tests/WebKitCocoa/EditorStateTests.mm:
Add versions of EditingTestHarness helpers that don't require us to expect any editor state after executing the
edit command.
(TestWebKitAPI::checkContentViewHasTextWithFailureDescription):
(TestWebKitAPI::TEST):
* TestWebKitAPI/cocoa/TestWKWebView.h:
* TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[TestWKWebView textInputContentView]):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (222653 => 222654)
--- trunk/Source/WebCore/ChangeLog 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebCore/ChangeLog 2017-09-29 18:33:32 UTC (rev 222654)
@@ -1,3 +1,25 @@
+2017-09-29 Wenson Hsieh <[email protected]>
+
+ [iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
+ https://bugs.webkit.org/show_bug.cgi?id=177662
+ <rdar://problem/33410373>
+
+ Reviewed by Tim Horton.
+
+ Adds a new TextIterator helper function to determine whether a Range has any plain text.
+
+ Tests: EditorStateTests.ContentViewHasTextInContentEditableElement
+ EditorStateTests.ContentViewHasTextInTextarea
+
+ * editing/TextIterator.cpp:
+ (WebCore::hasAnyPlainText):
+
+ Add a new helper to determine whether a Range contains any plain text. While inspired by and very similar to the
+ plainText() helper function, this variant does not create a new string buffer when invoked, and is therefore
+ more efficient for the purposes of determining whether there is any plain text at all.
+
+ * editing/TextIterator.h:
+
2017-09-29 Zalan Bujtas <[email protected]>
Add WeakPtr support to RenderObject.
Modified: trunk/Source/WebCore/editing/TextIterator.cpp (222653 => 222654)
--- trunk/Source/WebCore/editing/TextIterator.cpp 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebCore/editing/TextIterator.cpp 2017-09-29 18:33:32 UTC (rev 222654)
@@ -2634,6 +2634,15 @@
// --------
+bool hasAnyPlainText(const Range& range, TextIteratorBehavior behavior)
+{
+ for (TextIterator iterator { &range, behavior }; !iterator.atEnd(); iterator.advance()) {
+ if (!iterator.text().isEmpty())
+ return true;
+ }
+ return false;
+}
+
String plainText(const Range* r, TextIteratorBehavior defaultBehavior, bool isDisplayString)
{
// The initial buffer size can be critical for performance: https://bugs.webkit.org/show_bug.cgi?id=81192
Modified: trunk/Source/WebCore/editing/TextIterator.h (222653 => 222654)
--- trunk/Source/WebCore/editing/TextIterator.h 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebCore/editing/TextIterator.h 2017-09-29 18:33:32 UTC (rev 222654)
@@ -46,6 +46,7 @@
WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
Ref<Range> findPlainText(const Range&, const String&, FindOptions);
WEBCORE_EXPORT Ref<Range> findClosestPlainText(const Range&, const String&, FindOptions, unsigned);
+WEBCORE_EXPORT bool hasAnyPlainText(const Range&, TextIteratorBehavior = TextIteratorDefaultBehavior);
// FIXME: Move this somewhere else in the editing directory. It doesn't belong here.
bool isRendererReplacedElement(RenderObject*);
Modified: trunk/Source/WebKit/ChangeLog (222653 => 222654)
--- trunk/Source/WebKit/ChangeLog 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebKit/ChangeLog 2017-09-29 18:33:32 UTC (rev 222654)
@@ -1,3 +1,41 @@
+2017-09-29 Wenson Hsieh <[email protected]>
+
+ [iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
+ https://bugs.webkit.org/show_bug.cgi?id=177662
+ <rdar://problem/33410373>
+
+ Reviewed by Tim Horton.
+
+ Implements -[WKContentView hasText] by propagating a flag through post-layout editor state.
+
+ * Shared/EditorState.cpp:
+ (WebKit::EditorState::PostLayoutData::encode const):
+ (WebKit::EditorState::PostLayoutData::decode):
+ * Shared/EditorState.h:
+
+ Add a new flag to EditorState indicating whether or not the current editable root containing the selection has
+ any plain text. Add IPC support for this new flag.
+
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView hasText]):
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::computeEditableRootHasContentAndPlainText):
+
+ Add a new helper to compute whether or not the editable root has any content, and any plain text. This
+ is used as the last cached value for -hasText on WKContentView that we will deliver to UIKit. Some important
+ things to note here:
+ - If post layout data already indicates that we have selected some plain text, or that there is a plain text
+ character near the selection, just set the flags to true and bail, since the editable root necessarily has
+ content that is plain text.
+ - If hasContent is false, don't even bother computing hasPlainText, because it must also be false.
+ - Otherwise, use hasAnyPlainText to compute the value of hasPlainText, which is a faster variant of plainText.
+ These optimizations help us avoid doing extra work at all when running Speedometer, apart from checking the
+ values of a few PostLayoutData flags. This also fixes the value of hasContent, which was previously always false
+ if we had a range selection rather than a caret selection even when the editable root has content, because the
+ logic to compute the value of hasContent only existed in the branch where we have a caret selection.
+
+ (WebKit::WebPage::platformEditorState const):
+
2017-09-28 Timothy Horton <[email protected]>
Fix the macOS CMake build
Modified: trunk/Source/WebKit/Shared/EditorState.cpp (222653 => 222654)
--- trunk/Source/WebKit/Shared/EditorState.cpp 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebKit/Shared/EditorState.cpp 2017-09-29 18:33:32 UTC (rev 222654)
@@ -127,6 +127,7 @@
encoder << hasContent;
encoder << isStableStateUpdate;
encoder << insideFixedPosition;
+ encoder << hasPlainText;
#endif
#if PLATFORM(MAC)
encoder << candidateRequestStartPosition;
@@ -176,6 +177,8 @@
return false;
if (!decoder.decode(result.insideFixedPosition))
return false;
+ if (!decoder.decode(result.hasPlainText))
+ return false;
#endif
#if PLATFORM(MAC)
if (!decoder.decode(result.candidateRequestStartPosition))
Modified: trunk/Source/WebKit/Shared/EditorState.h (222653 => 222654)
--- trunk/Source/WebKit/Shared/EditorState.h 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebKit/Shared/EditorState.h 2017-09-29 18:33:32 UTC (rev 222654)
@@ -101,6 +101,7 @@
bool hasContent { false };
bool isStableStateUpdate { false };
bool insideFixedPosition { false };
+ bool hasPlainText { false };
#endif
#if PLATFORM(MAC)
uint64_t candidateRequestStartPosition { 0 };
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (222653 => 222654)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2017-09-29 18:33:32 UTC (rev 222654)
@@ -3182,7 +3182,8 @@
- (BOOL)hasText
{
- return YES;
+ auto& editorState = _page->editorState();
+ return !editorState.isMissingPostLayoutData && editorState.postLayoutData().hasPlainText;
}
// end of UITextInput protocol implementation
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (222653 => 222654)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2017-09-29 18:33:32 UTC (rev 222654)
@@ -145,6 +145,29 @@
notImplemented();
}
+static void computeEditableRootHasContentAndPlainText(const VisibleSelection& selection, EditorState::PostLayoutData& data)
+{
+ data.hasContent = false;
+ data.hasPlainText = false;
+ if (!selection.isContentEditable())
+ return;
+
+ if (data.selectedTextLength || data.characterAfterSelection || data.characterBeforeSelection || data.twoCharacterBeforeSelection) {
+ // If any of these variables have been previously set, the editable root must have plain text content, so we can bail from the remainder of the check.
+ data.hasContent = true;
+ data.hasPlainText = true;
+ return;
+ }
+
+ auto* root = selection.rootEditableElement();
+ if (!root)
+ return;
+
+ auto startInEditableRoot = firstPositionInNode(root);
+ data.hasContent = root->hasChildNodes() && !isEndOfEditableOrNonEditableContent(startInEditableRoot);
+ data.hasPlainText = data.hasContent && hasAnyPlainText(Range::create(root->document(), VisiblePosition { startInEditableRoot }, VisiblePosition { lastPositionInNode(root) }));
+}
+
void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
{
if (frame.editor().hasComposition()) {
@@ -185,11 +208,8 @@
// FIXME: The following check should take into account writing direction.
postLayoutData.isReplaceAllowed = result.isContentEditable && atBoundaryOfGranularity(selection.start(), WordGranularity, DirectionForward);
postLayoutData.wordAtSelection = plainTextReplacingNoBreakSpace(wordRangeFromPosition(selection.start()).get());
- if (selection.isContentEditable()) {
+ if (selection.isContentEditable())
charactersAroundPosition(selection.start(), postLayoutData.characterAfterSelection, postLayoutData.characterBeforeSelection, postLayoutData.twoCharacterBeforeSelection);
- Node* root = selection.rootEditableElement();
- postLayoutData.hasContent = root && root->hasChildNodes() && !isEndOfEditableOrNonEditableContent(firstPositionInNode(root));
- }
} else if (selection.isRange()) {
postLayoutData.caretRectAtStart = view->contentsToRootView(VisiblePosition(selection.start()).absoluteCaretBounds(&startNodeIsInsideFixedPosition));
postLayoutData.caretRectAtEnd = view->contentsToRootView(VisiblePosition(selection.end()).absoluteCaretBounds(&endNodeIsInsideFixedPosition));
@@ -211,6 +231,7 @@
if (!selection.isNone()) {
if (m_assistedNode && m_assistedNode->renderer())
postLayoutData.selectionClipRect = view->contentsToRootView(m_assistedNode->renderer()->absoluteBoundingBoxRect());
+ computeEditableRootHasContentAndPlainText(selection, postLayoutData);
}
}
Modified: trunk/Tools/ChangeLog (222653 => 222654)
--- trunk/Tools/ChangeLog 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/ChangeLog 2017-09-29 18:33:32 UTC (rev 222654)
@@ -1,3 +1,32 @@
+2017-09-29 Wenson Hsieh <[email protected]>
+
+ [iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
+ https://bugs.webkit.org/show_bug.cgi?id=177662
+ <rdar://problem/33410373>
+
+ Reviewed by Tim Horton.
+
+ Add EditorState API tests to check that the value of -[WKContentView hasText] is correct when editing both plain
+ and rich text areas.
+
+ * TestWebKitAPI/EditingTestHarness.h:
+ * TestWebKitAPI/EditingTestHarness.mm:
+ (-[EditingTestHarness insertParagraph]):
+ (-[EditingTestHarness insertText:]):
+ (-[EditingTestHarness insertHTML:]):
+ (-[EditingTestHarness selectAll]):
+ (-[EditingTestHarness deleteBackwards]):
+ * TestWebKitAPI/Tests/WebKitCocoa/EditorStateTests.mm:
+
+ Add versions of EditingTestHarness helpers that don't require us to expect any editor state after executing the
+ edit command.
+
+ (TestWebKitAPI::checkContentViewHasTextWithFailureDescription):
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/cocoa/TestWKWebView.h:
+ * TestWebKitAPI/cocoa/TestWKWebView.mm:
+ (-[TestWKWebView textInputContentView]):
+
2017-09-29 Charles Turner <[email protected]>
Update my status.
Modified: trunk/Tools/TestWebKitAPI/EditingTestHarness.h (222653 => 222654)
--- trunk/Tools/TestWebKitAPI/EditingTestHarness.h 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/TestWebKitAPI/EditingTestHarness.h 2017-09-29 18:33:32 UTC (rev 222654)
@@ -41,6 +41,11 @@
@property (nonatomic, readonly) NSDictionary *latestEditorState;
@property (nonatomic, readonly) NSArray<NSDictionary *> *editorStateHistory;
+- (void)insertParagraph;
+- (void)insertText:(NSString *)text;
+- (void)insertHTML:(NSString *)html;
+- (void)selectAll;
+- (void)deleteBackwards;
- (void)insertParagraphAndExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries;
- (void)insertText:(NSString *)text andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries;
- (void)insertHTML:(NSString *)html andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries;
Modified: trunk/Tools/TestWebKitAPI/EditingTestHarness.mm (222653 => 222654)
--- trunk/Tools/TestWebKitAPI/EditingTestHarness.mm 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/TestWebKitAPI/EditingTestHarness.mm 2017-09-29 18:33:32 UTC (rev 222654)
@@ -67,6 +67,31 @@
return _editorStateHistory.get();
}
+- (void)insertParagraph
+{
+ [self insertParagraphAndExpectEditorStateWith:nil];
+}
+
+- (void)insertText:(NSString *)text
+{
+ [self insertText:text andExpectEditorStateWith:nil];
+}
+
+- (void)insertHTML:(NSString *)html
+{
+ [self insertHTML:html andExpectEditorStateWith:nil];
+}
+
+- (void)selectAll
+{
+ [self selectAllAndExpectEditorStateWith:nil];
+}
+
+- (void)deleteBackwards
+{
+ [self deleteBackwardAndExpectEditorStateWith:nil];
+}
+
- (void)insertText:(NSString *)text andExpectEditorStateWith:(NSDictionary<NSString *, id> *)entries
{
[self _execCommand:@"InsertText" argument:text expectEntries:entries];
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EditorStateTests.mm (222653 => 222654)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EditorStateTests.mm 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EditorStateTests.mm 2017-09-29 18:33:32 UTC (rev 222654)
@@ -32,6 +32,10 @@
#import "TestWKWebView.h"
#import <WebKit/WKWebViewPrivate.h>
+#if PLATFORM(IOS)
+#import <UIKit/UIKit.h>
+#endif
+
namespace TestWebKitAPI {
static RetainPtr<EditingTestHarness> setUpEditorStateTestHarness()
@@ -229,6 +233,73 @@
EXPECT_WK_STREQ("https://www.apple.com/", [[testHarness webView] stringByEvaluatingJavaScript:@"document.querySelector('a').href"]);
}
+#if PLATFORM(IOS)
+
+static void checkContentViewHasTextWithFailureDescription(TestWKWebView *webView, BOOL expectedToHaveText, NSString *description)
+{
+ BOOL hasText = webView.textInputContentView.hasText;
+ if (expectedToHaveText)
+ EXPECT_TRUE(hasText);
+ else
+ EXPECT_FALSE(hasText);
+
+ if (expectedToHaveText != hasText)
+ NSLog(@"Expected -[%@ hasText] to be %@, but observed: %@ (%@)", [webView.textInputContentView class], expectedToHaveText ? @"YES" : @"NO", hasText ? @"YES" : @"NO", description);
+}
+
+TEST(EditorStateTests, ContentViewHasTextInContentEditableElement)
+{
+ auto testHarness = setUpEditorStateTestHarness();
+ TestWKWebView *webView = [testHarness webView];
+
+ checkContentViewHasTextWithFailureDescription(webView, NO, @"before inserting any content");
+ [testHarness insertHTML:@"<img src=''></img>"];
+ checkContentViewHasTextWithFailureDescription(webView, NO, @"after inserting an image element");
+ [testHarness insertText:@"A"];
+ checkContentViewHasTextWithFailureDescription(webView, YES, @"after inserting text");
+ [testHarness selectAll];
+ checkContentViewHasTextWithFailureDescription(webView, YES, @"after selecting everything");
+ [testHarness deleteBackwards];
+ checkContentViewHasTextWithFailureDescription(webView, NO, @"after deleting everything");
+ [testHarness insertParagraph];
+ checkContentViewHasTextWithFailureDescription(webView, YES, @"after inserting a newline");
+ [testHarness deleteBackwards];
+ checkContentViewHasTextWithFailureDescription(webView, NO, @"after deleting the newline");
+ [testHarness insertText:@"B"];
+ checkContentViewHasTextWithFailureDescription(webView, YES, @"after inserting text again");
+ [webView stringByEvaluatingJavaScript:@"document.body.blur()"];
+ [webView waitForNextPresentationUpdate];
+ checkContentViewHasTextWithFailureDescription(webView, NO, @"after losing focus");
+}
+
+TEST(EditorStateTests, ContentViewHasTextInTextarea)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ auto testHarness = adoptNS([[EditingTestHarness alloc] initWithWebView:webView.get()]);
+ [webView synchronouslyLoadHTMLString:@"<textarea id='textarea'></textarea>"];
+ [webView stringByEvaluatingJavaScript:@"textarea.focus()"];
+ [webView waitForNextPresentationUpdate];
+
+ checkContentViewHasTextWithFailureDescription(webView.get(), NO, @"before inserting any content");
+ [testHarness insertText:@"A"];
+ checkContentViewHasTextWithFailureDescription(webView.get(), YES, @"after inserting text");
+ [testHarness selectAll];
+ checkContentViewHasTextWithFailureDescription(webView.get(), YES, @"after selecting everything");
+ [testHarness deleteBackwards];
+ checkContentViewHasTextWithFailureDescription(webView.get(), NO, @"after deleting everything");
+ [testHarness insertParagraph];
+ checkContentViewHasTextWithFailureDescription(webView.get(), YES, @"after inserting a newline");
+ [testHarness deleteBackwards];
+ checkContentViewHasTextWithFailureDescription(webView.get(), NO, @"after deleting the newline");
+ [testHarness insertText:@"B"];
+ checkContentViewHasTextWithFailureDescription(webView.get(), YES, @"after inserting text again");
+ [webView stringByEvaluatingJavaScript:@"textarea.blur()"];
+ [webView waitForNextPresentationUpdate];
+ checkContentViewHasTextWithFailureDescription(webView.get(), NO, @"after losing focus");
+}
+
+#endif
+
} // namespace TestWebKitAPI
#endif // WK_API_ENABLED
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h (222653 => 222654)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h 2017-09-29 18:33:32 UTC (rev 222654)
@@ -23,11 +23,11 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if WK_API_ENABLED
+
#import <WebKit/WebKit.h>
#import <wtf/RetainPtr.h>
-#if WK_API_ENABLED
-
@class _WKProcessPoolConfiguration;
#if PLATFORM(IOS)
@@ -53,6 +53,7 @@
#if PLATFORM(IOS)
@interface TestWKWebView (IOSOnly)
+@property (nonatomic, readonly) UIView <UITextInput> *textInputContentView;
@property (nonatomic, readonly) RetainPtr<NSArray> selectionRectsAfterPresentationUpdate;
- (_WKActivatedElementInfo *)activatedElementAtPosition:(CGPoint)position;
@end
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm (222653 => 222654)
--- trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2017-09-29 17:50:59 UTC (rev 222653)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm 2017-09-29 18:33:32 UTC (rev 222654)
@@ -45,6 +45,7 @@
#endif
#if PLATFORM(IOS)
+#import <UIKit/UIKit.h>
#import <wtf/SoftLinking.h>
SOFT_LINK_FRAMEWORK(UIKit)
SOFT_LINK_CLASS(UIKit, UIWindow)
@@ -292,6 +293,11 @@
@implementation TestWKWebView (IOSOnly)
+- (UIView <UITextInput> *)textInputContentView
+{
+ return (UIView <UITextInput> *)[self valueForKey:@"_currentContentView"];
+}
+
- (RetainPtr<NSArray>)selectionRectsAfterPresentationUpdate
{
RetainPtr<TestWKWebView> retainedSelf = self;