[iOS] Present an action sheet when long-pressing on PDF links
https://bugs.webkit.org/show_bug.cgi?id=185093
<rdar://problem/39356651>
Reviewed by Dan Bernstein.
* UIProcess/ios/WKPDFView.mm:
(-[WKPDFView dealloc]):
Called -[WKActionSheetAssistant cleanupSheet].
(-[WKPDFView web_setContentProviderData:suggestedFilename:]):
Created a WKActionSheetAssistant with the host view as the assistant view and
ourselves as the delegate.
(-[WKPDFView _URLWithPageIndex:]):
Added. Creates a URL to the current page with a page number fragment appended.
(-[WKPDFView _goToURL:atLocation:]):
Added. Navigates to a URL with a synthetic mouse click at a location in host view
coordinates.
(-[WKPDFView pdfHostViewController:goToURL:]):
(-[WKPDFView pdfHostViewController:goToPageIndex:withViewFrustum:]):
Called -_goToURL:atLocation:. Used -_URLWithPageIndex: to construct an NSURL from
a page index.
(-[WKPDFView _showActionSheetForURL:atLocation:]):
Added. Populates _positionInformation with a URL and location and calls
-[WKActionSheetAssistant showLinkSheet].
(-[WKPDFView pdfHostViewController:didLongPressURL:atLocation:]):
(-[WKPDFView pdfHostViewController:didLongPressPageIndex:atLocation:]):
Called -_showActionSheetForURL:atLocation:. Used -_URLWithPageIndex: to construct
an NSURL from a page index.
(-[WKPDFView positionInformationForActionSheetAssistant:]):
Returned _positionInformation.
(-[WKPDFView actionSheetAssistant:performAction:]):
Populated the pasteboard with plain text and URL representations of
_positionInformation.url.
(-[WKPDFView actionSheetAssistant:openElementAtLocation:]):
Called -_goToURL:atLocation.
(-[WKPDFView actionSheetAssistant:shareElementWithURL:rect:]):
Created a UIWKSelectionAssistant and called -showShareSheetFor:fromRect:.
(-[WKPDFView actionSheetAssistant:shouldIncludeAppLinkActionsForElement:]):
Returned API::UIClient::shouldIncludeAppLinkActionsForElement().
(-[WKPDFView actionSheetAssistant:decideActionsForElement:defaultActions:]):
Returned API::UIClient::actionsForElement()l
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@231144 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 9f66cac..2ca3cdf 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,5 +1,74 @@
2018-04-28 Andy Estes <aestes@apple.com>
+ [iOS] Present an action sheet when long-pressing on PDF links
+ https://bugs.webkit.org/show_bug.cgi?id=185093
+ <rdar://problem/39356651>
+
+ Reviewed by Dan Bernstein.
+
+ * UIProcess/ios/WKPDFView.mm:
+ (-[WKPDFView dealloc]):
+
+ Called -[WKActionSheetAssistant cleanupSheet].
+
+ (-[WKPDFView web_setContentProviderData:suggestedFilename:]):
+
+ Created a WKActionSheetAssistant with the host view as the assistant view and
+ ourselves as the delegate.
+
+ (-[WKPDFView _URLWithPageIndex:]):
+
+ Added. Creates a URL to the current page with a page number fragment appended.
+
+ (-[WKPDFView _goToURL:atLocation:]):
+
+ Added. Navigates to a URL with a synthetic mouse click at a location in host view
+ coordinates.
+
+ (-[WKPDFView pdfHostViewController:goToURL:]):
+ (-[WKPDFView pdfHostViewController:goToPageIndex:withViewFrustum:]):
+
+ Called -_goToURL:atLocation:. Used -_URLWithPageIndex: to construct an NSURL from
+ a page index.
+
+ (-[WKPDFView _showActionSheetForURL:atLocation:]):
+
+ Added. Populates _positionInformation with a URL and location and calls
+ -[WKActionSheetAssistant showLinkSheet].
+
+ (-[WKPDFView pdfHostViewController:didLongPressURL:atLocation:]):
+ (-[WKPDFView pdfHostViewController:didLongPressPageIndex:atLocation:]):
+
+ Called -_showActionSheetForURL:atLocation:. Used -_URLWithPageIndex: to construct
+ an NSURL from a page index.
+
+ (-[WKPDFView positionInformationForActionSheetAssistant:]):
+
+ Returned _positionInformation.
+
+ (-[WKPDFView actionSheetAssistant:performAction:]):
+
+ Populated the pasteboard with plain text and URL representations of
+ _positionInformation.url.
+
+ (-[WKPDFView actionSheetAssistant:openElementAtLocation:]):
+
+ Called -_goToURL:atLocation.
+
+ (-[WKPDFView actionSheetAssistant:shareElementWithURL:rect:]):
+
+ Created a UIWKSelectionAssistant and called -showShareSheetFor:fromRect:.
+
+ (-[WKPDFView actionSheetAssistant:shouldIncludeAppLinkActionsForElement:]):
+
+ Returned API::UIClient::shouldIncludeAppLinkActionsForElement().
+
+ (-[WKPDFView actionSheetAssistant:decideActionsForElement:defaultActions:]):
+
+ Returned API::UIClient::actionsForElement()l
+
+2018-04-28 Andy Estes <aestes@apple.com>
+
[iOS] Allow com.apple.WebKit.Networking to look up com.apple.wifi.manager
https://bugs.webkit.org/show_bug.cgi?id=185114
<rdar://problem/39808763>
diff --git a/Source/WebKit/UIProcess/ios/WKPDFView.mm b/Source/WebKit/UIProcess/ios/WKPDFView.mm
index 0d60750..2a0c100 100644
--- a/Source/WebKit/UIProcess/ios/WKPDFView.mm
+++ b/Source/WebKit/UIProcess/ios/WKPDFView.mm
@@ -28,20 +28,24 @@
#if ENABLE(WKPDFVIEW)
+#import "APIUIClient.h"
#import "FindClient.h"
+#import "WKActionSheetAssistant.h"
#import "WKWebViewInternal.h"
#import "WeakObjCPtr.h"
#import "WebPageProxy.h"
#import "_WKWebViewPrintFormatterInternal.h"
#import <PDFKit/PDFHostViewController.h>
+#import <WebCore/WebCoreNSURLExtras.h>
#import <wtf/BlockPtr.h>
#import <wtf/MainThread.h>
#import <wtf/RetainPtr.h>
-@interface WKPDFView () <PDFHostViewControllerDelegate>
+@interface WKPDFView () <PDFHostViewControllerDelegate, WKActionSheetAssistantDelegate>
@end
@implementation WKPDFView {
+ RetainPtr<WKActionSheetAssistant> _actionSheetAssistant;
RetainPtr<NSData> _data;
BlockPtr<void()> _findCompletion;
RetainPtr<NSString> _findString;
@@ -53,12 +57,14 @@
RetainPtr<PDFHostViewController> _hostViewController;
CGSize _overlaidAccessoryViewsInset;
RetainPtr<UIView> _pageNumberIndicator;
+ WebKit::InteractionInformationAtPosition _positionInformation;
RetainPtr<NSString> _suggestedFilename;
WebKit::WeakObjCPtr<WKWebView> _webView;
}
- (void)dealloc
{
+ [_actionSheetAssistant cleanupSheet];
[[_hostViewController view] removeFromSuperview];
[_pageNumberIndicator removeFromSuperview];
[super dealloc];
@@ -107,6 +113,9 @@
[self removeFromSuperview];
[scrollView addSubview:hostView];
+ _actionSheetAssistant = adoptNS([[WKActionSheetAssistant alloc] initWithView:hostView]);
+ [_actionSheetAssistant setDelegate:self];
+
_pageNumberIndicator = hostViewController.pageNumberIndicator;
[_fixedOverlayView addSubview:_pageNumberIndicator.get()];
@@ -362,27 +371,109 @@
findCompletion();
}
-- (void)pdfHostViewController:(PDFHostViewController *)controller goToURL:(NSURL *)url
+- (NSURL *)_URLWithPageIndex:(NSInteger)pageIndex
{
- WKWebView *webView = _webView.getAutoreleased();
- if (!webView)
+ return [NSURL URLWithString:[NSString stringWithFormat:@"#page%ld", (long)pageIndex + 1] relativeToURL:[_webView URL]];
+}
+
+- (void)_goToURL:(NSURL *)url atLocation:(CGPoint)location
+{
+ auto page = [_webView _page];
+ if (!page)
return;
+ UIView *hostView = [_hostViewController view];
+ CGPoint locationInScreen = [hostView.window convertPoint:[hostView convertPoint:location toView:nil] toWindow:nil];
+ page->navigateToPDFLinkWithSimulatedClick(url.absoluteString, WebCore::roundedIntPoint(location), WebCore::roundedIntPoint(locationInScreen));
+}
+
+- (void)pdfHostViewController:(PDFHostViewController *)controller goToURL:(NSURL *)url
+{
// FIXME: We'd use the real tap location if we knew it.
- WebCore::IntPoint point;
- webView->_page->navigateToPDFLinkWithSimulatedClick(url.absoluteString, point, point);
+ [self _goToURL:url atLocation:CGPointMake(0, 0)];
}
- (void)pdfHostViewController:(PDFHostViewController *)controller goToPageIndex:(NSInteger)pageIndex withViewFrustum:(CGRect)documentViewRect
{
+ [self _goToURL:[self _URLWithPageIndex:pageIndex] atLocation:documentViewRect.origin];
+}
+
+- (void)_showActionSheetForURL:(NSURL *)url atLocation:(CGPoint)location
+{
WKWebView *webView = _webView.getAutoreleased();
if (!webView)
return;
- NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"#page%ld", (long)pageIndex + 1] relativeToURL:webView.URL];
- CGPoint documentPoint = documentViewRect.origin;
- CGPoint screenPoint = [self.window convertPoint:[self convertPoint:documentPoint toView:nil] toWindow:nil];
- webView->_page->navigateToPDFLinkWithSimulatedClick(url.absoluteString, WebCore::roundedIntPoint(documentPoint), WebCore::roundedIntPoint(screenPoint));
+ CGPoint locationInHostView = [webView.scrollView convertPoint:location toView:[_hostViewController view]];
+
+ WebKit::InteractionInformationAtPosition positionInformation;
+ positionInformation.bounds = WebCore::roundedIntRect(CGRect { locationInHostView, CGSizeMake(0, 0) });
+ positionInformation.request.point = WebCore::roundedIntPoint(locationInHostView);
+ positionInformation.url = url;
+
+ _positionInformation = WTFMove(positionInformation);
+ [_actionSheetAssistant showLinkSheet];
+}
+
+- (void)pdfHostViewController:(PDFHostViewController *)controller didLongPressURL:(NSURL *)url atLocation:(CGPoint)location
+{
+ [self _showActionSheetForURL:url atLocation:location];
+}
+
+- (void)pdfHostViewController:(PDFHostViewController *)controller didLongPressPageIndex:(NSInteger)pageIndex atLocation:(CGPoint)location
+{
+ [self _showActionSheetForURL:[self _URLWithPageIndex:pageIndex] atLocation:location];
+}
+
+#pragma mark WKActionSheetAssistantDelegate
+
+- (std::optional<WebKit::InteractionInformationAtPosition>)positionInformationForActionSheetAssistant:(WKActionSheetAssistant *)assistant
+{
+ return _positionInformation;
+}
+
+- (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant performAction:(WebKit::SheetAction)action
+{
+ if (action != WebKit::SheetAction::Copy)
+ return;
+
+ NSDictionary *representations = @{
+ (NSString *)kUTTypeUTF8PlainText : (NSString *)_positionInformation.url,
+ (NSString *)kUTTypeURL : (NSURL *)_positionInformation.url,
+ };
+
+ [UIPasteboard generalPasteboard].items = @[ representations ];
+}
+
+- (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant openElementAtLocation:(CGPoint)location
+{
+ [self _goToURL:_positionInformation.url atLocation:location];
+}
+
+- (void)actionSheetAssistant:(WKActionSheetAssistant *)assistant shareElementWithURL:(NSURL *)url rect:(CGRect)boundingRect
+{
+ auto selectionAssistant = adoptNS([[UIWKSelectionAssistant alloc] initWithView:[_hostViewController view]]);
+ [selectionAssistant showShareSheetFor:WebCore::userVisibleString(url) fromRect:boundingRect];
+}
+
+#if HAVE(APP_LINKS)
+- (BOOL)actionSheetAssistant:(WKActionSheetAssistant *)assistant shouldIncludeAppLinkActionsForElement:(_WKActivatedElementInfo *)element
+{
+ auto page = [_webView _page];
+ if (!page)
+ return NO;
+
+ return page->uiClient().shouldIncludeAppLinkActionsForElement(element);
+}
+#endif
+
+- (RetainPtr<NSArray>)actionSheetAssistant:(WKActionSheetAssistant *)assistant decideActionsForElement:(_WKActivatedElementInfo *)element defaultActions:(RetainPtr<NSArray>)defaultActions
+{
+ auto page = [_webView _page];
+ if (!page)
+ return nil;
+
+ return page->uiClient().actionsForElement(element, WTFMove(defaultActions));
}
@end