Modified: trunk/Source/WebKit/ChangeLog (286659 => 286660)
--- trunk/Source/WebKit/ChangeLog 2021-12-08 17:06:45 UTC (rev 286659)
+++ trunk/Source/WebKit/ChangeLog 2021-12-08 17:50:40 UTC (rev 286660)
@@ -1,3 +1,23 @@
+2021-12-08 Aditya Keerthi <akeer...@apple.com>
+
+ [iOS] Add support for _UITextSearchOptions when finding a string
+ https://bugs.webkit.org/show_bug.cgi?id=233957
+ rdar://86140673
+
+ Reviewed by Wenson Hsieh.
+
+ Add support for case-insensitive, full-word, and prefix matching.
+
+ * Shared/WebFindOptions.h:
+
+ Introduce AtWordEnds at the WebKit layer to support full-word matching
+ when used with AtWordStarts.
+
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView performTextSearchWithQueryString:usingOptions:resultAggregator:]):
+ * WebProcess/WebPage/FindController.cpp:
+ (WebKit::core):
+
2021-12-08 Wenson Hsieh <wenson_hs...@apple.com>
Add a missing CompletionHandlerCallChecker around a UI delegate method call after r286640
Modified: trunk/Source/WebKit/Shared/WebFindOptions.h (286659 => 286660)
--- trunk/Source/WebKit/Shared/WebFindOptions.h 2021-12-08 17:06:45 UTC (rev 286659)
+++ trunk/Source/WebKit/Shared/WebFindOptions.h 2021-12-08 17:50:40 UTC (rev 286660)
@@ -40,6 +40,7 @@
ShowHighlight = 1 << 7,
DetermineMatchIndex = 1 << 8,
NoIndexChange = 1 << 9,
+ AtWordEnds = 1 << 10,
};
} // namespace WebKit
@@ -58,7 +59,8 @@
WebKit::FindOptions::ShowFindIndicator,
WebKit::FindOptions::ShowHighlight,
WebKit::FindOptions::DetermineMatchIndex,
- WebKit::FindOptions::NoIndexChange
+ WebKit::FindOptions::NoIndexChange,
+ WebKit::FindOptions::AtWordEnds
>;
};
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (286659 => 286660)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-12-08 17:06:45 UTC (rev 286659)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-12-08 17:50:40 UTC (rev 286660)
@@ -9979,10 +9979,23 @@
- (void)performTextSearchWithQueryString:(NSString *)string usingOptions:(_UITextSearchOptions *)options resultAggregator:(id<_UITextSearchAggregator>)aggregator
{
- // FIXME: (rdar://86140673) Account for _UITextSearchOptions when performing the search.
OptionSet<WebKit::FindOptions> findOptions;
findOptions.add(WebKit::FindOptions::ShowOverlay);
+ switch (options.wordMatchMethod) {
+ case _UITextSearchMatchMethodStartsWith:
+ findOptions.add(WebKit::FindOptions::AtWordStarts);
+ break;
+ case _UITextSearchMatchMethodFullWord:
+ findOptions.add({ WebKit::FindOptions::AtWordStarts, WebKit::FindOptions::AtWordEnds });
+ break;
+ default:
+ break;
+ }
+
+ if (options.stringCompareOptions & NSCaseInsensitiveSearch)
+ findOptions.add(WebKit::FindOptions::CaseInsensitive);
+
_page->findRectsForStringMatches(string, findOptions, 1000, [string, aggregator = retainPtr(aggregator)](const Vector<WebCore::FloatRect>& rects) {
NSUInteger index = 0;
for (auto& rect : rects) {
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm (286659 => 286660)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm 2021-12-08 17:06:45 UTC (rev 286659)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm 2021-12-08 17:50:40 UTC (rev 286660)
@@ -330,8 +330,8 @@
#if HAVE(UIFINDINTERACTION)
@interface TestTextSearchOptions : NSObject
-@property (nonatomic, readonly) _UITextSearchMatchMethod wordMatchMethod;
-@property (nonatomic, readonly) NSStringCompareOptions stringCompareOptions;
+@property (nonatomic) _UITextSearchMatchMethod wordMatchMethod;
+@property (nonatomic) NSStringCompareOptions stringCompareOptions;
@end
@implementation TestTextSearchOptions
@@ -373,6 +373,21 @@
@end
+static void testPerformTextSearchWithQueryStringInWebView(WKWebView *webView, NSString *query, TestTextSearchOptions *searchOptions, NSUInteger expectedMatches)
+{
+ __block bool finishedSearching = false;
+ RetainPtr aggregator = adoptNS([[TestSearchAggregator alloc] initWithCompletionHandler:^{
+ finishedSearching = true;
+ }]);
+
+ // FIXME: (rdar://86140914) Use _UITextSearchOptions directly when the symbol is exported.
+ [webView performTextSearchWithQueryString:query usingOptions:(_UITextSearchOptions *)searchOptions resultAggregator:aggregator.get()];
+
+ TestWebKitAPI::Util::run(&finishedSearching);
+
+ EXPECT_EQ([aggregator count], expectedMatches);
+}
+
TEST(WebKit, FindInPage)
{
RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
@@ -381,17 +396,60 @@
[webView loadRequest:request];
[webView _test_waitForDidFinishNavigation];
- __block bool finishedSearching = false;
- RetainPtr aggregator = adoptNS([[TestSearchAggregator alloc] initWithCompletionHandler:^{
- finishedSearching = true;
- }]);
+ RetainPtr searchOptions = adoptNS([[TestTextSearchOptions alloc] init]);
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birthday", searchOptions.get(), 360UL);
+}
- // FIXME: (rdar://86140914) Use _UITextSearchOptions directly when the symbol is exported.
- [webView performTextSearchWithQueryString:@"Birthday" usingOptions:(_UITextSearchOptions *)[[TestTextSearchOptions alloc] init] resultAggregator:aggregator.get()];
+TEST(WebKit, FindInPageCaseInsensitive)
+{
+ RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
- TestWebKitAPI::Util::run(&finishedSearching);
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"lots-of-text" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [webView _test_waitForDidFinishNavigation];
- EXPECT_EQ([aggregator count], 360UL);
+ RetainPtr searchOptions = adoptNS([[TestTextSearchOptions alloc] init]);
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"birthday", searchOptions.get(), 0UL);
+
+ [searchOptions setStringCompareOptions:NSCaseInsensitiveSearch];
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"birthday", searchOptions.get(), 360UL);
}
+TEST(WebKit, FindInPageStartsWith)
+{
+ RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"lots-of-text" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [webView _test_waitForDidFinishNavigation];
+
+ RetainPtr searchOptions = adoptNS([[TestTextSearchOptions alloc] init]);
+
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birth", searchOptions.get(), 360UL);
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"day", searchOptions.get(), 360UL);
+
+ [searchOptions setWordMatchMethod:_UITextSearchMatchMethodStartsWith];
+
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birth", searchOptions.get(), 360UL);
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"day", searchOptions.get(), 0UL);
+}
+
+TEST(WebKit, FindInPageFullWord)
+{
+ RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]);
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"lots-of-text" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [webView _test_waitForDidFinishNavigation];
+
+ RetainPtr searchOptions = adoptNS([[TestTextSearchOptions alloc] init]);
+
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birth", searchOptions.get(), 360UL);
+
+ [searchOptions setWordMatchMethod:_UITextSearchMatchMethodFullWord];
+
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birthday", searchOptions.get(), 360UL);
+ testPerformTextSearchWithQueryStringInWebView(webView.get(), @"Birth", searchOptions.get(), 0UL);
+}
+
#endif // HAVE(UIFINDINTERACTION)