Diff
Modified: trunk/Source/WTF/ChangeLog (266653 => 266654)
--- trunk/Source/WTF/ChangeLog 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WTF/ChangeLog 2020-09-05 04:07:47 UTC (rev 266654)
@@ -1,3 +1,13 @@
+2020-09-04 Alex Christensen <[email protected]>
+
+ Move PDF heads-up display to UI process on macOS
+ https://bugs.webkit.org/show_bug.cgi?id=215780
+ <rdar://problem/58715847>
+
+ Reviewed by Tim Horton.
+
+ * wtf/PlatformHave.h:
+
2020-09-03 Ryosuke Niwa <[email protected]>
GTK+ build fix attempt after r266573.
Modified: trunk/Source/WTF/wtf/PlatformEnableCocoa.h (266653 => 266654)
--- trunk/Source/WTF/wtf/PlatformEnableCocoa.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WTF/wtf/PlatformEnableCocoa.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -228,6 +228,10 @@
#define ENABLE_GPU_DRIVER_PREWARMING 1
#endif
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
+#define ENABLE_UI_PROCESS_PDF_HUD 1
+#endif
+
#if !defined(ENABLE_INDEXED_DATABASE)
#define ENABLE_INDEXED_DATABASE 1
#endif
Modified: trunk/Source/WebCore/PAL/pal/spi/mac/NSImageSPI.h (266653 => 266654)
--- trunk/Source/WebCore/PAL/pal/spi/mac/NSImageSPI.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebCore/PAL/pal/spi/mac/NSImageSPI.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -36,6 +36,8 @@
NS_ASSUME_NONNULL_BEGIN
@interface NSImage ()
++ (instancetype)imageWithImageRep:(NSImageRep *)imageRep;
+- (instancetype)_imageWithConfiguration:(NSDictionary *)configuration;
- (void)lockFocusWithRect:(NSRect)rect context:(nullable NSGraphicsContext *)context hints:(nullable NSDictionary *)hints flipped:(BOOL)flipped;
@end
@@ -43,6 +45,13 @@
+ (nullable NSImage *)_imageWithSystemSymbolName:(NSString *) symbolName;
@end
+WTF_EXTERN_C_BEGIN
+
+extern const NSString *NSImageAlternateCriterionFont;
+extern const NSString *NSImageAlternateCriterionSymbolScale;
+
+WTF_EXTERN_C_END
+
NS_ASSUME_NONNULL_END
#endif
@@ -56,6 +65,6 @@
NS_ASSUME_NONNULL_END
-#endif
+#endif // HAVE(ALTERNATE_ICONS)
-#endif
+#endif // USE(APPLE_INTERNAL_SDK)
Modified: trunk/Source/WebKit/ChangeLog (266653 => 266654)
--- trunk/Source/WebKit/ChangeLog 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/ChangeLog 2020-09-05 04:07:47 UTC (rev 266654)
@@ -1,3 +1,96 @@
+2020-09-04 Alex Christensen <[email protected]>
+
+ Move PDF heads-up display to UI process on macOS
+ https://bugs.webkit.org/show_bug.cgi?id=215780
+ <rdar://problem/58715847>
+
+ Reviewed by Tim Horton.
+
+ This has many benefits including the one in the radar, testability, and moving WebKit-specific code from PDFKit to WebKit.
+
+ Now that the HUD is displayed in the UI process instead of in the web content, zooming in keeps the HUD the same size.
+ A 3d-transformed iframe with a PDF in it now shows the HUD in the place you can click on it, instead of in the transformed PDF.
+ Also, moving the mouse to the HUD within the first 3 seconds prevents it from hiding, which it does when the mouse leaves the HUD.
+ The rest of the behavior I think should be the same. Most users should not notice any difference.
+
+ Functionality covered by API tests, the first tests for PDF content interaction!
+
+ * Scripts/webkit/messages.py:
+ * UIProcess/API/Cocoa/WKWebViewInternal.h:
+ * UIProcess/API/mac/WKView.mm:
+ (-[WKView _createPDFHUD:rect:]):
+ (-[WKView _pdfHUD:changedLocation:]):
+ (-[WKView _removePDFHUD:]):
+ (-[WKView _removeAllPDFHUDs]):
+ * UIProcess/API/mac/WKWebViewMac.mm:
+ (-[WKWebView mouseMoved:]):
+ (-[WKWebView mouseDown:]):
+ (-[WKWebView mouseUp:]):
+ (-[WKWebView _createPDFHUD:rect:]):
+ (-[WKWebView _pdfHUD:changedLocation:]):
+ (-[WKWebView _removePDFHUD:]):
+ (-[WKWebView _removeAllPDFHUDs]):
+ * UIProcess/API/mac/WKWebViewPrivateForTestingMac.h:
+ * UIProcess/API/mac/WKWebViewTestingMac.mm:
+ (-[WKWebView pdfHUDs]):
+ * UIProcess/Cocoa/WebViewImpl.h:
+ * UIProcess/Cocoa/WebViewImpl.mm:
+ (WebKit::WebViewImpl::createPDFHUD):
+ (WebKit::WebViewImpl::updatePDFHUDLocation):
+ (WebKit::WebViewImpl::removePDFHUD):
+ (WebKit::WebViewImpl::removeAllPDFHUDs):
+ * UIProcess/PageClient.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::didCommitLoadForFrame):
+ (WebKit::WebPageProxy::processDidTerminate):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebPageProxy.messages.in:
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication): Deleted.
+ (WebKit::WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication): Deleted.
+ * UIProcess/mac/PageClientImplMac.h:
+ * UIProcess/mac/PageClientImplMac.mm:
+ (WebKit::PageClientImpl::createPDFHUD):
+ (WebKit::PageClientImpl::updatePDFHUDLocation):
+ (WebKit::PageClientImpl::removePDFHUD):
+ (WebKit::PageClientImpl::removeAllPDFHUDs):
+ * UIProcess/mac/WebPageProxyMac.mm:
+ (WebKit::WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication):
+ (WebKit::WebPageProxy::createPDFHUD):
+ (WebKit::WebPageProxy::removePDFHUD):
+ (WebKit::WebPageProxy::updatePDFHUDLocation):
+ (WebKit::WebPageProxy::pdfZoomIn):
+ (WebKit::WebPageProxy::pdfZoomOut):
+ (WebKit::WebPageProxy::pdfSaveToPDF):
+ (WebKit::WebPageProxy::pdfOpenWithPreview):
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/Plugins/PDF/PDFLayerControllerSPI.h:
+ * WebProcess/Plugins/PDF/PDFPlugin.h:
+ * WebProcess/Plugins/PDF/PDFPlugin.mm:
+ (-[WKPDFLayerControllerDelegate openWithNativeApplication]):
+ (-[WKPDFLayerControllerDelegate saveToPDF]):
+ (WebKit::PDFPlugin::PDFPlugin):
+ (WebKit::PDFPlugin::~PDFPlugin):
+ (WebKit::PDFPlugin::frameForHUD const):
+ (WebKit::PDFPlugin::calculateSizes):
+ (WebKit::PDFPlugin::convertFromPDFViewToRootView const):
+ (WebKit::PDFPlugin::visibilityDidChange):
+ (WebKit::PDFPlugin::zoomIn):
+ (WebKit::PDFPlugin::zoomOut):
+ (WebKit::PDFPlugin::save):
+ (WebKit::PDFPlugin::openWithPreview):
+ * WebProcess/WebPage/WebPage.cpp:
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/mac/WebPageMac.mm:
+ (WebKit::WebPage::zoomPDFIn):
+ (WebKit::WebPage::zoomPDFOut):
+ (WebKit::WebPage::savePDF):
+ (WebKit::WebPage::openPDFWithPreview):
+ (WebKit::WebPage::createPDFHUD):
+ (WebKit::WebPage::updatePDFHUDLocation):
+ (WebKit::WebPage::removePDFHUD):
+
2020-09-04 Chris Dumez <[email protected]>
handleXPCEndpointMessages does not check XPC object is an xpc_endpoint_t
Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (266653 => 266654)
--- trunk/Source/WebKit/Scripts/webkit/messages.py 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py 2020-09-05 04:07:47 UTC (rev 266654)
@@ -244,6 +244,7 @@
'WebKit::MDNSRegisterIdentifier',
'WebKit::MediaPlayerPrivateRemoteIdentifier',
'WebKit::MediaRecorderIdentifier',
+ 'WebKit::PDFPluginIdentifier',
'WebKit::PlaybackSessionContextIdentifier',
'WebKit::PluginProcessType',
'WebKit::RemoteAudioDestinationIdentifier',
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -23,11 +23,11 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "WKWebViewPrivate.h"
-
+#import "PDFPluginIdentifier.h"
#import "SameDocumentNavigationType.h"
#import "WKShareSheet.h"
#import "WKWebViewConfiguration.h"
+#import "WKWebViewPrivate.h"
#import "_WKAttachmentInternal.h"
#import "_WKWebViewPrintFormatterInternal.h"
#import <wtf/CompletionHandler.h>
@@ -133,7 +133,7 @@
// Only used with UI-side compositing.
RetainPtr<WKScrollView> _scrollView;
RetainPtr<WKContentView> _contentView;
-#endif
+#endif // PLATFORM(MAC)
#if PLATFORM(IOS_FAMILY)
RetainPtr<WKScrollView> _scrollView;
Modified: trunk/Source/WebKit/UIProcess/API/mac/WKWebViewPrivateForTestingMac.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/API/mac/WKWebViewPrivateForTestingMac.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/API/mac/WKWebViewPrivateForTestingMac.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -50,6 +50,7 @@
- (void)_setHeaderBannerHeight:(int)height;
- (void)_setFooterBannerHeight:(int)height;
+- (NSSet<NSView *> *)_pdfHUDs;
@end
Modified: trunk/Source/WebKit/UIProcess/API/mac/WKWebViewTestingMac.mm (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/API/mac/WKWebViewTestingMac.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/API/mac/WKWebViewTestingMac.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -103,6 +103,15 @@
_page->setFooterBannerHeightForTesting(height);
}
+- (NSSet<NSView *> *)_pdfHUDs
+{
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ return _impl->pdfHUDs();
+#else
+ return nil;
+#endif
+}
+
- (NSMenu *)_activeMenu
{
// FIXME: Only the DOM paste access menu is supported for now. In the future, it could be
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -27,6 +27,7 @@
#if PLATFORM(MAC)
+#include "PDFPluginIdentifier.h"
#include "PluginComplexTextInputState.h"
#include "ShareableBitmap.h"
#include "WKLayoutMode.h"
@@ -76,6 +77,10 @@
OBJC_CLASS WebPlaybackControlsManager;
#endif // HAVE(TOUCH_BAR)
+#if ENABLE(UI_PROCESS_PDF_HUD)
+OBJC_CLASS WKPDFHUDView;
+#endif
+
namespace API {
class HitTestResult;
class Object;
@@ -190,6 +195,14 @@
void viewWillStartLiveResize();
void viewDidEndLiveResize();
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ void createPDFHUD(PDFPluginIdentifier, const WebCore::IntRect&);
+ void updatePDFHUDLocation(PDFPluginIdentifier, const WebCore::IntRect&);
+ void removePDFHUD(PDFPluginIdentifier);
+ void removeAllPDFHUDs();
+ NSSet *pdfHUDs();
+#endif
+
void renewGState();
void setFrameSize(CGSize);
void disableFrameSizeUpdates();
@@ -729,7 +742,11 @@
#if ENABLE(FULLSCREEN_API)
RetainPtr<WKFullScreenWindowController> m_fullScreenWindowController;
#endif
-
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ HashMap<WebKit::PDFPluginIdentifier, RetainPtr<WKPDFHUDView>> _pdfHUDViews;
+#endif
+
RetainPtr<WKShareSheet> _shareSheet;
RetainPtr<WKWindowVisibilityObserver> m_windowVisibilityObserver;
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -62,6 +62,7 @@
#import "WKErrorInternal.h"
#import "WKFullScreenWindowController.h"
#import "WKImmediateActionController.h"
+#import "WKPDFHUDView.h"
#import "WKPrintingView.h"
#import "WKSafeBrowsingWarning.h"
#import "WKShareSheet.h"
@@ -1718,6 +1719,45 @@
[m_layoutStrategy didEndLiveResize];
}
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+void WebViewImpl::createPDFHUD(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ removePDFHUD(identifier);
+ auto hud = adoptNS([[WKPDFHUDView alloc] initWithFrame:rect pluginIdentifier:identifier page:m_page.get()]);
+ [m_view addSubview:hud.get()];
+ _pdfHUDViews.add(identifier, WTFMove(hud));
+}
+
+void WebViewImpl::updatePDFHUDLocation(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ if (auto hud = _pdfHUDViews.get(identifier))
+ [hud setFrame:rect];
+}
+
+void WebViewImpl::removePDFHUD(PDFPluginIdentifier identifier)
+{
+ if (auto hud = _pdfHUDViews.take(identifier))
+ [hud removeFromSuperview];
+}
+
+void WebViewImpl::removeAllPDFHUDs()
+{
+ for (auto& hud : _pdfHUDViews.values())
+ [hud removeFromSuperview];
+ _pdfHUDViews.clear();
+}
+
+NSSet *WebViewImpl::pdfHUDs()
+{
+ NSMutableSet<NSView *> *set = [NSMutableSet setWithCapacity:_pdfHUDViews.size()];
+ for (auto& hud : _pdfHUDViews.values())
+ [set addObject:hud.get()];
+ return set;
+}
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
+
void WebViewImpl::renewGState()
{
if (m_textIndicatorWindow)
@@ -2149,6 +2189,10 @@
return;
m_page->setIntrinsicDeviceScaleFactor(newBackingScaleFactor);
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ for (auto& hud : _pdfHUDViews.values())
+ [hud setDeviceScaleFactor:newBackingScaleFactor];
+#endif
}
void WebViewImpl::windowDidChangeScreen()
@@ -5391,6 +5435,11 @@
if (m_ignoresNonWheelEvents)
return;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ for (auto& hud : _pdfHUDViews.values())
+ [hud mouseMoved:event];
+#endif
+
// When a view is first responder, it gets mouse moved events even when the mouse is outside its visible rect.
if (m_view.getAutoreleased() == [m_view window].firstResponder && !NSPointInRect([m_view convertPoint:[event locationInWindow] fromView:nil], [m_view visibleRect]))
return;
@@ -5439,6 +5488,11 @@
if (m_ignoresNonWheelEvents)
return;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ for (auto& hud : _pdfHUDViews.values())
+ [hud mouseDown:event];
+#endif
+
setLastMouseDownEvent(event);
setIgnoresMouseDraggedEvents(false);
@@ -5450,6 +5504,11 @@
if (m_ignoresNonWheelEvents)
return;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ for (auto& hud : _pdfHUDViews.values())
+ [hud mouseUp:event];
+#endif
+
setLastMouseDownEvent(nil);
mouseUpInternal(event);
}
Copied: trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.h (from rev 266653, trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h) (0 => 266654)
--- trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+#import "PDFPluginIdentifier.h"
+
+namespace WebKit {
+class WebPageProxy;
+}
+
+@interface WKPDFHUDView : NSView
+
+- (instancetype)initWithFrame:(NSRect)frame pluginIdentifier:(WebKit::PDFPluginIdentifier)pluginIdentifier page:(WebKit::WebPageProxy&)page;
+- (void)setFrame:(NSRect)frame;
+- (void)mouseMoved:(NSEvent *)event;
+- (void)mouseDown:(NSEvent *)event;
+- (void)mouseUp:(NSEvent *)event;
+- (void)setDeviceScaleFactor:(CGFloat)deviceScaleFactor;
+
+@end
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
Added: trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm (0 => 266654)
--- trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/PDF/WKPDFHUDView.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2020 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 "WKPDFHUDView.h"
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+#import "WebPageProxy.h"
+#import <QuartzCore/CATransaction.h>
+#import <pal/spi/cocoa/QuartzCoreSPI.h>
+#import <pal/spi/mac/NSImageSPI.h>
+#import <wtf/WeakObjCPtr.h>
+
+// The HUD items should have the following spacing:
+// -------------------------------------------------
+// | 12 12 10 12 12 |
+// | ---- ---- | ---- ---- |
+// | 10 |icon| 10 |icon| 10 | 10 |icon| 10 |icon| 10 |
+// | ---- ---- | ---- ---- |
+// | 12 12 10 12 12 |
+// -------------------------------------------------
+// where the 12 point vertical spacing is anchored to the smallest icon image,
+// and all subsequent icons with be centered vertically with the smallest icon.
+
+static const CGFloat layerVerticalOffset = 40;
+static const CGFloat layerCornerRadius = 12;
+static const CGFloat layerGrayComponent = 0;
+static const CGFloat layerAlpha = 0.75;
+static const CGFloat layerImageScale = 1.5;
+static const CGFloat layerSeperatorControllerSize = 1.5;
+static const CGFloat layerControllerHorizontalMargin = 10.0;
+static const CGFloat layerImageVerticalMargin = 12.0;
+static const CGFloat layerSeperatorVerticalMargin = 10.0;
+static const CGFloat controlLayerNormalAlpha = 0.75;
+static const CGFloat controlLayerDownAlpha = 0.45;
+
+static NSString * const PDFHUDZoomInControl = @"plus.magnifyingglass";
+static NSString * const PDFHUDZoomOutControl = @"minus.magnifyingglass";
+static NSString * const PDFHUDLaunchPreviewControl = @"preview";
+static NSString * const PDFHUDSavePDFControl = @"arrow.down.circle";
+static NSString * const PDFHUDSeperatorControl = @"PDFHUDSeperatorControl";
+
+static const CGFloat layerFadeInTimeInterval = 0.25;
+static const CGFloat layerFadeOutTimeInterval = 0.5;
+static const CGFloat initialHideTimeInterval = 3.0;
+
+static NSArray<NSString *> *controlArray()
+{
+ return @[
+ PDFHUDZoomOutControl,
+ PDFHUDZoomInControl,
+ PDFHUDSeperatorControl,
+ PDFHUDLaunchPreviewControl,
+ PDFHUDSavePDFControl
+ ];
+}
+
+@implementation WKPDFHUDView {
+@private
+ WeakPtr<WebKit::WebPageProxy> _page;
+ RetainPtr<NSString> _activeControl;
+ WebKit::PDFPluginIdentifier _pluginIdentifier;
+ CGFloat _deviceScaleFactor;
+ RetainPtr<CALayer> _layer;
+ RetainPtr<CALayer> _activeLayer;
+ CGSize _frameSize;
+ RetainPtr<NSMutableDictionary<NSString *, NSImage *>> _cachedIcons;
+ BOOL _visible;
+ BOOL _mouseMovedToHUD;
+ BOOL _initialHideTimerFired;
+}
+
+- (instancetype)initWithFrame:(NSRect)frame pluginIdentifier:(WebKit::PDFPluginIdentifier)pluginIdentifier page:(WebKit::WebPageProxy&)page
+{
+ if (!(self = [super initWithFrame:frame]))
+ return nil;
+
+ self.wantsLayer = YES;
+ _cachedIcons = adoptNS([[NSMutableDictionary alloc] init]);
+ _pluginIdentifier = pluginIdentifier;
+ _page = makeWeakPtr(page);
+ _deviceScaleFactor = page.deviceScaleFactor();
+ _visible = YES;
+ [self _setupLayer:self.layer];
+ [self setFrame:frame];
+
+ WeakObjCPtr<WKPDFHUDView> weakSelf = self;
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(initialHideTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [weakSelf _hideTimerFired];
+ });
+ return self;
+}
+
+- (void)dealloc
+{
+ [_layer removeFromSuperlayer];
+ [super dealloc];
+}
+
+- (void)setFrame:(NSRect)rect
+{
+ [super setFrame:rect];
+ _frameSize = rect.size;
+
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ CGRect layerBounds = [_layer bounds];
+ [_layer setFrame:CGRectMake(rect.size.width / 2.0 - layerBounds.size.width / 2.0, layerVerticalOffset, layerBounds.size.width, layerBounds.size.height)];
+ [CATransaction commit];
+}
+
+- (void)setDeviceScaleFactor:(CGFloat)deviceScaleFactor
+{
+ if (_deviceScaleFactor == deviceScaleFactor)
+ return;
+
+ _deviceScaleFactor = deviceScaleFactor;
+
+ [self _redrawLayer];
+}
+
+- (void)_hideTimerFired
+{
+ _initialHideTimerFired = YES;
+ if (!_mouseMovedToHUD)
+ [self _setVisible:false];
+}
+
+- (void)_setVisible:(bool)isVisible
+{
+ if (_visible == isVisible)
+ return;
+ _visible = isVisible;
+ [CATransaction begin];
+ [CATransaction setAnimationDuration:isVisible ? layerFadeInTimeInterval : layerFadeOutTimeInterval];
+ [self _setLayerOpacity:isVisible ? layerAlpha : 0.0];
+ [CATransaction commit];
+}
+
+- (void)mouseMoved:(NSEvent *)event
+{
+ if (CGRectContainsPoint([self convertRect:CGRectInset([_layer frame], -16.0, -16.0) toView:nil], NSPointToCGPoint(event.locationInWindow))) {
+ [self _setVisible:true];
+ _mouseMovedToHUD = YES;
+ } else if (_initialHideTimerFired)
+ [self _setVisible:false];
+}
+
+- (void)mouseDown:(NSEvent *)event
+{
+ _activeControl = [self _controlForEvent:event];
+ if ([_activeControl isEqualToString:PDFHUDSeperatorControl])
+ _activeControl = nil;
+ if (_activeControl) {
+ // Update rendering to highlight it..
+ _activeLayer = [self _layerForEvent:event];
+
+ // Update layer image; do not animate
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+
+ [_activeLayer setOpacity:controlLayerDownAlpha];
+
+ [CATransaction commit];
+ }
+}
+
+- (void)mouseUp:(NSEvent *)event
+{
+ if (!_activeControl)
+ return;
+
+ NSString* mouseUpControl = [self _controlForEvent:event];
+ if ([_activeControl isEqualToString:mouseUpControl])
+ [self _performActionForControl:_activeControl.get()];
+
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ [_activeLayer setOpacity:controlLayerNormalAlpha];
+ [CATransaction commit];
+
+ _activeLayer = nil;
+ _activeControl = nil;
+}
+
+- (Optional<NSUInteger>)_controlIndexForEvent:(NSEvent *)event
+{
+ CGPoint initialPoint = NSPointToCGPoint(event.locationInWindow);
+ initialPoint.x -= [_layer frame].origin.x;
+ initialPoint.y -= [_layer frame].origin.y;
+ for (NSUInteger index = 0; index < [_layer sublayers].count; index++) {
+ CALayer *subLayer = [_layer sublayers][index];
+ NSRect windowSpaceRect = [self convertRect:subLayer.frame toView:nil];
+ if (CGRectContainsPoint(windowSpaceRect, initialPoint))
+ return index;
+ }
+ return WTF::nullopt;
+}
+
+- (NSString *)_controlForEvent:(NSEvent *)event
+{
+ if (auto index = [self _controlIndexForEvent:event])
+ return controlArray()[*index];
+ return nil;
+}
+
+- (CALayer *)_layerForEvent:(NSEvent *)event
+{
+ if (auto index = [self _controlIndexForEvent:event])
+ return [_layer sublayers][*index];
+ return nil;
+}
+
+- (void)_performActionForControl:(NSString *)control
+{
+ if (!_visible)
+ return;
+ auto* page = _page.get();
+ if (!page)
+ return;
+ if ([control isEqualToString:PDFHUDZoomInControl])
+ page->pdfZoomIn(_pluginIdentifier);
+ else if ([control isEqualToString:PDFHUDZoomOutControl])
+ page->pdfZoomOut(_pluginIdentifier);
+ else if ([control isEqualToString:PDFHUDSavePDFControl])
+ page->pdfSaveToPDF(_pluginIdentifier);
+ else if ([control isEqualToString:PDFHUDLaunchPreviewControl])
+ page->pdfOpenWithPreview(_pluginIdentifier);
+}
+
+- (void)_loadIconImages
+{
+ for (NSString *controlName in controlArray())
+ [self _getImageForControlName:controlName];
+}
+
+- (void)_setupLayer:(CALayer *)parentLayer
+{
+ _layer = adoptNS([[CALayer alloc] init]);
+ [_layer setCornerRadius:layerCornerRadius];
+
+ [_layer setBackgroundColor:WebCore::cachedCGColor({ WebCore::SRGBA<float>(layerGrayComponent, layerGrayComponent, layerGrayComponent) })];
+ [self _setLayerOpacity:layerAlpha];
+
+ [self _loadIconImages];
+ CGFloat minIconImageHeight = std::numeric_limits<CGFloat>::max();
+ for (NSImage *image in [_cachedIcons allValues])
+ minIconImageHeight = std::min(minIconImageHeight, (image.size.height / _deviceScaleFactor));
+
+ CGFloat dx = layerControllerHorizontalMargin;
+ for (NSString *controlName in controlArray()) {
+ auto controlLayer = adoptNS([[CALayer alloc] init]);
+ CGFloat dy = 0.0;
+ CGFloat controllerWidth = 0.0;
+ CGFloat controllerHeight = 0.0;
+
+ if ([controlName isEqualToString:PDFHUDSeperatorControl]) {
+ dy = layerSeperatorVerticalMargin;
+ controllerWidth = layerSeperatorControllerSize;
+ controllerHeight = minIconImageHeight + (2.0 * layerImageVerticalMargin) - (2.0 * layerSeperatorVerticalMargin);
+
+ [controlLayer setBackgroundColor:[[NSColor lightGrayColor] CGColor]];
+ } else {
+ NSImage *controlImage = [self _getImageForControlName:controlName];
+ [controlLayer setContents:controlImage];
+ [controlLayer setOpacity:controlLayerNormalAlpha];
+
+ dy = layerImageVerticalMargin;
+ controllerWidth = [controlImage size].width / _deviceScaleFactor;
+ controllerHeight = [controlImage size].height / _deviceScaleFactor;
+
+ dy -= (controllerHeight - minIconImageHeight) / 2.0;
+
+ [controlLayer setFilters:@[[CAFilter filterWithType:kCAFilterColorInvert]]];
+ }
+
+ [controlLayer setFrame:CGRectMake(dx, dy, controllerWidth, controllerHeight)];
+ [_layer addSublayer:controlLayer.get()];
+
+ dx += controllerWidth + layerControllerHorizontalMargin;
+ }
+
+ [_layer setFrame:CGRectMake(0, layerVerticalOffset, dx, minIconImageHeight + 2.0 * layerImageVerticalMargin)];
+ [parentLayer addSublayer:_layer.get()];
+}
+
+- (void)_redrawLayer
+{
+ [_cachedIcons removeAllObjects];
+ CALayer *parentLayer = [_layer superlayer];
+ [_layer removeFromSuperlayer];
+ [self _setupLayer:parentLayer];
+ [self setFrameSize:_frameSize];
+}
+
+- (NSImage *)_getImageForControlName:(NSString *)control
+{
+ NSImage *iconImage = _cachedIcons.get()[control];
+ if (iconImage)
+ return iconImage;
+
+ iconImage = [NSImage _imageWithSystemSymbolName:control];
+ if (!iconImage)
+ return nil;
+
+ // This was introduced in rdar://problem/59118412
+ iconImage = [iconImage _imageWithConfiguration:@{
+ NSImageAlternateCriterionFont:[NSFont preferredFontForTextStyle:NSFontTextStyleTitle2 options:@{ }],
+ NSImageAlternateCriterionSymbolScale:@(NSImageSymbolScaleLarge)
+ }];
+
+ NSRect iconImageRect = NSMakeRect(0, 0, [iconImage size].width * layerImageScale * _deviceScaleFactor, [iconImage size].height * layerImageScale * _deviceScaleFactor);
+ NSImageRep *iconImageRep = [iconImage bestRepresentationForRect:iconImageRect context:nil hints:nil];
+ iconImage = [NSImage imageWithImageRep:iconImageRep];
+
+ _cachedIcons.get()[control] = iconImage;
+ return iconImage;
+}
+
+- (void)_setLayerOpacity:(CGFloat)alpha
+{
+ [_layer setOpacity:alpha];
+ for (CALayer *subLayer in [_layer sublayers])
+ [subLayer setOpacity:alpha];
+}
+
+@end
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -26,6 +26,7 @@
#pragma once
#include "LayerTreeContext.h"
+#include "PDFPluginIdentifier.h"
#include "SameDocumentNavigationType.h"
#include "ShareableBitmap.h"
#include "WebColorPicker.h"
@@ -241,6 +242,13 @@
virtual void didFailProvisionalLoadForMainFrame() { };
virtual void didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) = 0;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ virtual void createPDFHUD(PDFPluginIdentifier, const WebCore::IntRect&) = 0;
+ virtual void updatePDFHUDLocation(PDFPluginIdentifier, const WebCore::IntRect&) = 0;
+ virtual void removePDFHUD(PDFPluginIdentifier) = 0;
+ virtual void removeAllPDFHUDs() = 0;
+#endif
+
virtual void handleDownloadRequest(DownloadProxy&) = 0;
virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, const FrameInfoData&, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) { return false; }
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-09-05 04:07:47 UTC (rev 266654)
@@ -4765,15 +4765,14 @@
m_pluginScaleFactor = 1;
m_mainFramePluginHandlesPageScaleGesture = false;
}
- }
-
#if ENABLE(POINTER_LOCK)
- if (frame->isMainFrame())
requestPointerUnlock();
#endif
-
- if (frame->isMainFrame())
pageClient().setMouseEventPolicy(mouseEventPolicy);
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ pageClient().removeAllPDFHUDs();
+#endif
+ }
m_pageLoadState.commitChanges();
if (m_loaderClient)
@@ -7446,6 +7445,9 @@
resetStateAfterProcessExited(reason);
stopAllURLSchemeTasks(m_process.ptr());
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ pageClient().removeAllPDFHUDs();
+#endif
// For bringup of process swapping, NavigationSwap termination will not go out to clients.
// If it does *during* process swapping, and the client triggers a reload, that causes bizarre WebKit re-entry.
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -40,6 +40,7 @@
#include "LayerTreeContext.h"
#include "MessageSender.h"
#include "NotificationPermissionRequestManagerProxy.h"
+#include "PDFPluginIdentifier.h"
#include "PageLoadState.h"
#include "PluginProcessAttributes.h"
#include "PolicyDecision.h"
@@ -1317,10 +1318,12 @@
void saveDataToFileInDownloadsFolder(String&& suggestedFilename, String&& mimeType, URL&& originatingURL, API::Data&);
void savePDFToFileInDownloadsFolder(String&& suggestedFilename, URL&& originatingURL, const IPC::DataReference&);
-#if PLATFORM(COCOA)
+#if ENABLE(PDFKIT_PLUGIN)
void savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, FrameInfoData&&, const IPC::DataReference&, const String& pdfUUID);
+#if !ENABLE(UI_PROCESS_PDF_HUD)
void openPDFFromTemporaryFolderWithNativeApplication(FrameInfoData&&, const String& pdfUUID);
#endif
+#endif
#if ENABLE(PDFKIT_PLUGIN)
void showPDFContextMenu(const WebKit::PDFContextMenu&, CompletionHandler<void(Optional<int32_t>&&)>&&);
@@ -1808,6 +1811,16 @@
bool canUseCredentialStorage() { return m_canUseCredentialStorage; }
void setCanUseCredentialStorage(bool);
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ void createPDFHUD(PDFPluginIdentifier, const WebCore::IntRect&);
+ void updatePDFHUDLocation(PDFPluginIdentifier, const WebCore::IntRect&);
+ void removePDFHUD(PDFPluginIdentifier);
+ void pdfZoomIn(PDFPluginIdentifier);
+ void pdfZoomOut(PDFPluginIdentifier);
+ void pdfSaveToPDF(PDFPluginIdentifier);
+ void pdfOpenWithPreview(PDFPluginIdentifier);
+#endif
+
private:
WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
void platformInitialize();
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in 2020-09-05 04:07:47 UTC (rev 266654)
@@ -433,9 +433,8 @@
SaveRecentSearches(String name, Vector<WebCore::RecentSearch> searchItems)
LoadRecentSearches(String name) -> (Vector<WebCore::RecentSearch> result) Synchronous
+#if ENABLE(PDFKIT_PLUGIN) && !ENABLE(UI_PROCESS_PDF_HUD)
SavePDFToFileInDownloadsFolder(String suggestedFilename, URL originatingURL, IPC::DataReference data)
-
-#if PLATFORM(COCOA)
SavePDFToTemporaryFolderAndOpenWithNativeApplication(String suggestedFilename, struct WebKit::FrameInfoData sourceFrameInfo, IPC::DataReference data, String pdfUUID)
OpenPDFFromTemporaryFolderWithNativeApplication(struct WebKit::FrameInfoData sourceFrameInfo, String pdfUUID)
#endif
@@ -566,6 +565,12 @@
SpeechSynthesisResume() -> () Async
#endif
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ CreatePDFHUD(WebKit::PDFPluginIdentifier identifier, WebCore::IntRect boundingBox)
+ UpdatePDFHUDLocation(WebKit::PDFPluginIdentifier identifier, WebCore::IntRect boundingBox)
+ RemovePDFHUD(WebKit::PDFPluginIdentifier identifier)
+#endif
+
ConfigureLoggingChannel(String channelName, enum:uint8_t WTFLogChannelState state, enum:uint8_t WTFLogLevel level)
#if PLATFORM(GTK)
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -1088,16 +1088,6 @@
pageClient().didPerformDictionaryLookup(dictionaryPopupInfo);
}
-void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String&, FrameInfoData&&, const IPC::DataReference&, const String&)
-{
- notImplemented();
-}
-
-void WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication(FrameInfoData&&, const String&)
-{
- notImplemented();
-}
-
void WebPageProxy::setRemoteLayerTreeRootNode(RemoteLayerTreeNode* rootNode)
{
pageClient().setRemoteLayerTreeRootNode(rootNode);
Modified: trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -190,6 +190,13 @@
void registerInsertionUndoGrouping() override;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ void createPDFHUD(PDFPluginIdentifier, const WebCore::IntRect&) override;
+ void updatePDFHUDLocation(PDFPluginIdentifier, const WebCore::IntRect&) override;
+ void removePDFHUD(PDFPluginIdentifier) override;
+ void removeAllPDFHUDs() override;
+#endif
+
// Auxiliary Client Creation
#if ENABLE(FULLSCREEN_API)
WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() override;
Modified: trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/mac/PageClientImplMac.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -349,6 +349,30 @@
registerInsertionUndoGroupingWithUndoManager([m_view undoManager]);
}
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+void PageClientImpl::createPDFHUD(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ m_impl->createPDFHUD(identifier, rect);
+}
+
+void PageClientImpl::updatePDFHUDLocation(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ m_impl->updatePDFHUDLocation(identifier, rect);
+}
+
+void PageClientImpl::removePDFHUD(PDFPluginIdentifier identifier)
+{
+ m_impl->removePDFHUD(identifier);
+}
+
+void PageClientImpl::removeAllPDFHUDs()
+{
+ m_impl->removeAllPDFHUDs();
+}
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
+
void PageClientImpl::clearAllEditCommands()
{
m_impl->clearAllEditCommands();
Modified: trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm (266653 => 266654)
--- trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/UIProcess/mac/WebPageProxyMac.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -480,8 +480,6 @@
void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, FrameInfoData&& frameInfo, const IPC::DataReference& data, const String& pdfUUID)
{
- MESSAGE_CHECK(TemporaryPDFFileMap::isValidKey(pdfUUID));
-
if (data.isEmpty()) {
WTFLogAlways("Cannot save empty PDF file to the temporary directory.");
return;
@@ -509,7 +507,8 @@
auto originatingURLString = frameInfo.request.url().string();
FileSystem::setMetadataURL(nsPath.get(), originatingURLString);
- m_temporaryPDFFiles.add(pdfUUID, nsPath.get());
+ if (TemporaryPDFFileMap::isValidKey(pdfUUID))
+ m_temporaryPDFFiles.add(pdfUUID, nsPath.get());
auto pdfFileURL = URL::fileURLWithFileSystemPath(String(nsPath.get()));
m_uiClient->confirmPDFOpening(*this, pdfFileURL, WTFMove(frameInfo), [pdfFileURL] (bool allowed) {
@@ -519,6 +518,7 @@
});
}
+#if ENABLE(PDFKIT_PLUGIN) && !ENABLE(UI_PROCESS_PDF_HUD)
void WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication(FrameInfoData&& frameInfo, const String& pdfUUID)
{
MESSAGE_CHECK(TemporaryPDFFileMap::isValidKey(pdfUUID));
@@ -535,6 +535,7 @@
[[NSWorkspace sharedWorkspace] openURL:pdfFileURL];
});
}
+#endif
#if ENABLE(PDFKIT_PLUGIN)
void WebPageProxy::showPDFContextMenu(const WebKit::PDFContextMenu& contextMenu, CompletionHandler<void(Optional<int32_t>&&)>&& completionHandler)
@@ -678,6 +679,49 @@
return [pageClient().platformWindow() contentView];
}
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+void WebPageProxy::createPDFHUD(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ pageClient().createPDFHUD(identifier, rect);
+}
+
+void WebPageProxy::removePDFHUD(PDFPluginIdentifier identifier)
+{
+ pageClient().removePDFHUD(identifier);
+}
+
+void WebPageProxy::updatePDFHUDLocation(PDFPluginIdentifier identifier, const WebCore::IntRect& rect)
+{
+ pageClient().updatePDFHUDLocation(identifier, rect);
+}
+
+void WebPageProxy::pdfZoomIn(PDFPluginIdentifier identifier)
+{
+ send(Messages::WebPage::ZoomPDFIn(identifier));
+}
+
+void WebPageProxy::pdfZoomOut(PDFPluginIdentifier identifier)
+{
+ send(Messages::WebPage::ZoomPDFOut(identifier));
+}
+
+void WebPageProxy::pdfSaveToPDF(PDFPluginIdentifier identifier)
+{
+ sendWithAsyncReply(Messages::WebPage::SavePDF(identifier), [this, protectedThis = makeRef(*this)] (String&& suggestedFilename, URL&& originatingURL, const IPC::DataReference& dataReference) {
+ savePDFToFileInDownloadsFolder(WTFMove(suggestedFilename), WTFMove(originatingURL), dataReference);
+ });
+}
+
+void WebPageProxy::pdfOpenWithPreview(PDFPluginIdentifier identifier)
+{
+ sendWithAsyncReply(Messages::WebPage::OpenPDFWithPreview(identifier), [this, protectedThis = makeRef(*this)] (String&& suggestedFilename, FrameInfoData&& frameInfo, const IPC::DataReference& data, const String& pdfUUID) {
+ savePDFToTemporaryFolderAndOpenWithNativeApplication(WTFMove(suggestedFilename), WTFMove(frameInfo), data, pdfUUID);
+ });
+}
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
+
} // namespace WebKit
#endif // PLATFORM(MAC)
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (266653 => 266654)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-09-05 04:07:47 UTC (rev 266654)
@@ -1786,6 +1786,7 @@
D3B9484911FF4B6500032B39 /* WebSearchPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */; };
DF462E0F23F22F5500EFF35F /* WKHTTPCookieStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
DF462E1223F338BE00EFF35F /* WKContentWorldPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ DF84CEE4249AA24D009096F6 /* WKPDFHUDView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */; };
E105FE5418D7B9DE008F57A8 /* EditingRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E105FE5318D7B9DE008F57A8 /* EditingRange.h */; };
E11D35AE16B63D1B006D23D7 /* com.apple.WebProcess.sb in Resources */ = {isa = PBXBuildFile; fileRef = E1967E37150AB5E200C73169 /* com.apple.WebProcess.sb */; };
E14A954A16E016A40068DE82 /* NetworkProcessPlatformStrategies.h in Headers */ = {isa = PBXBuildFile; fileRef = E14A954816E016A40068DE82 /* NetworkProcessPlatformStrategies.h */; };
@@ -5264,6 +5265,9 @@
DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentWorldPrivate.h; sourceTree = "<group>"; };
DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeWebWheelEvent.h; sourceTree = "<group>"; };
DF58C6351371ACA000F9A37C /* NativeWebWheelEventMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NativeWebWheelEventMac.mm; sourceTree = "<group>"; };
+ DF74275C24F4955000F8ABE9 /* PDFPluginIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFPluginIdentifier.h; sourceTree = "<group>"; };
+ DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKPDFHUDView.mm; path = PDF/WKPDFHUDView.mm; sourceTree = "<group>"; };
+ DF84CEE3249AA21F009096F6 /* WKPDFHUDView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKPDFHUDView.h; path = PDF/WKPDFHUDView.h; sourceTree = "<group>"; };
E105FE5318D7B9DE008F57A8 /* EditingRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingRange.h; sourceTree = "<group>"; };
E115C715190F8A2500ECC516 /* com.apple.WebKit.Storage.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = com.apple.WebKit.Storage.sb; path = DerivedSources/WebKit2/com.apple.WebKit.Storage.sb; sourceTree = BUILT_PRODUCTS_DIR; };
E133FD891423DD7F00FC7BFB /* WebKit.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = WebKit.icns; path = Resources/WebKit.icns; sourceTree = "<group>"; };
@@ -5885,6 +5889,7 @@
children = (
1A6FB90811E66FB100DB1371 /* Netscape */,
E199875B142BF9CF00BB2DE7 /* PDF */,
+ DF74275C24F4955000F8ABE9 /* PDFPluginIdentifier.h */,
1A6FB7D011E651E200DB1371 /* Plugin.cpp */,
1A6FB7D111E651E200DB1371 /* Plugin.h */,
1AA56F2811E92BC80061B882 /* PluginController.h */,
@@ -8938,6 +8943,7 @@
CD4570D82444CA1700A3DCEB /* Media */,
510CC7E716138E7200D03ED3 /* Network */,
31A2EC401489973700810D71 /* Notifications */,
+ DF84CEE1249AA200009096F6 /* PDF */,
1AEFCC0511D01F34008219D3 /* Plugins */,
2D1551A91F5A9B420006E3FE /* RemoteLayerTree */,
1AAF089E192681AC00B6390C /* UserContent */,
@@ -10425,6 +10431,15 @@
path = ios;
sourceTree = "<group>";
};
+ DF84CEE1249AA200009096F6 /* PDF */ = {
+ isa = PBXGroup;
+ children = (
+ DF84CEE3249AA21F009096F6 /* WKPDFHUDView.h */,
+ DF84CEE2249AA21F009096F6 /* WKPDFHUDView.mm */,
+ );
+ name = PDF;
+ sourceTree = "<group>";
+ };
E170876D16D6CA7200F99226 /* FileAPI */ = {
isa = PBXGroup;
children = (
@@ -13112,6 +13127,7 @@
637281A321ADC744009E0DE6 /* WKDownloadProgress.mm in Sources */,
5CE9120D2293C219005BEC78 /* WKMain.mm in Sources */,
4657D88A22664A2F005DE823 /* WKOrientationAccessAlert.mm in Sources */,
+ DF84CEE4249AA24D009096F6 /* WKPDFHUDView.mm in Sources */,
5CA26D83217AD1B800F97A35 /* WKSafeBrowsingWarning.mm in Sources */,
1DB01944211CF005009FB3E8 /* WKShareSheet.mm in Sources */,
7A78FF332241919B0096483E /* WKStorageAccessAlert.mm in Sources */,
Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFLayerControllerSPI.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -87,6 +87,12 @@
- (void)snapshotInContext:(CGContextRef)context;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+- (void)setDisplaysPDFHUDController:(BOOL)displaysController;
+- (void)zoomIn:(id)atPoint;
+- (void)zoomOut:(id)atPoint;
+#endif
+
- (void)magnifyWithMagnification:(CGFloat)magnification atPoint:(CGPoint)point immediately:(BOOL)immediately;
- (CGPoint)scrollPosition;
Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -28,6 +28,7 @@
#if ENABLE(PDFKIT_PLUGIN)
#include "PDFKitImports.h"
+#include "PDFPluginIdentifier.h"
#include "Plugin.h"
#include "WebEvent.h"
#include "WebHitTestResultData.h"
@@ -50,6 +51,7 @@
OBJC_CLASS NSArray;
OBJC_CLASS NSAttributedString;
OBJC_CLASS NSData;
+OBJC_CLASS NSEvent;
OBJC_CLASS NSString;
OBJC_CLASS PDFAnnotation;
OBJC_CLASS PDFLayerController;
@@ -77,8 +79,9 @@
class PDFPluginPasswordField;
class PluginView;
class WebFrame;
+struct FrameInfoData;
-class PDFPlugin final : public Plugin, private WebCore::ScrollableArea
+class PDFPlugin final : public Plugin, public WebCore::ScrollableArea
#if HAVE(INCREMENTAL_PDF_APIS)
, private WebCore::NetscapePlugInStreamLoaderClient
#endif
@@ -103,9 +106,19 @@
void notifySelectionChanged(PDFSelection *);
void notifyCursorChanged(uint64_t /* PDFLayerControllerCursorType */);
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ void zoomIn();
+ void zoomOut();
+ void save(CompletionHandler<void(const String&, const URL&, const IPC::DataReference&)>&&);
+ void openWithPreview(CompletionHandler<void(const String&, FrameInfoData&&, const IPC::DataReference&, const String&)>&&);
+ PDFPluginIdentifier identifier() const { return m_identifier; }
+#endif
+
void clickedLink(NSURL *);
+#if !ENABLE(UI_PROCESS_PDF_HUD)
void saveToPDF();
void openWithNativeApplication();
+#endif
void writeItemsToPasteboard(NSString *pasteboardName, NSArray *items, NSArray *types);
void showDefinitionForAttributedString(NSAttributedString *, CGPoint);
void performWebSearch(NSString *);
@@ -118,7 +131,10 @@
WebCore::FloatRect convertFromPDFViewToScreen(const WebCore::FloatRect&) const;
WebCore::IntPoint convertFromRootViewToPDFView(const WebCore::IntPoint&) const;
+ WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
+ WebCore::IntRect convertFromPDFViewToRootView(const WebCore::IntRect&) const;
WebCore::IntRect boundsOnScreen() const;
+ WebCore::IntRect frameForHUD() const;
bool showContextMenuAtPoint(const WebCore::IntPoint&);
@@ -159,7 +175,7 @@
bool wantsWheelEvents() final { return true; }
void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) final;
void contentsScaleFactorChanged(float) final;
- void visibilityDidChange(bool) final { }
+ void visibilityDidChange(bool) final;
void frameDidFinishLoading(uint64_t requestID) final;
void frameDidFail(uint64_t requestID, bool wasCancelled) final;
void didEvaluateJavaScript(uint64_t requestID, const String& result) final;
@@ -263,7 +279,6 @@
NSEvent *nsEventForWebMouseEvent(const WebMouseEvent&);
WebCore::IntPoint convertFromPluginToPDFView(const WebCore::IntPoint&) const;
WebCore::IntPoint convertFromRootViewToPlugin(const WebCore::IntPoint&) const;
- WebCore::IntPoint convertFromPDFViewToRootView(const WebCore::IntPoint&) const;
bool supportsForms();
bool isFullFramePlugin() const;
@@ -403,6 +418,9 @@
#endif
#endif // HAVE(INCREMENTAL_PDF_APIS)
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ PDFPluginIdentifier m_identifier;
+#endif
};
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -433,12 +433,16 @@
- (void)openWithNativeApplication
{
+#if !ENABLE(UI_PROCESS_PDF_HUD)
_pdfPlugin->openWithNativeApplication();
+#endif
}
- (void)saveToPDF
{
+#if !ENABLE(UI_PROCESS_PDF_HUD)
_pdfPlugin->saveToPDF();
+#endif
}
- (void)pdfLayerController:(PDFLayerController *)pdfLayerController clickedLinkWithURL:(NSURL *)url
@@ -600,7 +604,13 @@
#if HAVE(INCREMENTAL_PDF_APIS)
, m_incrementalPDFLoadingEnabled(WebCore::RuntimeEnabledFeatures::sharedFeatures().incrementalPDFLoadingEnabled())
#endif
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ , m_identifier(PDFPluginIdentifier::generate())
+#endif
{
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ [m_pdfLayerController setDisplaysPDFHUDController:NO];
+#endif
m_pdfLayerController.get().delegate = m_pdfLayerControllerDelegate.get();
m_pdfLayerController.get().parentLayer = m_contentLayer.get();
@@ -640,6 +650,10 @@
PDFPlugin::~PDFPlugin()
{
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ if (auto* page = m_frame.page())
+ page->removePDFHUD(*this);
+#endif
}
#if HAVE(INCREMENTAL_PDF_APIS)
@@ -1780,6 +1794,11 @@
updatePageAndDeviceScaleFactors();
}
+IntRect PDFPlugin::frameForHUD() const
+{
+ return convertFromPDFViewToRootView(IntRect(IntPoint(), size()));
+}
+
void PDFPlugin::calculateSizes()
{
if ([m_pdfDocument isLocked]) {
@@ -1790,6 +1809,10 @@
m_firstPageHeight = [m_pdfDocument pageCount] ? static_cast<unsigned>(CGCeiling([[m_pdfDocument pageAtIndex:0] boundsForBox:kPDFDisplayBoxCropBox].size.height)) : 0;
setPDFDocumentSize(IntSize([m_pdfLayerController contentSizeRespectingZoom]));
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ m_frame.page()->updatePDFHUDLocation(*this, frameForHUD());
+#endif
}
bool PDFPlugin::initialize(const Parameters& parameters)
@@ -1924,7 +1947,13 @@
IntPoint pointInPluginCoordinates(point.x(), size().height() - point.y());
return m_rootViewToPluginTransform.inverse().valueOr(AffineTransform()).mapPoint(pointInPluginCoordinates);
}
-
+
+IntRect PDFPlugin::convertFromPDFViewToRootView(const IntRect& rect) const
+{
+ IntRect rectInPluginCoordinates(rect.x(), rect.y(), rect.width(), rect.height());
+ return m_rootViewToPluginTransform.inverse().valueOr(AffineTransform()).mapRect(rectInPluginCoordinates);
+}
+
IntPoint PDFPlugin::convertFromRootViewToPDFView(const IntPoint& point) const
{
IntPoint pointInPluginCoordinates = m_rootViewToPluginTransform.mapPoint(point);
@@ -1955,6 +1984,18 @@
return frameView->contentsToScreen(enclosingIntRect(rectInRootViewCoordinates));
}
+void PDFPlugin::visibilityDidChange(bool visible)
+{
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ if (visible)
+ m_frame.page()->createPDFHUD(*this, frameForHUD());
+ else
+ m_frame.page()->removePDFHUD(*this);
+#else
+ UNUSED_PARAM(visible);
+#endif
+}
+
void PDFPlugin::geometryDidChange(const IntSize& pluginSize, const IntRect&, const AffineTransform& pluginToRootViewTransform)
{
if (size() == pluginSize && pluginView()->pageScaleFactor() == [m_pdfLayerController contentScaleFactor])
@@ -2400,6 +2441,31 @@
return true;
}
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+void PDFPlugin::zoomIn()
+{
+ [m_pdfLayerController zoomIn:nil];
+}
+
+void PDFPlugin::zoomOut()
+{
+ [m_pdfLayerController zoomOut:nil];
+}
+
+void PDFPlugin::save(CompletionHandler<void(const String&, const URL&, const IPC::DataReference&)>&& completionHandler)
+{
+ NSData *data = ""
+ completionHandler(m_suggestedFilename, m_frame.url(), IPC:: DataReference(static_cast<const uint8_t*>(data.bytes), data.length));
+}
+
+void PDFPlugin::openWithPreview(CompletionHandler<void(const String&, FrameInfoData&&, const IPC::DataReference&, const String&)>&& completionHandler)
+{
+ NSData *data = ""
+ completionHandler(m_suggestedFilename, m_frame.info(), IPC:: DataReference { static_cast<const uint8_t*>(data.bytes), data.length }, createCanonicalUUIDString());
+}
+
+#else // ENABLE(UI_PROCESS_PDF_HUD)
void PDFPlugin::saveToPDF()
{
@@ -2432,6 +2498,8 @@
m_frame.page()->send(Messages::WebPageProxy::OpenPDFFromTemporaryFolderWithNativeApplication(m_frame.info(), m_temporaryPDFUUID));
}
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
+
void PDFPlugin::writeItemsToPasteboard(NSString *pasteboardName, NSArray *items, NSArray *types)
{
auto pasteboardTypes = makeVector<String>(types);
Copied: trunk/Source/WebKit/WebProcess/Plugins/PDFPluginIdentifier.h (from rev 266653, trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h) (0 => 266654)
--- trunk/Source/WebKit/WebProcess/Plugins/PDFPluginIdentifier.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/Plugins/PDFPluginIdentifier.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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
+
+#include <wtf/ObjectIdentifier.h>
+
+namespace WebKit {
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+enum PDFPluginIdentifierType { };
+using PDFPluginIdentifier = ObjectIdentifier<PDFPluginIdentifierType>;
+#endif
+
+}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-09-05 04:07:47 UTC (rev 266654)
@@ -5120,12 +5120,12 @@
}
#endif
+#if ENABLE(PDFKIT_PLUGIN) && !ENABLE(UI_PROCESS_PDF_HUD)
void WebPage::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const URL& originatingURL, const uint8_t* data, unsigned long size)
{
send(Messages::WebPageProxy::SavePDFToFileInDownloadsFolder(suggestedFilename, originatingURL, IPC::DataReference(data, size)));
}
-#if PLATFORM(COCOA)
void WebPage::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, FrameInfoData&& frameInfo, const uint8_t* data, unsigned long size, const String& pdfUUID)
{
send(Messages::WebPageProxy::SavePDFToTemporaryFolderAndOpenWithNativeApplication(suggestedFilename, frameInfo, IPC::DataReference(data, size), pdfUUID));
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -45,6 +45,7 @@
#include "MessageReceiver.h"
#include "MessageSender.h"
#include "OptionalCallbackID.h"
+#include "PDFPluginIdentifier.h"
#include "Plugin.h"
#include "PolicyDecision.h"
#include "SandboxExtension.h"
@@ -345,6 +346,16 @@
void centerSelectionInVisibleArea();
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ void createPDFHUD(PDFPlugin&, const WebCore::IntRect&);
+ void updatePDFHUDLocation(PDFPlugin&, const WebCore::IntRect&);
+ void removePDFHUD(PDFPlugin&);
+ void zoomPDFIn(PDFPluginIdentifier);
+ void zoomPDFOut(PDFPluginIdentifier);
+ void savePDF(PDFPluginIdentifier, CompletionHandler<void(const String&, const URL&, const IPC::DataReference&)>&&);
+ void openPDFWithPreview(PDFPluginIdentifier, CompletionHandler<void(const String&, FrameInfoData&&, const IPC::DataReference&, const String&)>&&);
+#endif
+
#if PLATFORM(COCOA)
void willCommitLayerTree(RemoteLayerTreeTransaction&);
void didFlushLayerTreeAtTime(MonotonicTime);
@@ -1073,9 +1084,8 @@
NSDictionary *dataDetectionContext() const { return m_dataDetectionContext.get(); }
#endif
+#if ENABLE(PDFKIT_PLUGIN) && !ENABLE(UI_PROCESS_PDF_HUD)
void savePDFToFileInDownloadsFolder(const String& suggestedFilename, const URL& originatingURL, const uint8_t* data, unsigned long size);
-
-#if PLATFORM(COCOA)
void savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, FrameInfoData&&, const uint8_t* data, unsigned long size, const String& pdfUUID);
#endif
@@ -1790,6 +1800,10 @@
WebCore::Color m_underlayColor;
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ HashMap<PDFPluginIdentifier, WeakPtr<PDFPlugin>> m_pdfPlugInsWithHUD;
+#endif
+
bool m_isInRedo { false };
bool m_isClosed { false };
bool m_tabToLinks { false };
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-09-05 04:07:47 UTC (rev 266654)
@@ -575,6 +575,13 @@
SetDefersLoading(bool defersLoading)
+#if ENABLE(UI_PROCESS_PDF_HUD)
+ ZoomPDFIn(WebKit::PDFPluginIdentifier identifier)
+ ZoomPDFOut(WebKit::PDFPluginIdentifier identifier)
+ SavePDF(WebKit::PDFPluginIdentifier identifier) -> (String filename, URL url, IPC::DataReference data) Async
+ OpenPDFWithPreview(WebKit::PDFPluginIdentifier identifier) -> (String filename, struct WebKit::FrameInfoData frameInfo, IPC::DataReference data, String uuid) Async
+#endif
+
UpdateCurrentModifierState(OptionSet<WebCore::PlatformEvent::Modifier> modifiers)
SimulateDeviceOrientationChange(double alpha, double beta, double gamma)
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (266653 => 266654)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -33,6 +33,7 @@
#import "EditingRange.h"
#import "EditorState.h"
#import "FontInfo.h"
+#import "FrameInfoData.h"
#import "InjectedBundleHitTestResult.h"
#import "PDFKitImports.h"
#import "PDFPlugin.h"
@@ -1051,8 +1052,63 @@
[NSApp _setAccentColor:color.isValid() ? WebCore::nsColor(color) : nil];
}
-#endif
+#endif // HAVE(APP_ACCENT_COLORS)
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+void WebPage::zoomPDFIn(PDFPluginIdentifier identifier)
+{
+ auto pdfPlugin = m_pdfPlugInsWithHUD.get(identifier);
+ if (!pdfPlugin)
+ return;
+ pdfPlugin->zoomIn();
+}
+
+void WebPage::zoomPDFOut(PDFPluginIdentifier identifier)
+{
+ auto pdfPlugin = m_pdfPlugInsWithHUD.get(identifier);
+ if (!pdfPlugin)
+ return;
+ pdfPlugin->zoomOut();
+}
+
+void WebPage::savePDF(PDFPluginIdentifier identifier, CompletionHandler<void(const String&, const URL&, const IPC::DataReference&)>&& completionHandler)
+{
+ auto pdfPlugin = m_pdfPlugInsWithHUD.get(identifier);
+ if (!pdfPlugin)
+ return completionHandler({ }, { }, { });
+ pdfPlugin->save(WTFMove(completionHandler));
+}
+
+void WebPage::openPDFWithPreview(PDFPluginIdentifier identifier, CompletionHandler<void(const String&, FrameInfoData&&, const IPC::DataReference&, const String&)>&& completionHandler)
+{
+ auto pdfPlugin = m_pdfPlugInsWithHUD.get(identifier);
+ if (!pdfPlugin)
+ return completionHandler({ }, { }, { }, { });
+ pdfPlugin->openWithPreview(WTFMove(completionHandler));
+}
+
+void WebPage::createPDFHUD(PDFPlugin& plugin, const IntRect& boundingBox)
+{
+ auto addResult = m_pdfPlugInsWithHUD.add(plugin.identifier(), makeWeakPtr(plugin));
+ if (addResult.isNewEntry)
+ send(Messages::WebPageProxy::CreatePDFHUD(plugin.identifier(), boundingBox));
+}
+
+void WebPage::updatePDFHUDLocation(PDFPlugin& plugin, const IntRect& boundingBox)
+{
+ if (m_pdfPlugInsWithHUD.contains(plugin.identifier()))
+ send(Messages::WebPageProxy::UpdatePDFHUDLocation(plugin.identifier(), boundingBox));
+}
+
+void WebPage::removePDFHUD(PDFPlugin& plugin)
+{
+ if (m_pdfPlugInsWithHUD.remove(plugin.identifier()))
+ send(Messages::WebPageProxy::RemovePDFHUD(plugin.identifier()));
+}
+
+#endif // ENABLE(UI_PROCESS_PDF_HUD)
+
} // namespace WebKit
#endif // PLATFORM(MAC)
Modified: trunk/Tools/ChangeLog (266653 => 266654)
--- trunk/Tools/ChangeLog 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Tools/ChangeLog 2020-09-05 04:07:47 UTC (rev 266654)
@@ -1,3 +1,19 @@
+2020-09-04 Alex Christensen <[email protected]>
+
+ Move PDF heads-up display to UI process on macOS
+ https://bugs.webkit.org/show_bug.cgi?id=215780
+ <rdar://problem/58715847>
+
+ Reviewed by Tim Horton.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm:
+ (pdfData):
+ (TEST):
+ (checkFrame):
+ * TestWebKitAPI/cocoa/TestUIDelegate.h:
+ * TestWebKitAPI/cocoa/TestUIDelegate.mm:
+ (-[TestUIDelegate _webView:saveDataToFile:suggestedFilename:mimeType:originatingURL:]):
+
2020-09-04 Jonathan Bedard <[email protected]>
[webkitcorepy] Add mock Response object
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm (266653 => 266654)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKPDFView.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -30,12 +30,27 @@
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
+#import "TestUIDelegate.h"
+#import "TestURLSchemeHandler.h"
+#import "TestWKWebView.h"
#import <WebKit/WKWebView.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebViewPrivateForTesting.h>
#import <wtf/RetainPtr.h>
-#if HAVE(PDFKIT) && PLATFORM(IOS)
+#if PLATFORM(MAC)
+#import <Carbon/Carbon.h>
+#endif
+#if PLATFORM(IOS) || ENABLE(UI_PROCESS_PDF_HUD)
+static NSData *pdfData()
+{
+ return [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"test" withExtension:@"pdf" subdirectory:@"TestWebKitAPI.resources"]];
+}
+#endif
+
+#if PLATFORM(IOS)
+
@interface PDFHostViewController : UIViewController
+ (void)createHostView:(void(^)(id hostViewController))callback forExtensionIdentifier:(NSString *)extensionIdentifier;
@end
@@ -101,7 +116,7 @@
RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
// Load a PDF, so we install a WKPDFView.
- [webView loadData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"test" withExtension:@"pdf" subdirectory:@"TestWebKitAPI.resources"]] MIMEType:@"application/pdf" characterEncodingName:@"" baseURL:[NSURL URLWithString:@"https://www.apple.com/0"]];
+ [webView loadData:pdfData() MIMEType:@"application/pdf" characterEncodingName:@"" baseURL:[NSURL URLWithString:@"https://www.apple.com/0"]];
[webView _test_waitForDidFinishNavigation];
// Go into the background and parent the WKWebView.
@@ -132,3 +147,208 @@
}
#endif
+
+#if ENABLE(UI_PROCESS_PDF_HUD)
+
+static void checkFrame(NSRect frame, CGFloat x, CGFloat y, CGFloat width, CGFloat height)
+{
+ EXPECT_EQ(frame.origin.x, x);
+ EXPECT_EQ(frame.origin.y, y);
+ EXPECT_EQ(frame.size.width, width);
+ EXPECT_EQ(frame.size.height, height);
+}
+
+TEST(PDFHUD, MainResourcePDF)
+{
+ TestWKWebView *webView = [[[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:[[WKWebViewConfiguration new] autorelease]] autorelease];
+ [webView loadData:pdfData() MIMEType:@"application/pdf" characterEncodingName:@"" baseURL:[NSURL URLWithString:@"https://www.apple.com/testPath"]];
+ EXPECT_EQ(webView._pdfHUDs.count, 0u);
+ [webView _test_waitForDidFinishNavigation];
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 0, 0, 800, 600);
+
+ TestUIDelegate *delegate = [[TestUIDelegate new] autorelease];
+ webView.UIDelegate = delegate;
+ __block bool saveRequestReceived = false;
+ delegate.saveDataToFile = ^(WKWebView *webViewFromDelegate, NSData *data, NSString *suggestedFilename, NSString *mimeType, NSURL *originatingURL) {
+ EXPECT_EQ(webView, webViewFromDelegate);
+ EXPECT_TRUE([data isEqualToData:pdfData()]);
+ EXPECT_WK_STREQ(suggestedFilename, "testPath.pdf");
+ EXPECT_WK_STREQ(mimeType, "application/pdf");
+ saveRequestReceived = true;
+ };
+ [[webView _pdfHUDs].anyObject performSelector:NSSelectorFromString(@"_performActionForControl:") withObject:@"arrow.down.circle"];
+ TestWebKitAPI::Util::run(&saveRequestReceived);
+
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ [webView _killWebContentProcess];
+ while (webView._pdfHUDs.count)
+ TestWebKitAPI::Util::spinRunLoop();
+}
+
+TEST(PDFHUD, MoveIFrame)
+{
+ TestURLSchemeHandler *handler = [[TestURLSchemeHandler new] autorelease];
+ handler.startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {
+ if ([task.request.URL.path isEqualToString:@"/main.html"]) {
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease];
+ const char* html = "<br/><iframe src='' id='pdfframe'></iframe>";
+ [task didReceiveResponse:response];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ } else {
+ EXPECT_WK_STREQ(task.request.URL.path, "/test.pdf");
+ NSData *data = ""
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"application/pdf" expectedContentLength:data.length textEncodingName:nil] autorelease];
+ [task didReceiveResponse:response];
+ [task didReceiveData:data];
+ [task didFinish];
+ }
+ };
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration new] autorelease];
+ [configuration setURLSchemeHandler:handler forURLScheme:@"test"];
+ TestWKWebView *webView = [[[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration] autorelease];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///main.html"]]];
+ EXPECT_EQ(webView._pdfHUDs.count, 0u);
+ [webView _test_waitForDidFinishNavigation];
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 10, 28, 300, 150);
+
+ [webView evaluateJavaScript:@"pdfframe.width=400" completionHandler:nil];
+ while (webView._pdfHUDs.anyObject.frame.size.width != 400)
+ TestWebKitAPI::Util::spinRunLoop();
+ checkFrame(webView._pdfHUDs.anyObject.frame, 10, 28, 400, 150);
+
+ [webView evaluateJavaScript:@"var frameReference = pdfframe; document.body.removeChild(pdfframe)" completionHandler:nil];
+ while (webView._pdfHUDs.count)
+ TestWebKitAPI::Util::spinRunLoop();
+ [webView evaluateJavaScript:@"document.body.appendChild(frameReference)" completionHandler:nil];
+ while (!webView._pdfHUDs.count)
+ TestWebKitAPI::Util::spinRunLoop();
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 0, 0, 0, 0);
+ while (webView._pdfHUDs.anyObject.frame.size.width != 400)
+ TestWebKitAPI::Util::spinRunLoop();
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 10, 28, 400, 150);
+
+ webView.pageZoom = 1.4;
+ while (webView._pdfHUDs.anyObject.frame.size.width != 560)
+ TestWebKitAPI::Util::spinRunLoop();
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 14, 40, 560, 210);
+}
+
+TEST(PDFHUD, NestedIFrames)
+{
+ TestURLSchemeHandler *handler = [[TestURLSchemeHandler new] autorelease];
+ handler.startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {
+ NSURLResponse *htmlResponse = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease];
+ if ([task.request.URL.path isEqualToString:@"/main.html"]) {
+ const char* html = "<iframe src='' id='parentframe'></iframe>";
+ [task didReceiveResponse:htmlResponse];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ } else if ([task.request.URL.path isEqualToString:@"/frame.html"]) {
+ const char* html = "<iframe src=''></iframe>";
+ [task didReceiveResponse:htmlResponse];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ } else {
+ EXPECT_WK_STREQ(task.request.URL.path, "/test.pdf");
+ NSData *data = ""
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"application/pdf" expectedContentLength:data.length textEncodingName:nil] autorelease];
+ [task didReceiveResponse:response];
+ [task didReceiveData:data];
+ [task didFinish];
+ }
+ };
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration new] autorelease];
+ [configuration setURLSchemeHandler:handler forURLScheme:@"test"];
+ TestWKWebView *webView = [[[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration] autorelease];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///main.html"]]];
+ EXPECT_EQ(webView._pdfHUDs.count, 0u);
+ [webView _test_waitForDidFinishNavigation];
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 20, 20, 300, 150);
+
+ [webView evaluateJavaScript:@"document.body.removeChild(parentframe)" completionHandler:nil];
+ while (webView._pdfHUDs.count)
+ TestWebKitAPI::Util::spinRunLoop();
+}
+
+TEST(PDFHUD, IFrame3DTransform)
+{
+ TestURLSchemeHandler *handler = [[TestURLSchemeHandler new] autorelease];
+ handler.startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {
+ NSURLResponse *htmlResponse = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease];
+ if ([task.request.URL.path isEqualToString:@"/main.html"]) {
+ const char* html = "<iframe src='' height=500 width=500 style='transform:rotateY(235deg);'></iframe>";
+ [task didReceiveResponse:htmlResponse];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ } else {
+ EXPECT_WK_STREQ(task.request.URL.path, "/test.pdf");
+ NSData *data = ""
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"application/pdf" expectedContentLength:data.length textEncodingName:nil] autorelease];
+ [task didReceiveResponse:response];
+ [task didReceiveData:data];
+ [task didFinish];
+ }
+ };
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration new] autorelease];
+ [configuration setURLSchemeHandler:handler forURLScheme:@"test"];
+ TestWKWebView *webView = [[[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration] autorelease];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///main.html"]]];
+ EXPECT_EQ(webView._pdfHUDs.count, 0u);
+ [webView _test_waitForDidFinishNavigation];
+ EXPECT_EQ(webView._pdfHUDs.count, 1u);
+ checkFrame(webView._pdfHUDs.anyObject.frame, 403, 10, 500, 500);
+}
+
+TEST(PDFHUD, MultipleIFrames)
+{
+ TestURLSchemeHandler *handler = [[TestURLSchemeHandler new] autorelease];
+ handler.startURLSchemeTaskHandler = ^(WKWebView *, id<WKURLSchemeTask> task) {
+ NSURLResponse *htmlResponse = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil] autorelease];
+ if ([task.request.URL.path isEqualToString:@"/main.html"]) {
+ const char* html = "<iframe src='' height=100 width=150></iframe><iframe src='' height=123 width=134></iframe>";
+ [task didReceiveResponse:htmlResponse];
+ [task didReceiveData:[NSData dataWithBytes:html length:strlen(html)]];
+ [task didFinish];
+ } else {
+ EXPECT_WK_STREQ(task.request.URL.path, "/test.pdf");
+ NSData *data = ""
+ NSURLResponse *response = [[[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"application/pdf" expectedContentLength:data.length textEncodingName:nil] autorelease];
+ [task didReceiveResponse:response];
+ [task didReceiveData:data];
+ [task didFinish];
+ }
+ };
+
+ WKWebViewConfiguration *configuration = [[WKWebViewConfiguration new] autorelease];
+ [configuration setURLSchemeHandler:handler forURLScheme:@"test"];
+ TestWKWebView *webView = [[[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration] autorelease];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"test:///main.html"]]];
+ EXPECT_EQ(webView._pdfHUDs.count, 0u);
+ [webView _test_waitForDidFinishNavigation];
+ EXPECT_EQ(webView._pdfHUDs.count, 2u);
+ bool hadLeftFrame = false;
+ bool hadRightFrame = false;
+ for (NSView *hud in webView._pdfHUDs) {
+ if (hud.frame.origin.x == 10) {
+ checkFrame(hud.frame, 10, 33, 150, 100);
+ hadLeftFrame = true;
+ } else {
+ checkFrame(hud.frame, 164, 10, 134, 123);
+ hadRightFrame = true;
+ }
+ }
+ EXPECT_TRUE(hadLeftFrame);
+ EXPECT_TRUE(hadRightFrame);
+}
+
+#endif
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h (266653 => 266654)
--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.h 2020-09-05 04:07:47 UTC (rev 266654)
@@ -31,6 +31,7 @@
#if PLATFORM(MAC)
@property (nonatomic, copy) void (^getContextMenuFromProposedMenu)(NSMenu *, _WKContextMenuElementInfo *, id <NSSecureCoding>, void (^)(NSMenu *));
#endif
+@property (nonatomic, copy) void (^saveDataToFile)(WKWebView *, NSData *, NSString *, NSString *, NSURL *);
- (NSString *)waitForAlert;
Modified: trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm (266653 => 266654)
--- trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm 2020-09-05 03:52:42 UTC (rev 266653)
+++ trunk/Tools/TestWebKitAPI/cocoa/TestUIDelegate.mm 2020-09-05 04:07:47 UTC (rev 266654)
@@ -50,6 +50,12 @@
}
#endif // PLATFORM(MAC)
+- (void)_webView:(WKWebView *)webView saveDataToFile:(NSData *)data suggestedFilename:(NSString *)suggestedFilename mimeType:(NSString *)mimeType originatingURL:(NSURL *)url
+{
+ if (_saveDataToFile)
+ _saveDataToFile(webView, data, suggestedFilename, mimeType, url);
+}
+
- (NSString *)waitForAlert
{
EXPECT_FALSE(self.runJavaScriptAlertPanelWithMessage);