Diff
Modified: trunk/Source/WTF/ChangeLog (286640 => 286641)
--- trunk/Source/WTF/ChangeLog 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WTF/ChangeLog 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1,3 +1,13 @@
+2021-12-07 Aditya Keerthi <akeer...@apple.com>
+
+ [iOS] Add initial support for find-in-page SPI
+ https://bugs.webkit.org/show_bug.cgi?id=233915
+ rdar://86140501
+
+ Reviewed by Wenson Hsieh.
+
+ * wtf/PlatformHave.h:
+
2021-12-07 Wenson Hsieh <wenson_hs...@apple.com>
Add support for `navigator.requestCookieConsent()` behind a disabled feature flag
Modified: trunk/Source/WTF/wtf/PlatformHave.h (286640 => 286641)
--- trunk/Source/WTF/wtf/PlatformHave.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WTF/wtf/PlatformHave.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1111,3 +1111,7 @@
|| (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000))
#define HAVE_SANDBOX_STATE_FLAGS 1
#endif
+
+#if ((PLATFORM(IOS) || PLATFORM(MACCATALYST)) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000)
+#define HAVE_UIFINDINTERACTION 1
+#endif
Modified: trunk/Source/WebKit/ChangeLog (286640 => 286641)
--- trunk/Source/WebKit/ChangeLog 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/ChangeLog 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1,3 +1,92 @@
+2021-12-07 Aditya Keerthi <akeer...@apple.com>
+
+ [iOS] Add initial support for find-in-page SPI
+ https://bugs.webkit.org/show_bug.cgi?id=233915
+ rdar://86140501
+
+ Reviewed by Wenson Hsieh.
+
+ Expose new find-in-page SPI for use by clients.
+
+ * Platform/spi/ios/UIKitSPI.h:
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+ * UIProcess/API/ios/WKWebViewIOS.mm:
+ (-[WKWebView selectedTextRange]):
+ (-[WKWebView offsetFromPosition:toPosition:inDocument:]):
+ (-[WKWebView performTextSearchWithQueryString:usingOptions:resultAggregator:]):
+ (-[WKWebView decorateFoundTextRange:inDocument:usingStyle:]):
+ (-[WKWebView clearAllDecoratedFoundText]):
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::findRectsForStringMatches):
+ (WebKit::WebPageProxy::hideFindIndicator):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView offsetFromPosition:toPosition:]):
+
+ The implementation here is needed to determine the relative ordering of
+ two search results.
+
+ (-[WKContentView performTextSearchWithQueryString:usingOptions:resultAggregator:]):
+
+ Call into the WebProcess to perform the search, and asynchronously
+ mark the search as complete.
+
+ A search result is represented as a WKFoundTextRange, and contains
+ two pieces of information.
+
+ 1. A rect – so that clients can determine whether or not the result
+ is visible.
+
+ 2. An index – to allow for highlighting of a result and to enable
+ determining relative ordering between two results.
+
+ (-[WKContentView decorateFoundTextRange:usingStyle:]):
+ (-[WKContentView clearAllDecoratedFoundText]):
+ (+[WKFoundTextRange foundTextRangeWithRect:index:]):
+ (-[WKFoundTextRange start]):
+ (-[WKFoundTextRange end]):
+ (-[WKFoundTextRange isEmpty]):
+ (+[WKFoundTextPosition textPositionWithIndex:]):
+ * WebProcess/WebPage/FindController.cpp:
+ (WebKit::FindController::findString):
+
+ Prevent Editor from revealing the selection on all platforms, as the
+ existing call to didFindString is now responsible for revealing
+ selection on all platforms.
+
+ (WebKit::FindController::findRectsForStringMatches):
+
+ Gather rects for all search results and return them to the UIProcess.
+
+ (WebKit::FindController::indicateFindMatch):
+
+ This method was previously unused on iOS, and required some changes
+ to work correctly.
+
+ Wrap the call to select the current match with calls to
+ {will|did}FindString to account for iOS specific selection behavior.
+ See the existing comment in didFindString for more details.
+
+ No behavior change on other platforms, since willFindString is empty,
+ and didFindString now reveals the selection.
+
+ (WebKit::FindController::didFindString):
+ * WebProcess/WebPage/FindController.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::findRectsForStringMatches):
+ (WebKit::WebPage::hideFindIndicator):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
+ Added two new WebPage messages.
+
+ 1. findRectsForStringMatches returns an vector of string match rects
+ for use in the UIProcess.
+
+ 2. Expose hideFindIndicator via IPC so that the UIProcess can hide
+ the indicator without dismissing the overlay entirely.
+
2021-12-07 Wenson Hsieh <wenson_hs...@apple.com>
Add support for `navigator.requestCookieConsent()` behind a disabled feature flag
Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (286640 => 286641)
--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -130,6 +130,10 @@
#import <UIKit/_UITextDragCaretView.h>
#endif
+#if HAVE(UIFINDINTERACTION)
+#import <UIKit/_UITextSearching.h>
+#endif
+
#if __has_include(<UIKit/UITargetedPreview_Private.h>)
#import <UIKit/UITargetedPreview_Private.h>
#endif
@@ -284,6 +288,48 @@
- (UIEventButtonMask)_buttonMask;
@end
+#if HAVE(UIFINDINTERACTION)
+
+typedef NS_ENUM(NSUInteger, _UIFoundTextStyle) {
+ _UIFoundTextStyleNormal,
+ _UIFoundTextStyleFound,
+ _UIFoundTextStyleHighlighted,
+};
+
+typedef NS_ENUM(NSInteger, _UITextSearchMatchMethod) {
+ _UITextSearchMatchMethodContains,
+ _UITextSearchMatchMethodStartsWith,
+ _UITextSearchMatchMethodFullWord,
+};
+
+typedef id<NSCoding, NSCopying> _UITextSearchDocumentIdentifier;
+
+@interface _UITextSearchOptions : NSObject
+@property (nonatomic, readonly) _UITextSearchMatchMethod wordMatchMethod;
+@property (nonatomic, readonly) NSStringCompareOptions stringCompareOptions;
+@end
+
+@protocol _UITextSearchAggregator <NSObject>
+- (void)foundRange:(UITextRange *)range forSearchString:(NSString *)string inDocument:(_UITextSearchDocumentIdentifier)document;
+- (void)finishedSearching;
+@end
+
+@protocol _UITextSearching <NSObject>
+
+@property (readonly) UITextRange *selectedTextRange;
+
+- (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition inDocument:(_UITextSearchDocumentIdentifier)document;
+
+- (void)performTextSearchWithQueryString:(NSString *)string usingOptions:(_UITextSearchOptions *)options resultAggregator:(id<_UITextSearchAggregator>)aggregator;
+
+- (void)decorateFoundTextRange:(UITextRange *)range inDocument:(_UITextSearchDocumentIdentifier)document usingStyle:(_UIFoundTextStyle)style;
+
+- (void)clearAllDecoratedFoundText;
+
+@end
+
+#endif // HAVE(UIFINDINTERACTION)
+
typedef enum {
UIFontTraitPlain = 0,
UIFontTraitItalic = 1 << 0,
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -23,6 +23,12 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if TARGET_OS_IPHONE
+#if __has_include(<UIKit/_UITextSearching.h>)
+#import <UIKit/_UITextSearching.h>
+#endif
+#endif
+
#import <WebKit/WKDataDetectorTypes.h>
#import <WebKit/WKWebView.h>
#import <WebKit/_WKActivatedElementInfo.h>
@@ -420,7 +426,11 @@
#if TARGET_OS_IPHONE
+#if __has_include(<UIKit/_UITextSearching.h>)
+@interface WKWebView (WKPrivateIOS) <_UITextSearching>
+#else
@interface WKWebView (WKPrivateIOS)
+#endif
#if !TARGET_OS_TV && !TARGET_OS_WATCH
@property (nonatomic, copy, setter=_setUIEventAttribution:) UIEventAttribution *_uiEventAttribution WK_API_AVAILABLE(ios(15.0));
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm 2021-12-08 05:30:53 UTC (rev 286641)
@@ -3481,6 +3481,35 @@
});
}
+#if HAVE(UIFINDINTERACTION)
+
+- (UITextRange *)selectedTextRange
+{
+ return nil;
+}
+
+- (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition inDocument:(_UITextSearchDocumentIdentifier)document
+{
+ return [_contentView offsetFromPosition:from toPosition:toPosition];
+}
+
+- (void)performTextSearchWithQueryString:(NSString *)string usingOptions:(_UITextSearchOptions *)options resultAggregator:(id<_UITextSearchAggregator>)aggregator
+{
+ [_contentView performTextSearchWithQueryString:string usingOptions:options resultAggregator:aggregator];
+}
+
+- (void)decorateFoundTextRange:(UITextRange *)range inDocument:(_UITextSearchDocumentIdentifier)document usingStyle:(_UIFoundTextStyle)style
+{
+ [_contentView decorateFoundTextRange:range usingStyle:style];
+}
+
+- (void)clearAllDecoratedFoundText
+{
+ [_contentView clearAllDecoratedFoundText];
+}
+
+#endif // HAVE(UIFINDINTERACTION)
+
@end // WKWebView (WKPrivateIOS)
#if ENABLE(FULLSCREEN_API)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-12-08 05:30:53 UTC (rev 286641)
@@ -4273,6 +4273,11 @@
sendWithAsyncReply(Messages::WebPage::FindString(string, options, maxMatchCount), WTFMove(callbackFunction));
}
+void WebPageProxy::findRectsForStringMatches(const String& string, OptionSet<WebKit::FindOptions> options, unsigned maxMatchCount, CompletionHandler<void(Vector<WebCore::FloatRect>&&)>&& callbackFunction)
+{
+ sendWithAsyncReply(Messages::WebPage::FindRectsForStringMatches(string, options, maxMatchCount), WTFMove(callbackFunction));
+}
+
void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
{
send(Messages::WebPage::GetImageForFindMatch(matchIndex));
@@ -4293,6 +4298,11 @@
send(Messages::WebPage::HideFindUI());
}
+void WebPageProxy::hideFindIndicator()
+{
+ send(Messages::WebPage::HideFindIndicator());
+}
+
void WebPageProxy::countStringMatches(const String& string, OptionSet<FindOptions> options, unsigned maxMatchCount)
{
if (!hasRunningProcess())
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1200,11 +1200,13 @@
// Find.
void findString(const String&, OptionSet<FindOptions>, unsigned maxMatchCount, CompletionHandler<void(bool)>&& = [](bool) { });
void findStringMatches(const String&, OptionSet<FindOptions>, unsigned maxMatchCount);
+ void findRectsForStringMatches(const String&, OptionSet<WebKit::FindOptions>, unsigned maxMatchCount, CompletionHandler<void(Vector<WebCore::FloatRect>&&)>&&);
void getImageForFindMatch(int32_t matchIndex);
void selectFindMatch(int32_t matchIndex);
void indicateFindMatch(int32_t matchIndex);
void didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex);
void hideFindUI();
+ void hideFindIndicator();
void countStringMatches(const String&, OptionSet<FindOptions>, unsigned maxMatchCount);
void replaceMatches(Vector<uint32_t>&& matchIndices, const String& replacementText, bool selectionOnly, CompletionHandler<void(uint64_t)>&&);
void didCountStringMatches(const String&, uint32_t matchCount);
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -409,6 +409,10 @@
WeakObjCPtr<WKDataListSuggestionsControl> _dataListSuggestionsControl;
#endif
+#if HAVE(UIFINDINTERACTION)
+ RetainPtr<UITextRange> _foundHighlightedTextRange;
+#endif
+
BOOL _isEditable;
BOOL _showingTextStyleOptions;
BOOL _hasValidPositionInformation;
@@ -711,6 +715,12 @@
- (void)setTextIndicatorAnimationProgress:(float)NSAnimationProgress;
- (void)clearTextIndicator:(WebCore::TextIndicatorDismissalAnimation)animation;
+#if HAVE(UIFINDINTERACTION)
+- (void)performTextSearchWithQueryString:(NSString *)string usingOptions:(_UITextSearchOptions *)options resultAggregator:(id<_UITextSearchAggregator>)aggregator;
+- (void)decorateFoundTextRange:(UITextRange *)range usingStyle:(_UIFoundTextStyle)style;
+- (void)clearAllDecoratedFoundText;
+#endif
+
@property (nonatomic, readonly) BOOL _shouldUseContextMenus;
@property (nonatomic, readonly) BOOL _shouldUseContextMenusForFormControls;
@property (nonatomic, readonly) BOOL _shouldAvoidResizingWhenInputViewBoundsChange;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (286640 => 286641)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-12-08 05:30:53 UTC (rev 286641)
@@ -401,6 +401,27 @@
@end
+#if HAVE(UIFINDINTERACTION)
+
+@interface WKFoundTextRange : UITextRange
+
+@property (nonatomic) CGRect rect;
+@property (nonatomic) NSUInteger index;
+
++ (WKFoundTextRange *)foundTextRangeWithRect:(CGRect)rect index:(NSUInteger)index;
+
+@end
+
+@interface WKFoundTextPosition : UITextPosition
+
+@property (nonatomic) NSUInteger index;
+
++ (WKFoundTextPosition *)textPositionWithIndex:(NSUInteger)index;
+
+@end
+
+#endif
+
@interface WKAutocorrectionRects : UIWKAutocorrectionRects
+ (WKAutocorrectionRects *)autocorrectionRectsWithFirstCGRect:(CGRect)firstRect lastCGRect:(CGRect)lastRect;
@end
@@ -5238,6 +5259,11 @@
- (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition
{
+#if HAVE(UIFINDINTERACTION)
+ if ([from isKindOfClass:[WKFoundTextPosition class]] && [toPosition isKindOfClass:[WKFoundTextPosition class]])
+ return ((WKFoundTextPosition *)from).index - ((WKFoundTextPosition *)toPosition).index;
+#endif
+
return 0;
}
@@ -9949,6 +9975,47 @@
}];
}
+#if HAVE(UIFINDINTERACTION)
+
+- (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);
+
+ _page->findRectsForStringMatches(string, findOptions, 1000, [string, aggregator = retainPtr(aggregator)](const Vector<WebCore::FloatRect>& rects) {
+ NSUInteger index = 0;
+ for (auto& rect : rects) {
+ WKFoundTextRange *range = [WKFoundTextRange foundTextRangeWithRect:rect index:index];
+ [aggregator foundRange:range forSearchString:string inDocument:nil];
+ index++;
+ }
+
+ [aggregator finishedSearching];
+ });
+}
+
+- (void)decorateFoundTextRange:(UITextRange *)range usingStyle:(_UIFoundTextStyle)style
+{
+ if (![range isKindOfClass:[WKFoundTextRange class]])
+ return;
+
+ if (style == _UIFoundTextStyleHighlighted) {
+ _foundHighlightedTextRange = range;
+ WKFoundTextRange *foundRange = (WKFoundTextRange *)range;
+ _page->indicateFindMatch(foundRange.index);
+ } else if (style == _UIFoundTextStyleFound && _foundHighlightedTextRange == range)
+ _page->hideFindIndicator();
+}
+
+- (void)clearAllDecoratedFoundText
+{
+ _foundHighlightedTextRange = nil;
+ _page->hideFindUI();
+}
+
+#endif // HAVE(UIFINDINTERACTION)
+
#if ENABLE(IMAGE_ANALYSIS)
#if USE(QUICK_LOOK)
@@ -11805,6 +11872,49 @@
@end
+#if HAVE(UIFINDINTERACTION)
+
+@implementation WKFoundTextRange
+
++ (WKFoundTextRange *)foundTextRangeWithRect:(CGRect)rect index:(NSUInteger)index
+{
+ auto range = adoptNS([[WKFoundTextRange alloc] init]);
+ [range setRect:rect];
+ [range setIndex:index];
+ return range.autorelease();
+}
+
+- (WKFoundTextPosition *)start
+{
+ WKFoundTextPosition *position = [WKFoundTextPosition textPositionWithIndex:self.index];
+ return position;
+}
+
+- (UITextPosition *)end
+{
+ return self.start;
+}
+
+- (BOOL)isEmpty
+{
+ return NO;
+}
+
+@end
+
+@implementation WKFoundTextPosition
+
++ (WKFoundTextPosition *)textPositionWithIndex:(NSUInteger)index
+{
+ auto pos = adoptNS([[WKFoundTextPosition alloc] init]);
+ [pos setIndex:index];
+ return pos.autorelease();
+}
+
+@end
+
+#endif
+
@implementation WKAutocorrectionRects
+ (WKAutocorrectionRects *)autocorrectionRectsWithFirstCGRect:(CGRect)firstRect lastCGRect:(CGRect)lastRect
Modified: trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp (286640 => 286641)
--- trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp 2021-12-08 05:30:53 UTC (rev 286641)
@@ -39,6 +39,7 @@
#include <WebCore/Frame.h>
#include <WebCore/FrameSelection.h>
#include <WebCore/FrameView.h>
+#include <WebCore/GeometryUtilities.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/ImageOverlay.h>
#include <WebCore/Page.h>
@@ -235,9 +236,10 @@
// iOS will reveal the selection through a different mechanism, and
// we need to avoid sending the non-painted selection change to the UI process
// so that it does not clear the selection out from under us.
-#if PLATFORM(IOS_FAMILY)
+ //
+ // To share logic between platforms, prevent Editor from revealing the selection
+ // and reveal the selection in FindController::didFindString.
coreOptions.add(DoNotRevealSelection);
-#endif
willFindString();
@@ -301,6 +303,27 @@
});
}
+void FindController::findRectsForStringMatches(const String& string, OptionSet<FindOptions> options, unsigned maxMatchCount, CompletionHandler<void(Vector<FloatRect>&&)>&& completionHandler)
+{
+ auto result = m_webPage->corePage()->findTextMatches(string, core(options), maxMatchCount);
+ m_findMatches = WTFMove(result.ranges);
+
+ auto rects = m_findMatches.map([&] (auto& range) {
+ FloatRect rect = unionRect(RenderObject::absoluteTextRects(range));
+ return range.startContainer().document().frame()->view()->contentsToRootView(rect);
+ });
+
+ completionHandler(WTFMove(rects));
+
+ if (!options.contains(FindOptions::ShowOverlay) && !options.contains(FindOptions::ShowFindIndicator))
+ return;
+
+ bool found = !m_findMatches.isEmpty();
+ m_webPage->drawingArea()->dispatchAfterEnsuringUpdatedScrollPosition([protectedWebPage = RefPtr { m_webPage }, found, string, options, maxMatchCount] () {
+ protectedWebPage->findController().updateFindUIAfterPageScroll(found, string, options, maxMatchCount, DidWrap::No, FindUIOriginator::FindStringMatches);
+ });
+}
+
void FindController::getImageForFindMatch(uint32_t matchIndex)
{
if (matchIndex >= m_findMatches.size())
@@ -344,6 +367,8 @@
void FindController::indicateFindMatch(uint32_t matchIndex)
{
+ willFindString();
+
selectFindMatch(matchIndex);
Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
@@ -350,7 +375,7 @@
if (!selectedFrame)
return;
- selectedFrame->selection().revealSelection();
+ didFindString();
updateFindIndicator(*selectedFrame, !!m_findPageOverlay);
}
@@ -412,6 +437,11 @@
void FindController::didFindString()
{
+ Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
+ if (!selectedFrame)
+ return;
+
+ selectedFrame->selection().revealSelection();
}
void FindController::didFailToFindString()
Modified: trunk/Source/WebKit/WebProcess/WebPage/FindController.h (286640 => 286641)
--- trunk/Source/WebKit/WebProcess/WebPage/FindController.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/WebProcess/WebPage/FindController.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -60,6 +60,7 @@
void findString(const String&, OptionSet<FindOptions>, unsigned maxMatchCount, CompletionHandler<void(bool)>&&);
void findStringMatches(const String&, OptionSet<FindOptions>, unsigned maxMatchCount);
+ void findRectsForStringMatches(const String&, OptionSet<WebKit::FindOptions>, unsigned maxMatchCount, CompletionHandler<void(Vector<WebCore::FloatRect>&&)>&&);
void getImageForFindMatch(uint32_t matchIndex);
void selectFindMatch(uint32_t matchIndex);
void indicateFindMatch(uint32_t matchIndex);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (286640 => 286641)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-12-08 05:30:53 UTC (rev 286641)
@@ -4716,6 +4716,16 @@
findController().findStringMatches(string, options, maxMatchCount);
}
+void WebPage::findRectsForStringMatches(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(Vector<FloatRect>&&)>&& completionHandler)
+{
+ findController().findRectsForStringMatches(string, options, maxMatchCount, WTFMove(completionHandler));
+}
+
+void WebPage::hideFindIndicator()
+{
+ findController().hideFindIndicator();
+}
+
void WebPage::getImageForFindMatch(uint32_t matchIndex)
{
findController().getImageForFindMatch(matchIndex);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (286640 => 286641)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1763,6 +1763,8 @@
void hideFindUI();
void countStringMatches(const String&, OptionSet<FindOptions>, uint32_t maxMatchCount);
void replaceMatches(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly, CompletionHandler<void(uint64_t)>&&);
+ void findRectsForStringMatches(const String&, OptionSet<FindOptions>, uint32_t maxMatchCount, CompletionHandler<void(Vector<WebCore::FloatRect>&&)>&&);
+ void hideFindIndicator();
#if USE(COORDINATED_GRAPHICS)
void sendViewportAttributesChanged(const WebCore::ViewportArguments&);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (286640 => 286641)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2021-12-08 05:30:53 UTC (rev 286641)
@@ -312,6 +312,9 @@
HideFindUI()
CountStringMatches(String string, OptionSet<WebKit::FindOptions> findOptions, unsigned maxMatchCount)
ReplaceMatches(Vector<uint32_t> matchIndices, String replacementText, bool selectionOnly) -> (uint64_t numberOfReplacements) Async
+
+ FindRectsForStringMatches(String string, OptionSet<WebKit::FindOptions> findOptions, unsigned maxMatchCount) -> (Vector<WebCore::FloatRect> matches) Async
+ HideFindIndicator()
AddMIMETypeWithCustomContentProvider(String mimeType)
Modified: trunk/Tools/ChangeLog (286640 => 286641)
--- trunk/Tools/ChangeLog 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Tools/ChangeLog 2021-12-08 05:30:53 UTC (rev 286641)
@@ -1,3 +1,19 @@
+2021-12-07 Aditya Keerthi <akeer...@apple.com>
+
+ [iOS] Add initial support for find-in-page SPI
+ https://bugs.webkit.org/show_bug.cgi?id=233915
+ rdar://86140501
+
+ Reviewed by Wenson Hsieh.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm:
+ (-[TestSearchAggregator initWithCompletionHandler:]):
+ (-[TestSearchAggregator foundRange:forSearchString:inDocument:]):
+ (-[TestSearchAggregator finishedSearching]):
+ (TEST):
+
+ Added an API test to verify that search results are found correctly.
+
2021-12-07 Wenson Hsieh <wenson_hs...@apple.com>
Add support for `navigator.requestCookieConsent()` behind a disabled feature flag
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm (286640 => 286641)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm 2021-12-08 04:24:38 UTC (rev 286640)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FindInPage.mm 2021-12-08 05:30:53 UTC (rev 286641)
@@ -30,8 +30,13 @@
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKWebViewPrivate.h>
+#import <wtf/BlockPtr.h>
#import <wtf/RetainPtr.h>
+#if PLATFORM(IOS_FAMILY)
+#import "UIKitSPI.h"
+#endif
+
#if !PLATFORM(IOS_FAMILY)
typedef enum : NSUInteger {
@@ -321,3 +326,72 @@
#endif // ENABLE(IMAGE_ANALYSIS)
#endif // !PLATFORM(IOS_FAMILY)
+
+#if HAVE(UIFINDINTERACTION)
+
+@interface TestTextSearchOptions : NSObject
+@property (nonatomic, readonly) _UITextSearchMatchMethod wordMatchMethod;
+@property (nonatomic, readonly) NSStringCompareOptions stringCompareOptions;
+@end
+
+@implementation TestTextSearchOptions
+@end
+
+@interface TestSearchAggregator : NSObject <_UITextSearchAggregator>
+
+@property (readonly) NSUInteger count;
+
+- (instancetype)initWithCompletionHandler:(dispatch_block_t)completionHandler;
+
+@end
+
+@implementation TestSearchAggregator {
+ BlockPtr<void()> _completionHandler;
+}
+
+- (instancetype)initWithCompletionHandler:(dispatch_block_t)completionHandler
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _count = 0;
+ _completionHandler = makeBlockPtr(completionHandler);
+
+ return self;
+}
+
+- (void)foundRange:(UITextRange *)range forSearchString:(NSString *)string inDocument:(_UITextSearchDocumentIdentifier)document
+{
+ _count++;
+}
+
+- (void)finishedSearching
+{
+ if (_completionHandler)
+ _completionHandler();
+}
+
+@end
+
+TEST(WebKit, FindInPage)
+{
+ 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];
+
+ __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:@"Birthday" usingOptions:(_UITextSearchOptions *)[[TestTextSearchOptions alloc] init] resultAggregator:aggregator.get()];
+
+ TestWebKitAPI::Util::run(&finishedSearching);
+
+ EXPECT_EQ([aggregator count], 360UL);
+}
+
+#endif // HAVE(UIFINDINTERACTION)