Skip to content

Commit

Permalink
[UnifiedPDF] [iOS] Add support for Share/Translate with selected text
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=284646
rdar://141448279

Reviewed by Abrar Rahman Protyasha and Aditya Keerthi.

Add support for extracting text from unified PDF plugins, so that text services on iOS (e.g.
translate, share, look up) work properly.

* Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.h:
(WebKit::PDFPluginBase::fullDocumentString const):
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.h:
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.mm:
(WebKit::UnifiedPDFPlugin::fullDocumentString const):
* Source/WebKit/WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::fullDocumentString const):
* Source/WebKit/WebProcess/Plugins/PluginView.h:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::getSelectionOrContentsAsString):

Defer to the PDF plugin if needed — this returns the `selectionString()` if present, and otherwise
falls back to `fullDocumentString()` if there is no selection.

* Tools/TestWebKitAPI/Tests/WebKitCocoa/UnifiedPDFTests.mm:
(TestWebKitAPI::UNIFIED_PDF_TEST):
* Tools/TestWebKitAPI/cocoa/TestWKWebView.h:
* Tools/TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[TestWKWebView textForSpeakSelection]):

Add a new API test hook to synchronously request the text content for "Speak Selection".

(-[TestWKWebView _accessibilityDidGetSpeakSelectionContent:]):

Use the above testing helper to verify that "Speak Selection" (which exercises this same codepath)
now works when Unified PDF is enabled.

Canonical link: https://commits.webkit.org/287819@main
  • Loading branch information
whsieh committed Dec 13, 2024
1 parent 591e9b7 commit cfd8332
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions Source/WebKit/WebProcess/Plugins/PDF/PDFPluginBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class PDFPluginBase : public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr<PDF
virtual bool handleEditingCommand(const String& commandName, const String& argument) = 0;
virtual bool isEditingCommandEnabled(const String& commandName) = 0;

virtual String fullDocumentString() const { return { }; }
virtual String selectionString() const = 0;
virtual bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const = 0;
virtual WebCore::FloatRect rectForSelectionInRootView(PDFSelection *) const = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ class UnifiedPDFPlugin final : public PDFPluginBase, public WebCore::GraphicsLay
void repaintOnSelectionChange(ActiveStateChangeReason, PDFSelection *previousSelection = nil);
void showOrHideSelectionLayerAsNecessary();

String fullDocumentString() const override;
String selectionString() const override;
bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override;
WebCore::FloatRect rectForSelectionInRootView(PDFSelection *) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,11 @@ static FloatRect computeMarqueeSelectionRect(const WebCore::FloatPoint& point1,
notifySelectionChanged();
}

String UnifiedPDFPlugin::fullDocumentString() const
{
return [pdfDocument() string];
}

String UnifiedPDFPlugin::selectionString() const
{
if (!m_currentSelection)
Expand Down
8 changes: 8 additions & 0 deletions Source/WebKit/WebProcess/Plugins/PluginView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,14 @@ void PluginView::scrollToRevealTextMatch(const WebFoundTextRange::PDFData& match
return protectedPlugin()->scrollToRevealTextMatch(match);
}

String PluginView::fullDocumentString() const
{
if (!m_isInitialized)
return { };

return protectedPlugin()->fullDocumentString();
}

String PluginView::selectionString() const
{
if (!m_isInitialized)
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/WebProcess/Plugins/PluginView.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class PluginView final : public WebCore::PluginViewBase {
RefPtr<WebCore::TextIndicator> textIndicatorForTextMatch(const WebFoundTextRange::PDFData&, WebCore::TextIndicatorPresentationTransition);
void scrollToRevealTextMatch(const WebFoundTextRange::PDFData&);

String fullDocumentString() const;
String selectionString() const;

RefPtr<WebCore::FragmentedSharedBuffer> liveResourceData() const;
Expand Down
10 changes: 10 additions & 0 deletions Source/WebKit/WebProcess/WebPage/WebPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4519,6 +4519,16 @@ void WebPage::getSelectionOrContentsAsString(CompletionHandler<void(const String
{
RefPtr focusedOrMainCoreFrame = m_page->checkedFocusController()->focusedOrMainFrame();
RefPtr focusedOrMainFrame = focusedOrMainCoreFrame ? WebFrame::fromCoreFrame(*focusedOrMainCoreFrame) : nullptr;

#if ENABLE(PDF_PLUGIN)
if (RefPtr pluginView = pluginViewForFrame(focusedOrMainCoreFrame.get())) {
auto result = pluginView->selectionString();
if (result.isEmpty())
result = pluginView->fullDocumentString();
return callback(WTFMove(result));
}
#endif

String resultString = focusedOrMainFrame->selectionAsString();
if (resultString.isEmpty())
resultString = focusedOrMainFrame->contentsAsString();
Expand Down
12 changes: 12 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/UnifiedPDFTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,18 @@ - (bool)navigationFinished
EXPECT_FALSE([delegate webProcessCrashed]);
}

#if PLATFORM(IOS_FAMILY)

UNIFIED_PDF_TEST(SpeakSelection)
{
RetainPtr webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 600, 600) configuration:configurationForWebViewTestingUnifiedPDF().get()]);
[webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:[NSBundle.test_resourcesBundle URLForResource:@"test" withExtension:@"pdf"]]];

EXPECT_WK_STREQ(@"Test PDF Content\n555-555-1234", [webView textForSpeakSelection]);
}

#endif // PLATFORM(IOS_FAMILY)

#if HAVE(UIKIT_WITH_MOUSE_SUPPORT)

UNIFIED_PDF_TEST(MouseDidMoveOverPDF)
Expand Down
1 change: 1 addition & 0 deletions Tools/TestWebKitAPI/cocoa/TestWKWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ struct AutocorrectionContext {
@property (nonatomic) UIEdgeInsets overrideSafeAreaInset;
@property (nonatomic, readonly) CGRect caretViewRectInContentCoordinates;
@property (nonatomic, readonly) NSArray<NSValue *> *selectionViewRectsInContentCoordinates;
@property (nonatomic, readonly) NSString *textForSpeakSelection;
- (_WKActivatedElementInfo *)activatedElementAtPosition:(CGPoint)position;
- (void)evaluateJavaScriptAndWaitForInputSessionToChange:(NSString *)script;
- (WKContentView *)wkContentView;
Expand Down
18 changes: 18 additions & 0 deletions Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,8 @@ @implementation TestWKWebView {
#if PLATFORM(IOS_FAMILY)
InputSessionChangeCount _inputSessionChangeCount;
UIEdgeInsets _overrideSafeAreaInset;
RetainPtr<NSString> _textForSpeakSelection;
bool _doneWaitingForSpeakSelectionContent;
#endif
#if PLATFORM(MAC)
BOOL _forceWindowToBecomeKey;
Expand Down Expand Up @@ -1130,6 +1132,22 @@ - (void)focus

#if PLATFORM(IOS_FAMILY)

- (NSString *)textForSpeakSelection
{
_textForSpeakSelection = { };
_doneWaitingForSpeakSelectionContent = false;
[self _accessibilityRetrieveSpeakSelectionContent];

TestWebKitAPI::Util::run(&_doneWaitingForSpeakSelectionContent);
return _textForSpeakSelection.get();
}

- (void)_accessibilityDidGetSpeakSelectionContent:(NSString *)content
{
_textForSpeakSelection = adoptNS(content.copy);
_doneWaitingForSpeakSelectionContent = true;
}

- (void)didStartFormControlInteraction
{
_inputSessionChangeCount = nextInputSessionChangeCount();
Expand Down

0 comments on commit cfd8332

Please sign in to comment.