Optimized path zoom animation needs a valid UIImage and CGRect
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 May 2018 23:56:01 +0000 (23:56 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 May 2018 23:56:01 +0000 (23:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185883
<rdar://problem/40306056>

Reviewed by Jon Lee.

Source/WebCore:

Pass the bounding box of the element that was clicked onto
the UI process, so it can perform an animation from that spot.

This involved adding an IntRect to the ResourceRequest, and passing
that info into it from the HTMLAnchorElement, using a new struct
called SystemPreviewInfo.

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
* loader/FrameLoadRequest.cpp:
(WebCore::FrameLoadRequest::FrameLoadRequest):
* loader/FrameLoadRequest.h:
(WebCore::FrameLoadRequest::FrameLoadRequest):
(WebCore::FrameLoadRequest::isSystemPreview const):
(WebCore::FrameLoadRequest::systemPreviewRect const):
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::urlSelected):
(WebCore::FrameLoader::loadURL):
* loader/FrameLoader.h:
(WebCore::FrameLoader::urlSelected):
* loader/FrameLoaderTypes.h:
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::systemPreviewRect const):
(WebCore::ResourceRequestBase::setSystemPreviewRect):
* platform/network/ResourceRequestBase.h:

Source/WebKit:

Take the rectangle that was passed into the ResourceRequest and
use it for the origin of an animation into QuickLook.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ResourceRequest>::encode):
(IPC::ArgumentCoder<ResourceRequest>::decode):
* UIProcess/Cocoa/DownloadClient.mm:
(WebKit::DownloadClient::didStart):
* UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
(-[_WKPreviewControllerDelegate initWithSystemPreviewController:fromRect:]):
(-[_WKPreviewControllerDelegate presentingViewController]):
(-[_WKPreviewControllerDelegate previewController:frameForPreviewItem:inSourceView:]):
(-[_WKPreviewControllerDelegate previewController:transitionImageForPreviewItem:contentRect:]):
(WebKit::SystemPreviewController::start):
(-[_WKPreviewControllerDelegate initWithSystemPreviewController:]): Deleted.
* UIProcess/Downloads/DownloadProxy.h:
(WebKit::DownloadProxy::systemPreviewDownloadRect const):
* UIProcess/SystemPreviewController.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::syncRootViewToScreen):
* UIProcess/WebPageProxy.h:

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

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/loader/FrameLoadRequest.cpp
Source/WebCore/loader/FrameLoadRequest.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/FrameLoaderTypes.h
Source/WebCore/platform/network/ResourceRequestBase.cpp
Source/WebCore/platform/network/ResourceRequestBase.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/UIProcess/Cocoa/DownloadClient.mm
Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm
Source/WebKit/UIProcess/Downloads/DownloadProxy.h
Source/WebKit/UIProcess/SystemPreviewController.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h

index 8555c77..a34892f 100644 (file)
@@ -1,3 +1,37 @@
+2018-05-22  Dean Jackson  <dino@apple.com>
+
+        Optimized path zoom animation needs a valid UIImage and CGRect
+        https://bugs.webkit.org/show_bug.cgi?id=185883
+        <rdar://problem/40306056>
+
+        Reviewed by Jon Lee.
+
+        Pass the bounding box of the element that was clicked onto
+        the UI process, so it can perform an animation from that spot.
+
+        This involved adding an IntRect to the ResourceRequest, and passing
+        that info into it from the HTMLAnchorElement, using a new struct
+        called SystemPreviewInfo.
+
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::handleClick):
+        * loader/FrameLoadRequest.cpp:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        * loader/FrameLoadRequest.h:
+        (WebCore::FrameLoadRequest::FrameLoadRequest):
+        (WebCore::FrameLoadRequest::isSystemPreview const):
+        (WebCore::FrameLoadRequest::systemPreviewRect const):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::urlSelected):
+        (WebCore::FrameLoader::loadURL):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::urlSelected):
+        * loader/FrameLoaderTypes.h:
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::systemPreviewRect const):
+        (WebCore::ResourceRequestBase::setSystemPreviewRect):
+        * platform/network/ResourceRequestBase.h:
+
 2018-05-22  Chris Dumez  <cdumez@apple.com>
 
         [POSIX] Use access() instead of stat() in FileSystem::fileExists()
index 89a38c1..c6d57ee 100644 (file)
@@ -417,14 +417,19 @@ void HTMLAnchorElement::handleClick(Event& event)
     }
 #endif
 
-    bool isSystemPreview = false;
+    SystemPreviewInfo systemPreviewInfo;
 #if USE(SYSTEM_PREVIEW)
-    isSystemPreview = isSystemPreviewLink();
+    systemPreviewInfo.isSystemPreview = isSystemPreviewLink();
+
+    if (systemPreviewInfo.isSystemPreview) {
+        if (auto* child = firstElementChild())
+            systemPreviewInfo.systemPreviewRect = child->boundsInRootViewSpace();
+    }
 #endif
 
     ShouldSendReferrer shouldSendReferrer = hasRel(Relation::NoReferrer) ? NeverSendReferrer : MaybeSendReferrer;
     auto newFrameOpenerPolicy = hasRel(Relation::NoOpener) ? std::make_optional(NewFrameOpenerPolicy::Suppress) : std::nullopt;
-    frame->loader().urlSelected(completedURL, target(), &event, LockHistory::No, LockBackForwardList::No, shouldSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, isSystemPreview);
+    frame->loader().urlSelected(completedURL, target(), &event, LockHistory::No, LockBackForwardList::No, shouldSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute, systemPreviewInfo);
 
     sendPings(completedURL);
 }
index c154772..aaacbac 100644 (file)
@@ -37,7 +37,7 @@
 
 namespace WebCore {
 
-FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requesterSecurityOrigin, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, InitiatedByMainFrame initiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute, bool isSystemPreview)
+FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requesterSecurityOrigin, const ResourceRequest& resourceRequest, const String& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, AllowNavigationToInvalidURL allowNavigationToInvalidURL, NewFrameOpenerPolicy newFrameOpenerPolicy, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, InitiatedByMainFrame initiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute, const SystemPreviewInfo& systemPreviewInfo)
     : m_requester { makeRef(requester) }
     , m_requesterSecurityOrigin { makeRef(requesterSecurityOrigin) }
     , m_resourceRequest { resourceRequest }
@@ -51,7 +51,7 @@ FrameLoadRequest::FrameLoadRequest(Document& requester, SecurityOrigin& requeste
     , m_shouldOpenExternalURLsPolicy { shouldOpenExternalURLsPolicy }
     , m_downloadAttribute { downloadAttribute }
     , m_initiatedByMainFrame { initiatedByMainFrame }
-    , m_isSystemPreview { isSystemPreview }
+    , m_systemPreviewInfo { systemPreviewInfo }
 {
 }
 
index d6f10ed..da01eb7 100644 (file)
@@ -38,7 +38,7 @@ class SecurityOrigin;
 
 class FrameLoadRequest {
 public:
-    WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, InitiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { }, bool isSystemPreview = false);
+    WEBCORE_EXPORT FrameLoadRequest(Document&, SecurityOrigin&, const ResourceRequest&, const String& frameName, LockHistory, LockBackForwardList, ShouldSendReferrer, AllowNavigationToInvalidURL, NewFrameOpenerPolicy, ShouldOpenExternalURLsPolicy, InitiatedByMainFrame, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, const AtomicString& downloadAttribute = { }, const SystemPreviewInfo& = { });
     WEBCORE_EXPORT FrameLoadRequest(Frame&, const ResourceRequest&, ShouldOpenExternalURLsPolicy, const SubstituteData& = SubstituteData());
 
     WEBCORE_EXPORT ~FrameLoadRequest();
@@ -87,7 +87,8 @@ public:
     void setIsCrossOriginWindowOpenNavigation(bool value) { m_isCrossOriginWindowOpenNavigation = value; }
     bool isCrossOriginWindowOpenNavigation() const { return m_isCrossOriginWindowOpenNavigation; }
 
-    bool isSystemPreview() const { return m_isSystemPreview; }
+    bool isSystemPreview() const { return m_systemPreviewInfo.isSystemPreview; }
+    const IntRect& systemPreviewRect() const { return m_systemPreviewInfo.systemPreviewRect; }
 
 private:
     Ref<Document> m_requester;
@@ -109,6 +110,7 @@ private:
     InitiatedByMainFrame m_initiatedByMainFrame { InitiatedByMainFrame::Unknown };
     bool m_isCrossOriginWindowOpenNavigation { false };
     bool m_isSystemPreview { false };
+    SystemPreviewInfo m_systemPreviewInfo;
 };
 
 } // namespace WebCore
index 6904394..89d5dc9 100644 (file)
@@ -370,13 +370,13 @@ void FrameLoader::changeLocation(FrameLoadRequest&& request)
     urlSelected(WTFMove(request), nullptr);
 }
 
-void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> openerPolicy, const AtomicString& downloadAttribute, bool isSystemPreview)
+void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> openerPolicy, const AtomicString& downloadAttribute, const SystemPreviewInfo& systemPreviewInfo)
 {
     auto* frame = lexicalFrameFromCommonVM();
     auto initiatedByMainFrame = frame && frame->isMainFrame() ? InitiatedByMainFrame::Yes : InitiatedByMainFrame::Unknown;
 
     NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.value_or(shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
-    urlSelected(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, initiatedByMainFrame, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute, isSystemPreview), triggeringEvent);
+    urlSelected(FrameLoadRequest(*m_frame.document(), m_frame.document()->securityOrigin(), { url }, passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, shouldOpenExternalURLsPolicy, initiatedByMainFrame, DoNotReplaceDocumentIfJavaScriptURL, downloadAttribute, systemPreviewInfo), triggeringEvent);
 }
 
 void FrameLoader::urlSelected(FrameLoadRequest&& frameRequest, Event* triggeringEvent)
@@ -1366,7 +1366,12 @@ void FrameLoader::loadURL(FrameLoadRequest&& frameLoadRequest, const String& ref
 
     // Must grab this now, since this load may stop the previous load and clear this flag.
     bool isRedirect = m_quickRedirectComing;
-    request.setSystemPreview(frameLoadRequest.isSystemPreview());
+#if USE(SYSTEM_PREVIEW)
+    bool isSystemPreview = frameLoadRequest.isSystemPreview();
+    request.setSystemPreview(isSystemPreview);
+    if (isSystemPreview)
+        request.setSystemPreviewRect(frameLoadRequest.systemPreviewRect());
+#endif
     loadWithNavigationAction(request, action, lockHistory, newLoadType, formState, allowNavigationToInvalidURL, [this, isRedirect, sameURL, newLoadType, protectedFrame = makeRef(m_frame), completionHandler = completionHandlerCaller.release()] {
         if (isRedirect) {
             m_quickRedirectComing = false;
index 95e170a..fbc72ec 100644 (file)
@@ -121,7 +121,7 @@ public:
     unsigned long loadResourceSynchronously(const ResourceRequest&, ClientCredentialPolicy, const FetchOptions&, const HTTPHeaderMap&, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>& data);
 
     void changeLocation(FrameLoadRequest&&);
-    WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> = std::nullopt, const AtomicString& downloadAttribute = nullAtom(), bool isSystemPreview = false);
+    WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> = std::nullopt, const AtomicString& downloadAttribute = nullAtom(), const SystemPreviewInfo& = { });
     void submitForm(Ref<FormSubmission>&&);
 
     WEBCORE_EXPORT void reload(OptionSet<ReloadOption> = { });
index 6de1b6f..5d6abf1 100644 (file)
@@ -28,6 +28,8 @@
 
 #pragma once
 
+#include "IntRect.h"
+
 namespace WebCore {
 
 enum FrameState {
@@ -147,6 +149,12 @@ enum class HasInsecureContent {
     No,
 };
 
+
+struct SystemPreviewInfo {
+    IntRect systemPreviewRect;
+    bool isSystemPreview { false };
+};
+
 } // namespace WebCore
 
 namespace WTF {
index 3cb1569..49bd82e 100644 (file)
@@ -576,6 +576,7 @@ void ResourceRequestBase::setHTTPHeaderFields(HTTPHeaderMap headerFields)
     m_platformRequestUpdated = false;
 }
 
+#if USE(SYSTEM_PREVIEW)
 bool ResourceRequestBase::isSystemPreview() const
 {
     return m_isSystemPreview;
@@ -586,6 +587,17 @@ void ResourceRequestBase::setSystemPreview(bool s)
     m_isSystemPreview = s;
 }
 
+const IntRect& ResourceRequestBase::systemPreviewRect() const
+{
+    return m_systemPreviewRect;
+}
+
+void ResourceRequestBase::setSystemPreviewRect(const IntRect& rect)
+{
+    m_systemPreviewRect = rect;
+}
+#endif
+
 bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
 {
     if (a.url() != b.url())
index 00c5d2d..29b5572 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "FormData.h"
 #include "HTTPHeaderMap.h"
+#include "IntRect.h"
 #include "URL.h"
 #include "ResourceLoadPriority.h"
 
@@ -171,9 +172,14 @@ public:
     String initiatorIdentifier() const { return m_initiatorIdentifier; }
     void setInitiatorIdentifier(const String& identifier) { m_initiatorIdentifier = identifier; }
 
+#if USE(SYSTEM_PREVIEW)
     WEBCORE_EXPORT bool isSystemPreview() const;
     WEBCORE_EXPORT void setSystemPreview(bool);
 
+    WEBCORE_EXPORT const IntRect& systemPreviewRect() const;
+    WEBCORE_EXPORT void setSystemPreviewRect(const IntRect&);
+#endif
+
 #if !PLATFORM(COCOA)
     bool encodingRequiresPlatformData() const { return true; }
 #endif
@@ -233,7 +239,10 @@ protected:
     Requester m_requester { Requester::Unspecified };
     String m_initiatorIdentifier;
     String m_cachePartition { emptyString() };
+#if USE(SYSTEM_PREVIEW)
     bool m_isSystemPreview { false };
+    IntRect m_systemPreviewRect;
+#endif
 
 private:
     const ResourceRequest& asResourceRequest() const;
index 42b0196..3698602 100644 (file)
@@ -1,3 +1,33 @@
+2018-05-22  Dean Jackson  <dino@apple.com>
+
+        Optimized path zoom animation needs a valid UIImage and CGRect
+        https://bugs.webkit.org/show_bug.cgi?id=185883
+        <rdar://problem/40306056>
+
+        Reviewed by Jon Lee.
+
+        Take the rectangle that was passed into the ResourceRequest and
+        use it for the origin of an animation into QuickLook.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ResourceRequest>::encode):
+        (IPC::ArgumentCoder<ResourceRequest>::decode):
+        * UIProcess/Cocoa/DownloadClient.mm:
+        (WebKit::DownloadClient::didStart):
+        * UIProcess/Cocoa/SystemPreviewControllerCocoa.mm:
+        (-[_WKPreviewControllerDelegate initWithSystemPreviewController:fromRect:]):
+        (-[_WKPreviewControllerDelegate presentingViewController]):
+        (-[_WKPreviewControllerDelegate previewController:frameForPreviewItem:inSourceView:]):
+        (-[_WKPreviewControllerDelegate previewController:transitionImageForPreviewItem:contentRect:]):
+        (WebKit::SystemPreviewController::start):
+        (-[_WKPreviewControllerDelegate initWithSystemPreviewController:]): Deleted.
+        * UIProcess/Downloads/DownloadProxy.h:
+        (WebKit::DownloadProxy::systemPreviewDownloadRect const):
+        * UIProcess/SystemPreviewController.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::syncRootViewToScreen):
+        * UIProcess/WebPageProxy.h:
+
 2018-05-22  Sihui Liu  <sihui_liu@apple.com>
 
         [iOS] TestWebKitAPI.WebKit.WKHTTPCookieStoreWithoutProcessPool fails because cookies use different files with/without processpool
index e76ff64..94d3591 100644 (file)
@@ -1237,7 +1237,14 @@ void ArgumentCoder<ResourceRequest>::encode(Encoder& encoder, const ResourceRequ
 {
     encoder << resourceRequest.cachePartition();
     encoder << resourceRequest.hiddenFromInspector();
-    encoder << resourceRequest.isSystemPreview();
+
+#if USE(SYSTEM_PREVIEW)
+    if (resourceRequest.isSystemPreview()) {
+        encoder << true;
+        encoder << resourceRequest.systemPreviewRect();
+    } else
+        encoder << false;
+#endif
 
     if (resourceRequest.encodingRequiresPlatformData()) {
         encoder << true;
@@ -1260,11 +1267,20 @@ bool ArgumentCoder<ResourceRequest>::decode(Decoder& decoder, ResourceRequest& r
         return false;
     resourceRequest.setHiddenFromInspector(isHiddenFromInspector);
 
+#if USE(SYSTEM_PREVIEW)
     bool isSystemPreview;
     if (!decoder.decode(isSystemPreview))
         return false;
     resourceRequest.setSystemPreview(isSystemPreview);
 
+    if (isSystemPreview) {
+        IntRect systemPreviewRect;
+        if (!decoder.decode(systemPreviewRect))
+            return false;
+        resourceRequest.setSystemPreviewRect(systemPreviewRect);
+    }
+#endif
+
     bool hasPlatformData;
     if (!decoder.decode(hasPlatformData))
         return false;
index f44542c..9eeabe1 100644 (file)
@@ -78,7 +78,7 @@ void DownloadClient::didStart(WebProcessPool&, DownloadProxy& downloadProxy)
     if (downloadProxy.isSystemPreviewDownload()) {
         if (auto* webPage = downloadProxy.originatingPage()) {
             // FIXME: Update the MIME-type once it is known in the ResourceResponse.
-            webPage->systemPreviewController()->start(ASCIILiteral { "application/octet-stream" });
+            webPage->systemPreviewController()->start(ASCIILiteral { "application/octet-stream" }, downloadProxy.systemPreviewDownloadRect());
         }
         takeActivityToken(downloadProxy);
         return;
index 6477754..cb90268 100644 (file)
@@ -111,17 +111,19 @@ SOFT_LINK_CLASS(QuickLook, QLItem);
 
 @interface _WKPreviewControllerDelegate : NSObject <QLPreviewControllerDelegate> {
     WebKit::SystemPreviewController* _previewController;
+    WebCore::IntRect _linkRect;
 };
 @end
 
 @implementation _WKPreviewControllerDelegate
 
-- (id)initWithSystemPreviewController:(WebKit::SystemPreviewController*)previewController
+- (id)initWithSystemPreviewController:(WebKit::SystemPreviewController*)previewController fromRect:(WebCore::IntRect)rect
 {
     if (!(self = [super init]))
         return nil;
 
     _previewController = previewController;
+    _linkRect = rect;
     return self;
 }
 
@@ -131,35 +133,57 @@ SOFT_LINK_CLASS(QuickLook, QLItem);
         _previewController->cancel();
 }
 
-- (CGRect)previewController:(QLPreviewController *)controller frameForPreviewItem:(id <QLPreviewItem>)item inSourceView:(UIView * *)view
+- (UIViewController *)presentingViewController
 {
     if (!_previewController)
-        return CGRectZero;
+        return nil;
 
-    UIViewController *presentingViewController = _previewController->page().uiClient().presentingViewController();
+    return _previewController->page().uiClient().presentingViewController();
+}
+
+- (CGRect)previewController:(QLPreviewController *)controller frameForPreviewItem:(id <QLPreviewItem>)item inSourceView:(UIView * *)view
+{
+    UIViewController *presentingViewController = [self presentingViewController];
 
     if (!presentingViewController)
         return CGRectZero;
 
     *view = presentingViewController.view;
-    CGRect frame = presentingViewController.view.frame;
-    // Create a smaller rectangle centered in the frame.
-    CGFloat halfWidth = frame.size.width / 2;
-    CGFloat halfHeight = frame.size.height / 2;
-    frame = CGRectMake(CGRectGetMidX(frame) - halfWidth / 2, CGRectGetMidY(frame) - halfHeight / 2, halfWidth, halfHeight);
-    return frame;
+
+    if (_linkRect.isEmpty()) {
+        CGRect frame;
+        frame.size.width = presentingViewController.view.frame.size.width / 2.0;
+        frame.size.height = presentingViewController.view.frame.size.height / 2.0;
+        frame.origin.x = (presentingViewController.view.frame.size.width - frame.size.width) / 2.0;
+        frame.origin.y = (presentingViewController.view.frame.size.height - frame.size.height) / 2.0;
+        return frame;
+    }
+
+    return _previewController->page().syncRootViewToScreen(_linkRect);
 }
 
 - (UIImage *)previewController:(QLPreviewController *)controller transitionImageForPreviewItem:(id <QLPreviewItem>)item contentRect:(CGRect *)contentRect
 {
-    return nil;
+    *contentRect = CGRectZero;
+
+    UIViewController *presentingViewController = [self presentingViewController];
+    if (presentingViewController) {
+        if (_linkRect.isEmpty())
+            *contentRect = {CGPointZero, {presentingViewController.view.frame.size.width / 2.0, presentingViewController.view.frame.size.height / 2.0}};
+        else {
+            WebCore::IntRect screenRect = _previewController->page().syncRootViewToScreen(_linkRect);
+            *contentRect = { CGPointZero, { static_cast<CGFloat>(screenRect.width()), static_cast<CGFloat>(screenRect.height()) } };
+        }
+    }
+
+    return [UIImage new];
 }
 
 @end
 
 namespace WebKit {
 
-void SystemPreviewController::start(const String& mimeType)
+void SystemPreviewController::start(const String& mimeType, const WebCore::IntRect& fromRect)
 {
     ASSERT(!m_qlPreviewController);
     if (m_qlPreviewController)
@@ -172,7 +196,7 @@ void SystemPreviewController::start(const String& mimeType)
 
     m_qlPreviewController = adoptNS([allocQLPreviewControllerInstance() init]);
 
-    m_qlPreviewControllerDelegate = adoptNS([[_WKPreviewControllerDelegate alloc] initWithSystemPreviewController:this]);
+    m_qlPreviewControllerDelegate = adoptNS([[_WKPreviewControllerDelegate alloc] initWithSystemPreviewController:this fromRect:fromRect]);
     [m_qlPreviewController setDelegate:m_qlPreviewControllerDelegate.get()];
 
     m_qlPreviewControllerDataSource = adoptNS([[_WKPreviewControllerDataSource alloc] initWithMIMEType:mimeType]);
index 903bc56..e07aac8 100644 (file)
@@ -41,6 +41,7 @@ class Data;
 
 namespace WebCore {
 class AuthenticationChallenge;
+class IntRect;
 class ProtectionSpace;
 class ResourceError;
 class ResourceResponse;
@@ -91,6 +92,7 @@ public:
 
 #if USE(SYSTEM_PREVIEW)
     bool isSystemPreviewDownload() const { return request().isSystemPreview(); }
+    const WebCore::IntRect& systemPreviewDownloadRect() const { return request().systemPreviewRect(); }
 #endif
 
 private:
index 804b228..b8a6849 100644 (file)
@@ -27,6 +27,7 @@
 
 #if USE(SYSTEM_PREVIEW)
 
+#include <WebCore/IntRect.h>
 #include <WebCore/URL.h>
 #include <wtf/RetainPtr.h>
 
@@ -46,7 +47,7 @@ public:
 
     bool canPreview(const String& mimeType) const;
 
-    void start(const String& mimeType);
+    void start(const String& mimeType, const WebCore::IntRect&);
     void updateProgress(float);
     void finish(WebCore::URL);
     void cancel();
index 1da04d3..8894603 100644 (file)
@@ -3994,7 +3994,11 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Secur
 
     uint64_t newNavigationID = navigation->navigationID();
     navigation->setWasUserInitiated(!!navigationActionData.userGestureTokenIdentifier);
+#if USE(SYSTEM_PREVIEW)
     navigation->setShouldForceDownload(!navigationActionData.downloadAttribute.isNull() || request.isSystemPreview());
+#else
+    navigation->setShouldForceDownload(!navigationActionData.downloadAttribute.isNull());
+#endif
     navigation->setCurrentRequest(ResourceRequest(request), m_process->coreProcessIdentifier());
     navigation->setCurrentRequestIsRedirect(navigationActionData.isRedirect);
     navigation->setTreatAsSameOriginNavigation(navigationActionData.treatAsSameOriginNavigation);
@@ -4450,7 +4454,12 @@ void WebPageProxy::rootViewToScreen(const IntRect& viewRect, Messages::WebPagePr
 {
     reply(m_pageClient.rootViewToScreen(viewRect));
 }
-    
+
+IntRect WebPageProxy::syncRootViewToScreen(const IntRect& viewRect)
+{
+    return m_pageClient.rootViewToScreen(viewRect);
+}
+
 #if PLATFORM(IOS)
 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
 {
index 9c24a3f..c8b19f8 100644 (file)
@@ -1311,6 +1311,8 @@ public:
 
     void setDefersLoadingForTesting(bool);
 
+    WebCore::IntRect syncRootViewToScreen(const WebCore::IntRect& viewRect);
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     void platformInitialize();