Title: [290481] trunk
Revision
290481
Author
akeer...@apple.com
Date
2022-02-24 17:43:01 -0800 (Thu, 24 Feb 2022)

Log Message

[iOS] Add support for replacing WKFoundTextRanges
https://bugs.webkit.org/show_bug.cgi?id=237151
rdar://89258687

Reviewed by Wenson Hsieh.

Source/WebKit:

Implement protocol methods to support replacement.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::replaceFoundTextRangeWithString):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView replaceFoundTextInRange:inDocument:withText:]):
(-[WKContentView supportsTextReplacement]):

Restrict replacement to editable web views.

* WebProcess/WebPage/WebFoundTextRangeController.cpp:
(WebKit::WebFoundTextRangeController::replaceFoundTextRangeWithString):

Use a `TemporarySelectionChange` to select and replace the desired range.

* WebProcess/WebPage/WebFoundTextRangeController.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::replaceFoundTextRangeWithString):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Add a test that replaces found ranges.

* TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (290480 => 290481)


--- trunk/Source/WebKit/ChangeLog	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/ChangeLog	2022-02-25 01:43:01 UTC (rev 290481)
@@ -1,3 +1,33 @@
+2022-02-24  Aditya Keerthi  <akeer...@apple.com>
+
+        [iOS] Add support for replacing WKFoundTextRanges
+        https://bugs.webkit.org/show_bug.cgi?id=237151
+        rdar://89258687
+
+        Reviewed by Wenson Hsieh.
+
+        Implement protocol methods to support replacement.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::replaceFoundTextRangeWithString):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView replaceFoundTextInRange:inDocument:withText:]):
+        (-[WKContentView supportsTextReplacement]):
+
+        Restrict replacement to editable web views.
+
+        * WebProcess/WebPage/WebFoundTextRangeController.cpp:
+        (WebKit::WebFoundTextRangeController::replaceFoundTextRangeWithString):
+
+        Use a `TemporarySelectionChange` to select and replace the desired range.
+
+        * WebProcess/WebPage/WebFoundTextRangeController.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::replaceFoundTextRangeWithString):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2022-02-24  Chris Dumez  <cdu...@apple.com>
 
         Take down shared worker context connection less aggressively when it becomes idle

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (290480 => 290481)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-02-25 01:43:01 UTC (rev 290481)
@@ -4296,6 +4296,11 @@
     sendWithAsyncReply(Messages::WebPage::FindTextRangesForStringMatches(string, options, maxMatchCount), WTFMove(callbackFunction));
 }
 
+void WebPageProxy::replaceFoundTextRangeWithString(const WebFoundTextRange& range, const String& string)
+{
+    send(Messages::WebPage::ReplaceFoundTextRangeWithString(range, string));
+}
+
 void WebPageProxy::decorateTextRangeWithStyle(const WebFoundTextRange& range, FindDecorationStyle style)
 {
     send(Messages::WebPage::DecorateTextRangeWithStyle(range, style));

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (290480 => 290481)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-25 01:43:01 UTC (rev 290481)
@@ -1221,6 +1221,7 @@
     void didFindStringMatches(const String&, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection);
 
     void findTextRangesForStringMatches(const String&, OptionSet<FindOptions>, unsigned maxMatchCount, CompletionHandler<void(Vector<WebFoundTextRange>&&)>&&);
+    void replaceFoundTextRangeWithString(const WebFoundTextRange&, const String&);
     void decorateTextRangeWithStyle(const WebFoundTextRange&, FindDecorationStyle);
     void scrollTextRangeToVisible(const WebFoundTextRange&);
     void clearAllDecoratedFoundText();

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (290480 => 290481)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-25 01:43:01 UTC (rev 290481)
@@ -10330,6 +10330,18 @@
     });
 }
 
+- (void)replaceFoundTextInRange:(UITextRange *)range inDocument:(_UITextSearchDocumentIdentifier)document withText:(NSString *)replacementText
+{
+    if (!self.supportsTextReplacement)
+        return;
+
+    auto foundTextRange = dynamic_objc_cast<WKFoundTextRange>(range);
+    if (!foundTextRange)
+        return;
+
+    _page->replaceFoundTextRangeWithString([foundTextRange webFoundTextRange], replacementText);
+}
+
 - (void)decorateFoundTextRange:(UITextRange *)range inDocument:(_UITextSearchDocumentIdentifier)document usingStyle:(_UIFoundTextStyle)style
 {
     auto foundTextRange = dynamic_objc_cast<WKFoundTextRange>(range);
@@ -10366,6 +10378,11 @@
     _page->didEndTextSearchOperation();
 }
 
+- (BOOL)supportsTextReplacement
+{
+    return self.webView._editable;
+}
+
 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
 - (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition inDocument:(_UITextSearchDocumentIdentifier)document
 {

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.cpp (290480 => 290481)


--- trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.cpp	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.cpp	2022-02-25 01:43:01 UTC (rev 290481)
@@ -85,6 +85,27 @@
     completionHandler(WTFMove(foundTextRanges));
 }
 
+void WebFoundTextRangeController::replaceFoundTextRangeWithString(const WebFoundTextRange& range, const String& string)
+{
+    auto simpleRange = simpleRangeFromFoundTextRange(range);
+    if (!simpleRange)
+        return;
+
+    RefPtr document = documentForFoundTextRange(range);
+    if (!document)
+        return;
+
+    RefPtr frame = document->frame();
+    if (!frame)
+        return;
+
+    WebCore::VisibleSelection visibleSelection(*simpleRange);
+    OptionSet temporarySelectionOptions { WebCore::TemporarySelectionOption::DoNotSetFocus, WebCore::TemporarySelectionOption::IgnoreSelectionChanges };
+    WebCore::TemporarySelectionChange selectionChange(*document, visibleSelection, temporarySelectionOptions);
+
+    frame->editor().replaceSelectionWithText(string, WebCore::Editor::SelectReplacement::Yes, WebCore::Editor::SmartReplace::No, WebCore::EditAction::InsertReplacement);
+}
+
 void WebFoundTextRangeController::decorateTextRangeWithStyle(const WebFoundTextRange& range, FindDecorationStyle style)
 {
     auto simpleRange = simpleRangeFromFoundTextRange(range);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.h (290480 => 290481)


--- trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.h	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFoundTextRangeController.h	2022-02-25 01:43:01 UTC (rev 290481)
@@ -54,6 +54,8 @@
 
     void findTextRangesForStringMatches(const String&, OptionSet<FindOptions>, uint32_t maxMatchCount, CompletionHandler<void(Vector<WebKit::WebFoundTextRange>&&)>&&);
 
+    void replaceFoundTextRangeWithString(const WebFoundTextRange&, const String&);
+
     void decorateTextRangeWithStyle(const WebFoundTextRange&, FindDecorationStyle);
     void scrollTextRangeToVisible(const WebFoundTextRange&);
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (290480 => 290481)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2022-02-25 01:43:01 UTC (rev 290481)
@@ -4721,6 +4721,11 @@
     foundTextRangeController().findTextRangesForStringMatches(string, options, maxMatchCount, WTFMove(completionHandler));
 }
 
+void WebPage::replaceFoundTextRangeWithString(const WebFoundTextRange& range, const String& string)
+{
+    foundTextRangeController().replaceFoundTextRangeWithString(range, string);
+}
+
 void WebPage::decorateTextRangeWithStyle(const WebFoundTextRange& range, WebKit::FindDecorationStyle style)
 {
     foundTextRangeController().decorateTextRangeWithStyle(range, style);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (290480 => 290481)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-25 01:43:01 UTC (rev 290481)
@@ -1789,6 +1789,7 @@
     void hideFindIndicator();
 
     void findTextRangesForStringMatches(const String&, OptionSet<FindOptions>, uint32_t maxMatchCount, CompletionHandler<void(Vector<WebFoundTextRange>&&)>&&);
+    void replaceFoundTextRangeWithString(const WebFoundTextRange&, const String&);
     void decorateTextRangeWithStyle(const WebFoundTextRange&, WebKit::FindDecorationStyle);
     void scrollTextRangeToVisible(const WebFoundTextRange&);
     void clearAllDecoratedFoundText();

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (290480 => 290481)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-25 01:43:01 UTC (rev 290481)
@@ -324,6 +324,7 @@
     HideFindIndicator()
 
     FindTextRangesForStringMatches(String string, OptionSet<WebKit::FindOptions> findOptions, unsigned maxMatchCount) -> (Vector<WebKit::WebFoundTextRange> ranges) Async
+    ReplaceFoundTextRangeWithString(struct WebKit::WebFoundTextRange range, String string)
     DecorateTextRangeWithStyle(struct WebKit::WebFoundTextRange range, enum:uint8_t WebKit::FindDecorationStyle style)
     ScrollTextRangeToVisible(struct WebKit::WebFoundTextRange range)
     ClearAllDecoratedFoundText();

Modified: trunk/Tools/ChangeLog (290480 => 290481)


--- trunk/Tools/ChangeLog	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Tools/ChangeLog	2022-02-25 01:43:01 UTC (rev 290481)
@@ -1,3 +1,16 @@
+2022-02-24  Aditya Keerthi  <akeer...@apple.com>
+
+        [iOS] Add support for replacing WKFoundTextRanges
+        https://bugs.webkit.org/show_bug.cgi?id=237151
+        rdar://89258687
+
+        Reviewed by Wenson Hsieh.
+
+        Add a test that replaces found ranges.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm:
+        (TEST):
+
 2022-02-24  Jonathan Bedard  <jbed...@apple.com>
 
         [Python3] Remove shebangs from webkitpy files

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm (290480 => 290481)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm	2022-02-25 01:42:55 UTC (rev 290480)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm	2022-02-25 01:43:01 UTC (rev 290481)
@@ -490,6 +490,32 @@
     testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birth", searchOptions.get(), 0UL);
 }
 
+TEST(WebKit, FindAndReplace)
+{
+    NSString *originalContent = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+    NSString *searchString = @"dolor";
+    NSString *replacementString = @"colour";
+    NSString *replacedContent = [originalContent stringByReplacingOccurrencesOfString:searchString withString:replacementString];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView _setFindInteractionEnabled:YES];
+    [webView synchronouslyLoadHTMLString:[NSString stringWithFormat:@"<p>%@</p>", originalContent]];
+
+    auto ranges = textRangesForQueryString(webView.get(), searchString);
+
+    [webView _setEditable:NO];
+    for (UITextRange *range in [ranges reverseObjectEnumerator])
+        [[[webView _findInteraction] searchableObject] replaceFoundTextInRange:range inDocument:nil withText:replacementString];
+
+    EXPECT_WK_STREQ(originalContent, [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
+
+    [webView _setEditable:YES];
+    for (UITextRange *range in [ranges reverseObjectEnumerator])
+        [[[webView _findInteraction] searchableObject] replaceFoundTextInRange:range inDocument:nil withText:replacementString];
+
+    EXPECT_WK_STREQ(replacedContent, [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
+}
+
 TEST(WebKit, FindInteraction)
 {
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to