Add support for using the current text selection as the find string on iOS
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jan 2019 04:00:47 +0000 (04:00 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Jan 2019 04:00:47 +0000 (04:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193034
<rdar://problem/45138739>

Reviewed by Tim Horton.

Source/WebCore:

Add support for "TakeFindStringFromSelection" on iOS. Unlike macOS, iOS does not have a notion of a "find
pasteboard" like macOS; instead, we handle this editing command by sending the selection string to the UI
process, where it is exposed via WebKit SPI so that clients that present find-in-page UI (i.e. MobileSafari) are
able to trigger find-in-page with this string.

Test: WebKit.UseSelectionAsFindString

* editing/Editor.cpp:
(WebCore::Editor::canCopyExcludingStandaloneImages const):

Make this helper function cross-platform.

* editing/Editor.h:
* editing/EditorCommand.cpp:
(WebCore::createCommandMap):
* editing/cocoa/EditorCocoa.mm:
(WebCore::Editor::takeFindStringFromSelection):

Move this from EditorMac to EditorCocoa, and implement it on iOS by calling into the editor client to update the
find string (see WebKit/ChangeLog for more details).

* editing/mac/EditorMac.mm:
(WebCore::Editor::canCopyExcludingStandaloneImages): Deleted.
(WebCore::Editor::takeFindStringFromSelection): Deleted.
* loader/EmptyClients.cpp:
* page/EditorClient.h:

Add a new editor client method to send the string for find-in-page to the UI process.

Source/WebKit:

* SourcesCocoa.txt:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _takeFindStringFromSelection:]):

Provides a way to set the find string on iOS and macOS (an aside: takeFindStringFromSelection: already exists on
macOS, but there is no equivalent protocol method on iOS, so this new SPI acts as a cross-platform way for
WebKit clients to take the find string from the selection across all Cocoa platforms).

(+[WKWebView _stringForFind]):
(+[WKWebView _setStringForFind:]):

Call into find-in-page helper functions.

(-[WKWebView _findString:options:maxCount:]):

On iOS, additionally update the find-in-page string when exercising the _findString:options:maxCount: SPI. This
mirrors macOS behavior of updating the find pasteboard every time the find string changes; however, on macOS,
this is implemented by the platform (in AppKit), whereas there's no platform find pasteboard on iOS, let alone
logic to update it in UIKit. As such, we directly drive updates to the find string within WebKit.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Add some new cross-platform find-in-page SPI. See above for more details.

* UIProcess/Cocoa/GlobalFindInPageState.h: Added.
* UIProcess/Cocoa/GlobalFindInPageState.mm: Added.
(WebKit::findPasteboard):
(WebKit::globalStringForFind):

Fetch the string to use when finding text in the page. On macOS, this accesses the AppKit find pasteboard; on
iOS, this instead returns the current global find string.

(WebKit::updateStringForFind):

Sets the global find string. Uses the find pasteboard on macOS, and sets the global find string on iOS.

(WebKit::stringForFind):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:

Add plumbing to allow WebEditorClient to deliver the update the global find string in the UI process.

* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::updateStringForFind):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebEditorClient.h:
* WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
(WebKit::WebEditorClient::updateStringForFind):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateStringForFind):

Source/WebKitLegacy/mac:

Add a method stub for WebKitLegacy.

* WebCoreSupport/WebEditorClient.h:

Tools:

Add a new API test to verify that the new WebKit SPI (_stringForFind, _takeFindStringFromSelection:, and
_setStringForFind) works as expected.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/UseSelectionAsFindString.mm: Added.

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

27 files changed:
Source/WebCore/ChangeLog
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/EditorCommand.cpp
Source/WebCore/editing/cocoa/EditorCocoa.mm
Source/WebCore/editing/mac/EditorMac.mm
Source/WebCore/loader/EmptyClients.cpp
Source/WebCore/page/EditorClient.h
Source/WebKit/ChangeLog
Source/WebKit/SourcesCocoa.txt
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.h [new file with mode: 0644]
Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.mm [new file with mode: 0644]
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h
Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/UseSelectionAsFindString.mm [new file with mode: 0644]

index 723c7ef..b83270c 100644 (file)
@@ -1,3 +1,40 @@
+2019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for using the current text selection as the find string on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193034
+        <rdar://problem/45138739>
+
+        Reviewed by Tim Horton.
+
+        Add support for "TakeFindStringFromSelection" on iOS. Unlike macOS, iOS does not have a notion of a "find
+        pasteboard" like macOS; instead, we handle this editing command by sending the selection string to the UI
+        process, where it is exposed via WebKit SPI so that clients that present find-in-page UI (i.e. MobileSafari) are
+        able to trigger find-in-page with this string.
+
+        Test: WebKit.UseSelectionAsFindString
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::canCopyExcludingStandaloneImages const):
+
+        Make this helper function cross-platform.
+
+        * editing/Editor.h:
+        * editing/EditorCommand.cpp:
+        (WebCore::createCommandMap):
+        * editing/cocoa/EditorCocoa.mm:
+        (WebCore::Editor::takeFindStringFromSelection):
+
+        Move this from EditorMac to EditorCocoa, and implement it on iOS by calling into the editor client to update the
+        find string (see WebKit/ChangeLog for more details).
+
+        * editing/mac/EditorMac.mm:
+        (WebCore::Editor::canCopyExcludingStandaloneImages): Deleted.
+        (WebCore::Editor::takeFindStringFromSelection): Deleted.
+        * loader/EmptyClients.cpp:
+        * page/EditorClient.h:
+
+        Add a new editor client method to send the string for find-in-page to the UI process.
+
 2019-01-02  Devin Rousso  <webkit@devinrousso.com>
 
         Web Inspector: Implement `queryObjects` Command Line API
index a5e8584..8d17137 100644 (file)
@@ -4256,4 +4256,10 @@ RefPtr<HTMLImageElement> Editor::insertEditableImage()
     return InsertEditableImageCommand::insertEditableImage(document());
 }
 
+bool Editor::canCopyExcludingStandaloneImages() const
+{
+    auto& selection = m_frame.selection().selection();
+    return selection.isRange() && !selection.isInPasswordField();
+}
+
 } // namespace WebCore
index 7cad220..05cc1b8 100644 (file)
@@ -485,9 +485,8 @@ public:
 #if PLATFORM(COCOA)
     WEBCORE_EXPORT String stringSelectionForPasteboard();
     String stringSelectionForPasteboardWithImageAltText();
-#if !PLATFORM(IOS_FAMILY)
-    bool canCopyExcludingStandaloneImages();
     void takeFindStringFromSelection();
+#if !PLATFORM(IOS_FAMILY)
     WEBCORE_EXPORT void readSelectionFromPasteboard(const String& pasteboardName);
     WEBCORE_EXPORT void replaceNodeFromPasteboard(Node*, const String& pasteboardName);
     WEBCORE_EXPORT RefPtr<SharedBuffer> dataSelectionForPasteboard(const String& pasteboardName);
@@ -495,6 +494,8 @@ public:
     WEBCORE_EXPORT void replaceSelectionWithAttributedString(NSAttributedString *, MailBlockquoteHandling = MailBlockquoteHandling::RespectBlockquote);
 #endif
 
+    bool canCopyExcludingStandaloneImages() const;
+
     String clientReplacementURLForResource(Ref<SharedBuffer>&& resourceData, const String& mimeType);
 
 #if !PLATFORM(WIN)
index 9fdac1d..0b3bbb9 100644 (file)
@@ -1102,13 +1102,15 @@ static bool executeSwapWithMark(Frame& frame, Event*, EditorCommandSource, const
     return true;
 }
 
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
+
 static bool executeTakeFindStringFromSelection(Frame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().takeFindStringFromSelection();
     return true;
 }
-#endif
+
+#endif // PLATFORM(COCOA)
 
 static bool executeToggleBold(Frame& frame, Event*, EditorCommandSource source, const String&)
 {
@@ -1367,12 +1369,14 @@ static bool enabledRedo(Frame& frame, Event*, EditorCommandSource)
     return frame.editor().canRedo();
 }
 
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
+
 static bool enabledTakeFindStringFromSelection(Frame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canCopyExcludingStandaloneImages();
 }
-#endif
+
+#endif // PLATFORM(COCOA)
 
 static bool enabledUndo(Frame& frame, Event*, EditorCommandSource)
 {
@@ -1718,7 +1722,7 @@ static const CommandMap& createCommandMap()
         { "PasteGlobalSelection", { executePasteGlobalSelection, supportedFromMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
 #endif
 
-#if PLATFORM(MAC)
+#if PLATFORM(COCOA)
         { "TakeFindStringFromSelection", { executeTakeFindStringFromSelection, supportedFromMenuOrKeyBinding, enabledTakeFindStringFromSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
 #endif
     };
index 5de716f..949b1a9 100644 (file)
 #import "HTMLConverter.h"
 #import "HTMLImageElement.h"
 #import "HTMLSpanElement.h"
+#import "LegacyNSPasteboardTypes.h"
 #import "LegacyWebArchive.h"
 #import "Pasteboard.h"
+#import "PasteboardStrategy.h"
+#import "PlatformStrategies.h"
 #import "RenderElement.h"
 #import "RenderStyle.h"
 #import "Settings.h"
@@ -55,6 +58,7 @@
 #import "markup.h"
 #import <pal/spi/cocoa/NSAttributedStringSPI.h>
 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
+#import <pal/system/Sound.h>
 #import <wtf/BlockObjCExceptions.h>
 #import <wtf/cocoa/NSURLExtras.h>
 
@@ -223,4 +227,28 @@ RefPtr<DocumentFragment> Editor::webContentFromPasteboard(Pasteboard& pasteboard
     return WTFMove(reader.fragment);
 }
 
+void Editor::takeFindStringFromSelection()
+{
+    if (!canCopyExcludingStandaloneImages()) {
+        PAL::systemBeep();
+        return;
+    }
+
+    auto stringFromSelection = m_frame.displayStringModifiedByEncoding(selectedTextForDataTransfer());
+#if PLATFORM(MAC)
+    Vector<String> types;
+    types.append(String(legacyStringPasteboardType()));
+    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
+    platformStrategies()->pasteboardStrategy()->setTypes(types, NSFindPboard);
+    platformStrategies()->pasteboardStrategy()->setStringForType(WTFMove(stringFromSelection), legacyStringPasteboardType(), NSFindPboard);
+    ALLOW_DEPRECATED_DECLARATIONS_END
+#else
+    if (auto* client = this->client()) {
+        // Since the find pasteboard doesn't exist on iOS, WebKit maintains its own notion of the latest find string,
+        // which SPI clients may respect when presenting find-in-page UI.
+        client->updateStringForFind(stringFromSelection);
+    }
+#endif
+}
+
 }
index 3fe6f4e..6971f00 100644 (file)
@@ -55,7 +55,6 @@
 #import "WebNSAttributedStringExtras.h"
 #import "markup.h"
 #import <AppKit/AppKit.h>
-#import <pal/system/Sound.h>
 #import <wtf/cocoa/NSURLExtras.h>
 
 namespace WebCore {
@@ -98,27 +97,6 @@ void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption>
     client()->setInsertionPasteboard(String());
 }
 
-bool Editor::canCopyExcludingStandaloneImages()
-{
-    const VisibleSelection& selection = m_frame.selection().selection();
-    return selection.isRange() && !selection.isInPasswordField();
-}
-
-void Editor::takeFindStringFromSelection()
-{
-    if (!canCopyExcludingStandaloneImages()) {
-        PAL::systemBeep();
-        return;
-    }
-
-    Vector<String> types;
-    types.append(String(legacyStringPasteboardType()));
-    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    platformStrategies()->pasteboardStrategy()->setTypes(types, NSFindPboard);
-    platformStrategies()->pasteboardStrategy()->setStringForType(m_frame.displayStringModifiedByEncoding(selectedTextForDataTransfer()), legacyStringPasteboardType(), NSFindPboard);
-    ALLOW_DEPRECATED_DECLARATIONS_END
-}
-
 void Editor::readSelectionFromPasteboard(const String& pasteboardName)
 {
     Pasteboard pasteboard(pasteboardName);
index a28ec68..492524b 100644 (file)
@@ -215,6 +215,7 @@ private:
     int getPasteboardItemsCount() final { return 0; }
     RefPtr<DocumentFragment> documentFragmentFromDelegate(int) final { return nullptr; }
     bool performsTwoStepPaste(DocumentFragment*) final { return false; }
+    void updateStringForFind(const String&) final { }
 #endif
 
     bool performTwoStepDrop(DocumentFragment&, Range&, bool) final { return false; }
index a65d80c..37bf182 100644 (file)
@@ -134,6 +134,7 @@ public:
     virtual int getPasteboardItemsCount() = 0;
     virtual RefPtr<DocumentFragment> documentFragmentFromDelegate(int index) = 0;
     virtual bool performsTwoStepPaste(DocumentFragment*) = 0;
+    virtual void updateStringForFind(const String&) = 0;
 #endif
 
 #if PLATFORM(COCOA)
index 050f714..ff74565 100644 (file)
@@ -1,3 +1,63 @@
+2019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for using the current text selection as the find string on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193034
+        <rdar://problem/45138739>
+
+        Reviewed by Tim Horton.
+
+        * SourcesCocoa.txt:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _takeFindStringFromSelection:]):
+
+        Provides a way to set the find string on iOS and macOS (an aside: takeFindStringFromSelection: already exists on
+        macOS, but there is no equivalent protocol method on iOS, so this new SPI acts as a cross-platform way for
+        WebKit clients to take the find string from the selection across all Cocoa platforms).
+
+        (+[WKWebView _stringForFind]):
+        (+[WKWebView _setStringForFind:]):
+
+        Call into find-in-page helper functions.
+
+        (-[WKWebView _findString:options:maxCount:]):
+
+        On iOS, additionally update the find-in-page string when exercising the _findString:options:maxCount: SPI. This
+        mirrors macOS behavior of updating the find pasteboard every time the find string changes; however, on macOS,
+        this is implemented by the platform (in AppKit), whereas there's no platform find pasteboard on iOS, let alone
+        logic to update it in UIKit. As such, we directly drive updates to the find string within WebKit.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+        Add some new cross-platform find-in-page SPI. See above for more details.
+
+        * UIProcess/Cocoa/GlobalFindInPageState.h: Added.
+        * UIProcess/Cocoa/GlobalFindInPageState.mm: Added.
+        (WebKit::findPasteboard):
+        (WebKit::globalStringForFind):
+
+        Fetch the string to use when finding text in the page. On macOS, this accesses the AppKit find pasteboard; on
+        iOS, this instead returns the current global find string.
+
+        (WebKit::updateStringForFind):
+
+        Sets the global find string. Uses the find pasteboard on macOS, and sets the global find string on iOS.
+
+        (WebKit::stringForFind):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        Add plumbing to allow WebEditorClient to deliver the update the global find string in the UI process.
+
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::updateStringForFind):
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+        * WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
+        (WebKit::WebEditorClient::updateStringForFind):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::updateStringForFind):
+
 2019-01-02  Brent Fulgham  <bfulgham@apple.com>
 
         Allow WebContent process access to some drawing-related IOKit properties
index 8459750..56f3c45 100644 (file)
@@ -317,6 +317,7 @@ UIProcess/Cocoa/DiagnosticLoggingClient.mm
 UIProcess/Cocoa/DownloadClient.mm
 UIProcess/Cocoa/FindClient.mm
 UIProcess/Cocoa/FullscreenClient.mm
+UIProcess/Cocoa/GlobalFindInPageState.mm
 UIProcess/Cocoa/IconLoadingDelegate.mm
 UIProcess/Cocoa/LegacyCustomProtocolManagerClient.mm
 UIProcess/Cocoa/NavigationState.mm
index 6d89396..3c5bebf 100644 (file)
@@ -37,6 +37,7 @@
 #import "FindClient.h"
 #import "FrontBoardServicesSPI.h"
 #import "FullscreenClient.h"
+#import "GlobalFindInPageState.h"
 #import "IconLoadingDelegate.h"
 #import "LegacySessionStateCoding.h"
 #import "Logging.h"
@@ -4442,6 +4443,25 @@ FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKCONTENTVIEW)
 #endif
 }
 
+- (void)_takeFindStringFromSelection:(id)sender
+{
+#if PLATFORM(MAC)
+    [self takeFindStringFromSelection:sender];
+#else
+    _page->executeEditCommand("TakeFindStringFromSelection"_s);
+#endif
+}
+
++ (NSString *)_stringForFind
+{
+    return WebKit::stringForFind();
+}
+
++ (void)_setStringForFind:(NSString *)findString
+{
+    WebKit::updateStringForFind(findString);
+}
+
 - (_WKRemoteObjectRegistry *)_remoteObjectRegistry
 {
 #if PLATFORM(MAC)
@@ -5177,6 +5197,11 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
 - (void)_findString:(NSString *)string options:(_WKFindOptions)options maxCount:(NSUInteger)maxCount
 {
 #if PLATFORM(IOS_FAMILY)
+    // While AppKit contains logic in NSBarTextFinder to automatically update the find pasteboard
+    // when the find string changes, this (along with the find pasteboard itself) are both missing
+    // from iOS; thus, on iOS, we update the current find-in-page string here.
+    WebKit::updateStringForFind(string);
+
     if (_customContentView) {
         [_customContentView web_findString:string options:options maxCount:maxCount];
         return;
index 88b5635..e709409 100644 (file)
@@ -215,6 +215,9 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 - (IBAction)_changeListType:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (IBAction)_pasteAsQuotation:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (IBAction)_pasteAndMatchStyle:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (IBAction)_takeFindStringFromSelection:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
+@property (class, nonatomic, copy, setter=_setStringForFind:) NSString *_stringForFind WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if TARGET_OS_IPHONE
 
diff --git a/Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.h b/Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.h
new file mode 100644 (file)
index 0000000..feaa581
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#if PLATFORM(COCOA)
+
+namespace WTF {
+class String;
+}
+
+namespace WebKit {
+
+void updateStringForFind(const WTF::String&);
+WTF::String stringForFind();
+
+} // namespace WebKit
+
+#endif // PLATFORM(COCOA)
diff --git a/Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.mm b/Source/WebKit/UIProcess/Cocoa/GlobalFindInPageState.mm
new file mode 100644 (file)
index 0000000..3ff69ee
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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 "GlobalFindInPageState.h"
+
+#import <wtf/text/WTFString.h>
+
+#if PLATFORM(MAC)
+#import <AppKit/NSPasteboard.h>
+#import <WebCore/LegacyNSPasteboardTypes.h>
+#endif
+
+namespace WebKit {
+
+#if PLATFORM(MAC)
+
+static NSPasteboard *findPasteboard()
+{
+    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
+    return [NSPasteboard pasteboardWithName:NSFindPboard];
+    ALLOW_DEPRECATED_DECLARATIONS_END
+}
+
+#else
+
+static String& globalStringForFind()
+{
+    static NeverDestroyed<String> string;
+    return string.get();
+}
+
+#endif
+
+void updateStringForFind(const String& string)
+{
+#if PLATFORM(MAC)
+    [findPasteboard() setString:string forType:WebCore::legacyStringPasteboardType()];
+#else
+    globalStringForFind() = string;
+#endif
+}
+
+String stringForFind()
+{
+#if PLATFORM(MAC)
+    return [findPasteboard() stringForType:WebCore::legacyStringPasteboardType()];
+#else
+    return globalStringForFind();
+#endif
+}
+
+} // namespace WebKit
index 01bea50..52834e6 100644 (file)
@@ -1720,6 +1720,8 @@ private:
     void interpretKeyEvent(const EditorState&, bool isCharEvent, bool& handled);
     void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect, WebCore::RouteSharingPolicy, const String&);
     void selectionRectsCallback(const Vector<WebCore::SelectionRect>&, CallbackID);
+
+    void updateStringForFind(const String&);
 #endif
 #if PLATFORM(GTK)
     void printFinishedCallback(const WebCore::ResourceError&, CallbackID);
index 1e4518f..cf40fdc 100644 (file)
@@ -416,6 +416,8 @@ messages -> WebPageProxy {
 
     EnableInspectorNodeSearch()
     DisableInspectorNodeSearch()
+
+    UpdateStringForFind(String findString)
 #endif
 
     DidChangeInspectorFrontendCount(uint64_t count)
index f6d304b..d33263d 100644 (file)
@@ -31,6 +31,7 @@
 #import "APIUIClient.h"
 #import "DataReference.h"
 #import "EditingRange.h"
+#import "GlobalFindInPageState.h"
 #import "InteractionInformationAtPosition.h"
 #import "Logging.h"
 #import "NativeWebKeyboardEvent.h"
@@ -226,6 +227,14 @@ void WebPageProxy::resendLastVisibleContentRects()
     m_process->send(Messages::ViewUpdateDispatcher::VisibleContentRectUpdate(m_pageID, m_lastVisibleContentRectUpdate), 0);
 }
 
+void WebPageProxy::updateStringForFind(const String& string)
+{
+    if (!isValid())
+        return;
+
+    WebKit::updateStringForFind(string);
+}
+
 static inline float adjustedUnexposedEdge(float documentEdge, float exposedRectEdge, float factor)
 {
     if (exposedRectEdge < documentEdge)
index 223a7bf..743d012 100644 (file)
@@ -75,9 +75,9 @@
                005D158F18E4C4EB00734619 /* _WKFindDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 005D158E18E4C4EB00734619 /* _WKFindDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                00B9661618E24CBA00CE1F88 /* APIFindClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B9661518E24CBA00CE1F88 /* APIFindClient.h */; };
                00B9661A18E25AE100CE1F88 /* FindClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B9661818E25AE100CE1F88 /* FindClient.h */; };
+               07297F9F1C17AA1A015F0735 /* PersistencyUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */; };
                07297F9F1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */; };
                07297F9F1C17BBEA015F0735 /* DeviceIdHashSaltStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */; };
-               07297F9F1C17AA1A015F0735 /* PersistencyUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */; };
                07297FA31C186ADB003F0735 /* WKUserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
                074E75FE1DF2211900D318EC /* UserMediaProcessManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 074E75FB1DF1FD1300D318EC /* UserMediaProcessManager.h */; };
                076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */; };
                57DCEDC3214F114C0016B847 /* MockLocalService.h in Headers */ = {isa = PBXBuildFile; fileRef = 57DCEDC1214F114C0016B847 /* MockLocalService.h */; };
                57DCEDC7214F18300016B847 /* MockLocalConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 57DCEDC5214F18300016B847 /* MockLocalConnection.h */; };
                57DCEDCB214F4E420016B847 /* MockAuthenticatorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 57DCEDC9214F4E420016B847 /* MockAuthenticatorManager.h */; };
-               58E977DF21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 58E977DD21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h */; };
                587743A621C30BBE00AE9084 /* HTTPSUpgradeList.db in Resources */ = {isa = PBXBuildFile; fileRef = 587743A421C30AD800AE9084 /* HTTPSUpgradeList.db */; };
+               58E977DF21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 58E977DD21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h */; };
                5C0B17781E7C880E00E9123C /* NetworkSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17741E7C879C00E9123C /* NetworkSocketStreamMessageReceiver.cpp */; };
                5C0B17791E7C882100E9123C /* WebSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17761E7C879C00E9123C /* WebSocketStreamMessageReceiver.cpp */; };
                5C1426ED1C23F80900D41183 /* NetworkProcessCreationParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1426E31C23F80500D41183 /* NetworkProcessCreationParameters.h */; };
                00B9661518E24CBA00CE1F88 /* APIFindClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIFindClient.h; sourceTree = "<group>"; };
                00B9661718E25AE100CE1F88 /* FindClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FindClient.mm; sourceTree = "<group>"; };
                00B9661818E25AE100CE1F88 /* FindClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindClient.h; sourceTree = "<group>"; };
+               0729455C1C1711EA003F0735 /* PersistencyUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PersistencyUtils.cpp; sourceTree = "<group>"; };
                07297F9C1C1711EA003F0735 /* DeviceIdHashSaltStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceIdHashSaltStorage.cpp; sourceTree = "<group>"; };
                07297F9C1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaPermissionCheckProxy.cpp; sourceTree = "<group>"; };
                07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheckProxy.h; sourceTree = "<group>"; };
                07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceIdHashSaltStorage.h; sourceTree = "<group>"; };
-               0729455C1C1711EA003F0735 /* PersistencyUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PersistencyUtils.cpp; sourceTree = "<group>"; };
-               07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersistencyUtils.h; sourceTree = "<group>"; };
                07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKUserMediaPermissionCheck.cpp; sourceTree = "<group>"; };
                07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKUserMediaPermissionCheck.h; sourceTree = "<group>"; };
+               07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersistencyUtils.h; sourceTree = "<group>"; };
                074E75FB1DF1FD1300D318EC /* UserMediaProcessManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaProcessManager.h; sourceTree = "<group>"; };
                074E75FC1DF2002400D318EC /* UserMediaProcessManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaProcessManager.cpp; sourceTree = "<group>"; };
                074E76001DF7075D00D318EC /* MediaDeviceSandboxExtensions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDeviceSandboxExtensions.cpp; sourceTree = "<group>"; };
                2DFF7B6E1DA4CFAF00814614 /* WKBackForwardListItemPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBackForwardListItemPrivate.h; sourceTree = "<group>"; };
                2E16B6CC2017B7AB008996D6 /* WKFocusedFormControlView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFocusedFormControlView.mm; path = ios/forms/WKFocusedFormControlView.mm; sourceTree = "<group>"; };
                2E16B6CD2017B7AC008996D6 /* WKFocusedFormControlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFocusedFormControlView.h; path = ios/forms/WKFocusedFormControlView.h; sourceTree = "<group>"; };
+               2E2B3BA321D4879000538EDF /* GlobalFindInPageState.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GlobalFindInPageState.mm; sourceTree = "<group>"; };
+               2E2B3BA421D4879000538EDF /* GlobalFindInPageState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobalFindInPageState.h; sourceTree = "<group>"; };
                2E5C770C1FA7D429005932C3 /* APIAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = APIAttachment.h; sourceTree = "<group>"; };
                2E5C770D1FA7D429005932C3 /* APIAttachment.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = APIAttachment.cpp; sourceTree = "<group>"; };
                2E7A94491BBD95C600945547 /* _WKFocusedElementInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKFocusedElementInfo.h; sourceTree = "<group>"; };
                57DCEDC6214F18300016B847 /* MockLocalConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MockLocalConnection.mm; sourceTree = "<group>"; };
                57DCEDC9214F4E420016B847 /* MockAuthenticatorManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockAuthenticatorManager.h; sourceTree = "<group>"; };
                57DCEDCD214F51680016B847 /* MockAuthenticatorManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MockAuthenticatorManager.cpp; sourceTree = "<group>"; };
+               587743A421C30AD800AE9084 /* HTTPSUpgradeList.db */ = {isa = PBXFileReference; lastKnownFileType = file; name = HTTPSUpgradeList.db; path = DerivedSources/WebKit2/HTTPSUpgradeList.db; sourceTree = BUILT_PRODUCTS_DIR; };
                58E977DC21C499FE005D92A6 /* NetworkHTTPSUpgradeChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkHTTPSUpgradeChecker.cpp; sourceTree = "<group>"; };
                58E977DD21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkHTTPSUpgradeChecker.h; sourceTree = "<group>"; };
-               587743A421C30AD800AE9084 /* HTTPSUpgradeList.db */ = {isa = PBXFileReference; lastKnownFileType = file; name = HTTPSUpgradeList.db; path = DerivedSources/WebKit2/HTTPSUpgradeList.db; sourceTree = BUILT_PRODUCTS_DIR; };
                5C0B17741E7C879C00E9123C /* NetworkSocketStreamMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkSocketStreamMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkSocketStreamMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
                5C0B17751E7C879C00E9123C /* NetworkSocketStreamMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkSocketStreamMessages.h; path = DerivedSources/WebKit2/NetworkSocketStreamMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
                5C0B17761E7C879C00E9123C /* WebSocketStreamMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebSocketStreamMessageReceiver.cpp; path = DerivedSources/WebKit2/WebSocketStreamMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
                                00B9661718E25AE100CE1F88 /* FindClient.mm */,
                                CD78E1131DB7D7ED0014A2DE /* FullscreenClient.h */,
                                CD78E1121DB7D7ED0014A2DE /* FullscreenClient.mm */,
+                               2E2B3BA421D4879000538EDF /* GlobalFindInPageState.h */,
+                               2E2B3BA321D4879000538EDF /* GlobalFindInPageState.mm */,
                                51C0C9721DDD74F00032CAD3 /* IconLoadingDelegate.h */,
                                51C0C9731DDD74F00032CAD3 /* IconLoadingDelegate.mm */,
                                0F0C365918C0555800F607D7 /* LayerRepresentation.h */,
index 4b5a6d3..4720b71 100644 (file)
@@ -173,6 +173,7 @@ private:
     int getPasteboardItemsCount() final;
     RefPtr<WebCore::DocumentFragment> documentFragmentFromDelegate(int index) final;
     bool performsTwoStepPaste(WebCore::DocumentFragment*) final;
+    void updateStringForFind(const String&) final;
 #endif
 
     bool performTwoStepDrop(WebCore::DocumentFragment&, WebCore::Range&, bool isMove) final;
index c60438c..00b871e 100644 (file)
@@ -86,6 +86,11 @@ bool WebEditorClient::performsTwoStepPaste(WebCore::DocumentFragment*)
     return false;
 }
 
+void WebEditorClient::updateStringForFind(const String& findString)
+{
+    m_page->updateStringForFind(findString);
+}
+
 void WebEditorClient::overflowScrollPositionChanged()
 {
     m_page->didChangeSelection();
index 267a983..d8b8b30 100644 (file)
@@ -939,6 +939,8 @@ public:
     const WebCore::ViewportConfiguration& viewportConfiguration() const { return m_viewportConfiguration; }
 
     void hardwareKeyboardAvailabilityChanged();
+
+    void updateStringForFind(const String&);
 #endif
 
 #if ENABLE(IOS_TOUCH_EVENTS)
index 9065805..b0f2d18 100644 (file)
@@ -3125,6 +3125,11 @@ void WebPage::hardwareKeyboardAvailabilityChanged()
         focusedFrame->eventHandler().capsLockStateMayHaveChanged();
 }
 
+void WebPage::updateStringForFind(const String& findString)
+{
+    send(Messages::WebPageProxy::UpdateStringForFind(findString));
+}
+
 #if USE(QUICK_LOOK)
 void WebPage::didReceivePasswordForQuickLookDocument(const String& password)
 {
index 3ebfcc8..1372daf 100644 (file)
@@ -1,3 +1,15 @@
+2019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for using the current text selection as the find string on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193034
+        <rdar://problem/45138739>
+
+        Reviewed by Tim Horton.
+
+        Add a method stub for WebKitLegacy.
+
+        * WebCoreSupport/WebEditorClient.h:
+
 2019-01-01  Jeff Miller  <jeffm@apple.com>
 
         Update user-visible copyright strings to include 2019
index 8464059..f0f968b 100644 (file)
@@ -144,6 +144,7 @@ private:
     int getPasteboardItemsCount() final;
     RefPtr<WebCore::DocumentFragment> documentFragmentFromDelegate(int index) final;
     bool performsTwoStepPaste(WebCore::DocumentFragment*) final;
+    void updateStringForFind(const String&) final { }
 #endif
 
     bool performTwoStepDrop(WebCore::DocumentFragment&, WebCore::Range& destination, bool isMove) final;
index b37e4d4..6693eaf 100644 (file)
@@ -1,3 +1,17 @@
+2019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add support for using the current text selection as the find string on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193034
+        <rdar://problem/45138739>
+
+        Reviewed by Tim Horton.
+
+        Add a new API test to verify that the new WebKit SPI (_stringForFind, _takeFindStringFromSelection:, and
+        _setStringForFind) works as expected.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/UseSelectionAsFindString.mm: Added.
+
 2019-01-02  Aakash Jain  <aakash_jain@apple.com>
 
         [ews-build] Use git on OpenSource EWS bots
index 2314328..bcdd2cf 100644 (file)
                2E92B8F7216490D4005B64F0 /* rich-text-attributes.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E92B8F6216490C3005B64F0 /* rich-text-attributes.html */; };
                2E92B8FA2164A0C1005B64F0 /* FontAttributes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E92B8F8216490EA005B64F0 /* FontAttributes.mm */; };
                2E9896151D8F093800739892 /* text-and-password-inputs.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E9896141D8F092B00739892 /* text-and-password-inputs.html */; };
+               2EB242B821D4140B0055C1C0 /* UseSelectionAsFindString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E133B4F21D40AF000ED1CB2 /* UseSelectionAsFindString.mm */; };
                2EB29D5E1F762DB90023A5F1 /* dump-datatransfer-types.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2EB29D5D1F762DA50023A5F1 /* dump-datatransfer-types.html */; };
                2EBD9D0A2134730D002DA758 /* video.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07CD32F72065B72A0064A4BE /* video.html */; };
                2ECFF5551D9B12F800B55394 /* NowPlayingControlsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2ECFF5541D9B12F800B55394 /* NowPlayingControlsTests.mm */; };
                2DE71AFF1D49C2F000904094 /* blinking-div.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "blinking-div.html"; sourceTree = "<group>"; };
                2DFF7B6C1DA487AF00814614 /* SnapshotStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SnapshotStore.mm; sourceTree = "<group>"; };
                2E131C171D83A97E001BA36C /* wide-autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "wide-autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
+               2E133B4F21D40AF000ED1CB2 /* UseSelectionAsFindString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UseSelectionAsFindString.mm; sourceTree = "<group>"; };
                2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
                2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-after-ending.html"; sourceTree = "<group>"; };
                2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-hides-controls-after-seek-to-end.html"; sourceTree = "<group>"; };
                                7CCB99201D3B41F6003922F6 /* UserInitiatedActionInNavigationAction.mm */,
                                07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */,
                                07F4E92D20AF58D3002E3803 /* UserMediaSimulateFailedSandbox.mm */,
+                               2E133B4F21D40AF000ED1CB2 /* UseSelectionAsFindString.mm */,
                                93E943F11CD3E87E00AC08C2 /* VideoControlsManager.mm */,
                                CD3065DF2165682E00E895DF /* VideoQualityDisplayCompositing.mm */,
                                6356FB211EC4E0BA0044BF18 /* VisibleContentRect.mm */,
                                0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */,
                                07F4E92E20AF59E2002E3803 /* UserMediaSimulateFailedSandbox.mm in Sources */,
                                7CCE7F181A411AE600447C4C /* UserMessage.cpp in Sources */,
+                               2EB242B821D4140B0055C1C0 /* UseSelectionAsFindString.mm in Sources */,
                                7C83E03A1D0A602700FEBCF3 /* UtilitiesCocoa.mm in Sources */,
                                7C83E0C61D0A654E00FEBCF3 /* VideoControlsManager.mm in Sources */,
                                CD3065E02165682E00E895DF /* VideoQualityDisplayCompositing.mm in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/UseSelectionAsFindString.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/UseSelectionAsFindString.mm
new file mode 100644 (file)
index 0000000..398ceca
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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"
+
+#if WK_API_ENABLED
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+
+namespace TestWebKitAPI {
+
+TEST(WebKit, UseSelectionAsFindString)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    [webView synchronouslyLoadHTMLString:@"<body>Hello <span id='text'>world</span></body>"];
+    [webView evaluateJavaScript:@"getSelection().selectAllChildren(text)" completionHandler:nil];
+    [webView _takeFindStringFromSelection:nil];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_WK_STREQ("world", WKWebView._stringForFind);
+    [WKWebView _setStringForFind:@"testing"];
+    EXPECT_WK_STREQ("testing", [WKWebView _stringForFind]);
+
+#if PLATFORM(IOS_FAMILY)
+    [webView _findString:@"foo" options:0 maxCount:10];
+    EXPECT_WK_STREQ("foo", [WKWebView _stringForFind]);
+#endif
+}
+
+} // namespace TestWebKitAPI
+
+#endif // WK_API_ENABLED