Allow NavigationState to intercept requests and send them to SystemPreviewController
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2018 23:39:19 +0000 (23:39 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2018 23:39:19 +0000 (23:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183526
<rdar://problem/37801140>

Reviewed by Tim Horton.

Implement a bit more of SystemPreviewController, such that it can be used
from NavigationState to identify and handle content that can be previewed.

* UIProcess/Cocoa/NavigationState.mm:
(WebKit::NavigationState::NavigationClient::decidePolicyForNavigationResponse):
    If we'd in a download response policy, then check if SystemPreviewController
    can show the content. We ignore the download, but pass the original URL onto
    the preview. Ultimately, we'd want to avoid the navigation
    but use the download destination URL for preview.

* UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
(-[_WKPreviewControllerDataSource initWithURL:]):
    Move the URL to property, to help use a single datasource object for all previews.
(-[_WKPreviewControllerDataSource previewController:previewItemAtIndex:]):
(-[_WKPreviewControllerDelegate initWithSystemPreviewController:]):
    Add a delegate object, so we can detect when the preview is dismissed and return
    to the previous page.
(-[_WKPreviewControllerDelegate previewControllerWillDismiss:]):
(WebKit::SystemPreviewController::showPreview):
    Use single instances of the QLPreviewController, its datasource and delegate.

* UIProcess/SystemPreviewController.cpp:
    Add a helper to navigate back.
(WebKit::SystemPreviewController::SystemPreviewController):
(WebKit::SystemPreviewController::sendPageBack):
* UIProcess/SystemPreviewController.h:

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Cocoa/NavigationState.mm
Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm
Source/WebKit/UIProcess/SystemPreviewController.cpp
Source/WebKit/UIProcess/SystemPreviewController.h

index e911567..f840099 100644 (file)
@@ -1,3 +1,38 @@
+2018-03-09  Dean Jackson  <dino@apple.com>
+
+        Allow NavigationState to intercept requests and send them to SystemPreviewController
+        https://bugs.webkit.org/show_bug.cgi?id=183526
+        <rdar://problem/37801140>
+
+        Reviewed by Tim Horton.
+
+        Implement a bit more of SystemPreviewController, such that it can be used
+        from NavigationState to identify and handle content that can be previewed.
+
+        * UIProcess/Cocoa/NavigationState.mm:
+        (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationResponse):
+            If we'd in a download response policy, then check if SystemPreviewController
+            can show the content. We ignore the download, but pass the original URL onto
+            the preview. Ultimately, we'd want to avoid the navigation
+            but use the download destination URL for preview.
+
+        * UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
+        (-[_WKPreviewControllerDataSource initWithURL:]):
+            Move the URL to property, to help use a single datasource object for all previews.
+        (-[_WKPreviewControllerDataSource previewController:previewItemAtIndex:]):
+        (-[_WKPreviewControllerDelegate initWithSystemPreviewController:]):
+            Add a delegate object, so we can detect when the preview is dismissed and return
+            to the previous page.
+        (-[_WKPreviewControllerDelegate previewControllerWillDismiss:]):
+        (WebKit::SystemPreviewController::showPreview):
+            Use single instances of the QLPreviewController, its datasource and delegate.
+
+        * UIProcess/SystemPreviewController.cpp:
+            Add a helper to navigate back.
+        (WebKit::SystemPreviewController::SystemPreviewController):
+        (WebKit::SystemPreviewController::sendPageBack):
+        * UIProcess/SystemPreviewController.h:
+
 2018-03-09  Jer Noble  <jer.noble@apple.com>
 
         webkitfullscreenchange event not fired at the same time as :-webkit-full-screen pseudo selector changes; causes glitchiness
index 3eee7d1..978a102 100644 (file)
@@ -607,7 +607,7 @@ void NavigationState::NavigationClient::contentRuleListNotification(WebPageProxy
     [(id <WKNavigationDelegatePrivate>)navigationDelegate _webView:m_navigationState.m_webView URL:url contentRuleListIdentifiers:identifiers.get() notifications:nsNotifications.get()];
 }
     
-void NavigationState::NavigationClient::decidePolicyForNavigationResponse(WebPageProxy&, Ref<API::NavigationResponse>&& navigationResponse, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData)
+void NavigationState::NavigationClient::decidePolicyForNavigationResponse(WebPageProxy& page, Ref<API::NavigationResponse>&& navigationResponse, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData)
 {
     if (!m_navigationState.m_navigationDelegateMethods.webViewDecidePolicyForNavigationResponseDecisionHandler) {
         NSURL *url = navigationResponse->response().nsURLResponse().URL;
@@ -635,7 +635,8 @@ void NavigationState::NavigationClient::decidePolicyForNavigationResponse(WebPag
 
     RefPtr<WebFramePolicyListenerProxy> localListener = WTFMove(listener);
     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(navigationDelegate.get(), @selector(webView:decidePolicyForNavigationResponse:decisionHandler:));
-    [navigationDelegate webView:m_navigationState.m_webView decidePolicyForNavigationResponse:wrapper(navigationResponse) decisionHandler:[localListener, checker](WKNavigationResponsePolicy responsePolicy) {
+    RefPtr<API::NavigationResponse> navigationResponseRefPtr(navigationResponse.ptr());
+    [navigationDelegate webView:m_navigationState.m_webView decidePolicyForNavigationResponse:wrapper(navigationResponse) decisionHandler:[localListener, checker, navigationResponse = WTFMove(navigationResponseRefPtr), &page](WKNavigationResponsePolicy responsePolicy) {
         if (checker->completionHandlerHasBeenCalled())
             return;
         checker->didCallCompletionHandler();
@@ -653,8 +654,12 @@ void NavigationState::NavigationClient::decidePolicyForNavigationResponse(WebPag
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wswitch"
         case _WKNavigationResponsePolicyBecomeDownload:
+            if (page.systemPreviewController()->canPreview(navigationResponse->response().mimeType())) {
+                page.systemPreviewController()->showPreview(navigationResponse->response().url());
+                localListener->ignore();
+            } else
+                localListener->download();
 #pragma clang diagnostic pop
-            localListener->download();
             break;
         }
     }];
index 015bafa..52be6e6 100644 (file)
@@ -43,8 +43,10 @@ SOFT_LINK_FRAMEWORK(QuickLook)
 SOFT_LINK_CLASS(QuickLook, QLPreviewController);
 
 @interface _WKPreviewControllerDataSource : NSObject <QLPreviewControllerDataSource> {
-    WebCore::URL _url;
 };
+
+@property (nonatomic) WebCore::URL url;
+
 @end
 
 @implementation _WKPreviewControllerDataSource
@@ -54,7 +56,7 @@ SOFT_LINK_CLASS(QuickLook, QLPreviewController);
     if (!(self = [super init]))
         return nil;
 
-    _url = url;
+    self.url = url;
     return self;
 }
 
@@ -65,11 +67,34 @@ SOFT_LINK_CLASS(QuickLook, QLPreviewController);
 
 - (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index
 {
-    return (NSURL*)self->_url;
+    return (NSURL*)self.url;
 }
 
 @end
 
+@interface _WKPreviewControllerDelegate : NSObject <QLPreviewControllerDelegate> {
+    WebKit::SystemPreviewController* _previewController;
+};
+@end
+
+@implementation _WKPreviewControllerDelegate
+
+- (id)initWithSystemPreviewController:(WebKit::SystemPreviewController*)previewController
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _previewController = previewController;
+    return self;
+}
+
+- (void)previewControllerWillDismiss:(QLPreviewController *)controller
+{
+    if (_previewController)
+        _previewController->sendPageBack();
+}
+@end
+
 namespace WebKit {
 
 bool SystemPreviewController::canPreview(const String& mimeType) const
@@ -91,12 +116,20 @@ void SystemPreviewController::showPreview(const WebCore::URL& url)
     if (!presentingViewController)
         return;
 
-    RetainPtr<QLPreviewController> qlPreviewController = adoptNS([allocQLPreviewControllerInstance() init]);
-    RetainPtr<_WKPreviewControllerDataSource> dataSource = adoptNS([[_WKPreviewControllerDataSource alloc] initWithURL:url]);
+    if (!m_qlPreviewController) {
+        m_qlPreviewController = adoptNS([allocQLPreviewControllerInstance() init]);
+
+        m_qlPreviewControllerDelegate = adoptNS([[_WKPreviewControllerDelegate alloc] initWithSystemPreviewController:this]);
+        [m_qlPreviewController setDelegate:m_qlPreviewControllerDelegate.get()];
+
+        m_qlPreviewControllerDataSource = adoptNS([[_WKPreviewControllerDataSource alloc] initWithURL:url]);
+        [m_qlPreviewController setDataSource:m_qlPreviewControllerDataSource.get()];
+    } else
+        m_qlPreviewControllerDataSource.get().url = url;
 
-    [qlPreviewController setDataSource:dataSource.get()];
+    [m_qlPreviewController reloadData];
 
-    [presentingViewController presentViewController:qlPreviewController.get() animated:YES completion:nullptr];
+    [presentingViewController presentViewController:m_qlPreviewController.get() animated:YES completion:nullptr];
 }
 
 }
index 5032f24..4b13071 100644 (file)
 #include "config.h"
 #include "SystemPreviewController.h"
 
+#import "WebPageProxy.h"
+
 namespace WebKit {
 
 SystemPreviewController::SystemPreviewController(WebPageProxy& webPageProxy)
     : m_webPageProxy(webPageProxy)
 {
-    (void)m_webPageProxy; // This will be used eventually. Using it here to keep the compiler from complaining.
+}
+
+void SystemPreviewController::sendPageBack()
+{
+    m_webPageProxy.goBack();
 }
 
 #if !PLATFORM(IOS) || !USE(QUICK_LOOK)
index 261d48f..8141810 100644 (file)
 #pragma once
 
 #include <WebCore/URL.h>
+#include <wtf/RetainPtr.h>
+
+#if PLATFORM(IOS) && USE(QUICK_LOOK)
+OBJC_CLASS QLPreviewController;
+OBJC_CLASS _WKPreviewControllerDataSource;
+OBJC_CLASS _WKPreviewControllerDelegate;
+#endif
 
 namespace WebKit {
 
@@ -38,8 +45,16 @@ public:
     bool canPreview(const String& mimeType) const;
     void showPreview(const WebCore::URL&);
 
+    void sendPageBack();
+
 private:
     WebPageProxy& m_webPageProxy;
+
+#if PLATFORM(IOS) && USE(QUICK_LOOK)
+    RetainPtr<QLPreviewController> m_qlPreviewController;
+    RetainPtr<_WKPreviewControllerDelegate> m_qlPreviewControllerDelegate;
+    RetainPtr<_WKPreviewControllerDataSource> m_qlPreviewControllerDataSource;
+#endif
 };
 
 }