Title: [217571] trunk
Revision
217571
Author
[email protected]
Date
2017-05-30 14:01:59 -0700 (Tue, 30 May 2017)

Log Message

[WK2] Add runBeforeUnloadConfirmPanel WKUIDelegate SPI; support onbeforeunload confirm panel in MiniBrowser
https://bugs.webkit.org/show_bug.cgi?id=172603
<rdar://problem/32471306>

Reviewed by Brady Eidson.

Source/WebKit2:

A page loaded in MiniBrowser using WebKit2 cannot show a beforeunload confirm panel (by registering
an onbeforeunload event handler) when it is unloaded. The same page loaded in MiniBrowser using
WebKit1 can show such a confirm panel. We need to add WKUIDelegate SPI so that an embedding client,
such as MiniBrowser, can register to receive a callback to show a beforeunload confirm panel.

* UIProcess/API/APIUIClient.h:
(API::UIClient::runBeforeUnloadConfirmPanel): Modified to take a SecurityOriginData object. This
makes the API consistent with the existing _javascript_ dialog callbacks.
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageUIClient):
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h: Add SPI -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView setUIDelegate:]): Set the delegate of WebKit::UIDelegate to the specified WKUIDelegate
before we set the UI client on the page so as to ensure that API::UIClient callbacks that depend
-respondsToSelector: checks (e.g. API::UIClient::canRunBeforeUnloadConfirmPanel()) return the correct
result. To elaborate further, a API::UIClient client must override both canRunBeforeUnloadConfirmPanel()
and runBeforeUnloadConfirmPanel() to support running a beforeunload confirm dialog. When mapping
the Cocoa SPI, WKUIDelegatePrivate, to API::UIClient we implement API::UIClient::canRunBeforeUnloadConfirmPanel()
in terms of whether the Cocoa delegate responds at runtime to the selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
We need to do such runtime checks before we pass the API::UIClient to the page. Otherwise, querying
API::UIClient::canRunBeforeUnloadConfirmPanel() will return the wrong result.
* UIProcess/API/gtk/WebKitUIClient.cpp: Modified runBeforeUnloadConfirmPanel() to take a SecurityOriginData object.
* UIProcess/Cocoa/UIDelegate.h: Add declarations for API::UIClient overrides: canRunBeforeUnloadConfirmPanel()
and runBeforeUnloadConfirmPanel(). Add a bit to m_delegateMethods as to whether the Cocoa delegate
responds to selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::setDelegate): Set the above m_delegateMethods bit if the Cocoa delegate responds
to selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
(WebKit::UIDelegate::UIClient::canRunBeforeUnloadConfirmPanel): Return whether the above m_delegateMethods
bit was set.
(WebKit::UIDelegate::UIClient::runBeforeUnloadConfirmPanel): Turn around and call -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: (if applicable).
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::runBeforeUnloadConfirmPanel): Modified to take a SecurityOriginData object
and pass it to API::UIClient::runBeforeUnloadConfirmPanel().
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in: Add SecurityOriginData argument to message RunBeforeUnloadConfirmPanel.
Also pass the message for the panel as the last argument so as to make the order of arguments to message
RunBeforeUnloadConfirmPanel more closely match the order of arguments passed to other _javascript_ dialog
messages (e.g. RunJavaScriptAlert) for consistency.
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): Include the SecurityOriginData object for the
frame in message RunBeforeUnloadConfirmPanel.

Tools:

Implement the -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: delegate
method in MiniBrowser to show a confirm panel as to whether to allow the unloading of the page when
unloading is initiated for a page that registered a onbeforeunload handler.

Modify TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm to test that the -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:
is called. Also fix style nit; pass YES instead of true to avoid implicit conversion from bool to BOOL
when invoking the completion handler in -_webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:.

Until we fix <https://bugs.webkit.org/show_bug.cgi?id=172614> the unit test in TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm
for -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: is only run on Mac
as we do not have the infrastructure to simulate a click/tap on iOS and a click/tap on the page that
registered an onbeforeunload handler is required to show a confirm panel when the page will be unloaded.

* MiniBrowser/mac/WK2BrowserWindowController.m:
(-[WK2BrowserWindowController _webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):
* TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html:
* TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm:
(sawDialog):
(-[ModalAlertsUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
(-[ModalAlertsUIDelegate webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):
(-[ModalAlertsUIDelegate _webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (217570 => 217571)


--- trunk/Source/WebKit2/ChangeLog	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/ChangeLog	2017-05-30 21:01:59 UTC (rev 217571)
@@ -1,3 +1,54 @@
+2017-05-30  Daniel Bates  <[email protected]>
+
+        [WK2] Add runBeforeUnloadConfirmPanel WKUIDelegate SPI; support onbeforeunload confirm panel in MiniBrowser
+        https://bugs.webkit.org/show_bug.cgi?id=172603
+        <rdar://problem/32471306>
+
+        Reviewed by Brady Eidson.
+
+        A page loaded in MiniBrowser using WebKit2 cannot show a beforeunload confirm panel (by registering
+        an onbeforeunload event handler) when it is unloaded. The same page loaded in MiniBrowser using
+        WebKit1 can show such a confirm panel. We need to add WKUIDelegate SPI so that an embedding client,
+        such as MiniBrowser, can register to receive a callback to show a beforeunload confirm panel.
+
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::runBeforeUnloadConfirmPanel): Modified to take a SecurityOriginData object. This
+        makes the API consistent with the existing _javascript_ dialog callbacks.
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageUIClient):
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h: Add SPI -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView setUIDelegate:]): Set the delegate of WebKit::UIDelegate to the specified WKUIDelegate
+        before we set the UI client on the page so as to ensure that API::UIClient callbacks that depend
+        -respondsToSelector: checks (e.g. API::UIClient::canRunBeforeUnloadConfirmPanel()) return the correct
+        result. To elaborate further, a API::UIClient client must override both canRunBeforeUnloadConfirmPanel()
+        and runBeforeUnloadConfirmPanel() to support running a beforeunload confirm dialog. When mapping
+        the Cocoa SPI, WKUIDelegatePrivate, to API::UIClient we implement API::UIClient::canRunBeforeUnloadConfirmPanel()
+        in terms of whether the Cocoa delegate responds at runtime to the selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
+        We need to do such runtime checks before we pass the API::UIClient to the page. Otherwise, querying
+        API::UIClient::canRunBeforeUnloadConfirmPanel() will return the wrong result.
+        * UIProcess/API/gtk/WebKitUIClient.cpp: Modified runBeforeUnloadConfirmPanel() to take a SecurityOriginData object.
+        * UIProcess/Cocoa/UIDelegate.h: Add declarations for API::UIClient overrides: canRunBeforeUnloadConfirmPanel()
+        and runBeforeUnloadConfirmPanel(). Add a bit to m_delegateMethods as to whether the Cocoa delegate
+        responds to selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::UIDelegate::setDelegate): Set the above m_delegateMethods bit if the Cocoa delegate responds
+        to selector -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:.
+        (WebKit::UIDelegate::UIClient::canRunBeforeUnloadConfirmPanel): Return whether the above m_delegateMethods
+        bit was set.
+        (WebKit::UIDelegate::UIClient::runBeforeUnloadConfirmPanel): Turn around and call -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: (if applicable).
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::runBeforeUnloadConfirmPanel): Modified to take a SecurityOriginData object
+        and pass it to API::UIClient::runBeforeUnloadConfirmPanel().
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in: Add SecurityOriginData argument to message RunBeforeUnloadConfirmPanel.
+        Also pass the message for the panel as the last argument so as to make the order of arguments to message
+        RunBeforeUnloadConfirmPanel more closely match the order of arguments passed to other _javascript_ dialog
+        messages (e.g. RunJavaScriptAlert) for consistency.
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::runBeforeUnloadConfirmPanel): Include the SecurityOriginData object for the
+        frame in message RunBeforeUnloadConfirmPanel.
+
 2017-05-30  Alex Christensen  <[email protected]>
 
         Update libwebrtc configuration

Modified: trunk/Source/WebKit2/UIProcess/API/APIUIClient.h (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/API/APIUIClient.h	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/API/APIUIClient.h	2017-05-30 21:01:59 UTC (rev 217571)
@@ -115,7 +115,7 @@
     virtual WebCore::FloatRect windowFrame(WebKit::WebPageProxy*) { return WebCore::FloatRect(); }
 
     virtual bool canRunBeforeUnloadConfirmPanel() const { return false; }
-    virtual void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, Function<void (bool)>&& completionHandler) { completionHandler(true); }
+    virtual void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) { completionHandler(true); }
 
     virtual void pageDidScroll(WebKit::WebPageProxy*) { }
 

Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPage.cpp	2017-05-30 21:01:59 UTC (rev 217571)
@@ -2060,7 +2060,7 @@
             return m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6 || m_client.runBeforeUnloadConfirmPanel;
         }
 
-        void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, Function<void (bool)>&& completionHandler) override
+        void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, const SecurityOriginData&, Function<void (bool)>&& completionHandler) override
         {
             if (m_client.runBeforeUnloadConfirmPanel) {
                 RefPtr<RunBeforeUnloadConfirmPanelResultListener> listener = RunBeforeUnloadConfirmPanelResultListener::create(WTFMove(completionHandler));

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegatePrivate.h (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2017-05-30 21:01:59 UTC (rev 217571)
@@ -70,6 +70,8 @@
 - (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures completionHandler:(void (^)(WKWebView *webView))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
+- (void)_webView:(WKWebView *)webView runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 #if TARGET_OS_IPHONE
 - (BOOL)_webView:(WKWebView *)webView shouldIncludeAppLinkActionsForElement:(_WKActivatedElementInfo *)element WK_API_AVAILABLE(ios(9.0));
 - (NSArray *)_webView:(WKWebView *)webView actionsForElement:(_WKActivatedElementInfo *)element defaultActions:(NSArray<_WKElementAction *> *)defaultActions;

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-05-30 21:01:59 UTC (rev 217571)
@@ -707,11 +707,11 @@
 
 - (void)setUIDelegate:(id<WKUIDelegate>)UIDelegate
 {
+    _uiDelegate->setDelegate(UIDelegate);
 #if ENABLE(CONTEXT_MENUS)
     _page->setContextMenuClient(_uiDelegate->createContextMenuClient());
 #endif
     _page->setUIClient(_uiDelegate->createUIClient());
-    _uiDelegate->setDelegate(UIDelegate);
 }
 
 - (id <_WKIconLoadingDelegate>)_iconLoadingDelegate

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp	2017-05-30 21:01:59 UTC (rev 217571)
@@ -86,7 +86,7 @@
 
     bool canRunBeforeUnloadConfirmPanel() const override { return true; }
 
-    void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, Function<void (bool)>&& completionHandler) override
+    void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) override
     {
         completionHandler(webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8()));
     }

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.h (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.h	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.h	2017-05-30 21:01:59 UTC (rev 217571)
@@ -86,6 +86,8 @@
         void runJavaScriptAlert(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void ()>&& completionHandler) override;
         void runJavaScriptConfirm(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) override;
         void runJavaScriptPrompt(WebKit::WebPageProxy*, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (const WTF::String&)>&& completionHandler) override;
+        bool canRunBeforeUnloadConfirmPanel() const final;
+        void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) final;
         void exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, const WTF::String& databaseName, const WTF::String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentUsage, unsigned long long expectedUsage, Function<void (unsigned long long)>&& completionHandler) override;
         void reachedApplicationCacheOriginQuota(WebPageProxy*, const WebCore::SecurityOrigin&, uint64_t currentQuota, uint64_t totalBytesNeeded, Function<void (unsigned long long)>&& completionHandler) override;
 #if PLATFORM(MAC)
@@ -127,6 +129,7 @@
         bool webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler : 1;
         bool webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
         bool webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler : 1;
+        bool webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1;
 #if PLATFORM(MAC)
         bool webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler : 1;
 #endif

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/UIDelegate.mm	2017-05-30 21:01:59 UTC (rev 217571)
@@ -96,6 +96,7 @@
     m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
     m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
     m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
+    m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
 
 #if PLATFORM(MAC)
     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
@@ -313,6 +314,33 @@
     }).get()];
 }
 
+bool UIDelegate::UIClient::canRunBeforeUnloadConfirmPanel() const
+{
+    return m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler;
+}
+
+void UIDelegate::UIClient::runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String& message, WebKit::WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void (bool)>&& completionHandler)
+{
+    if (!m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler) {
+        completionHandler(false);
+        return;
+    }
+
+    auto delegate = m_uiDelegate.m_delegate.get();
+    if (!delegate) {
+        completionHandler(false);
+        return;
+    }
+
+    RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:));
+    [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:BlockPtr<void (BOOL)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](BOOL result) {
+        if (checker->completionHandlerHasBeenCalled())
+            return;
+        completionHandler(result);
+        checker->didCallCompletionHandler();
+    }).get()];
+}
+
 void UIDelegate::UIClient::exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin* securityOrigin, const WTF::String& databaseName, const WTF::String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentUsage, unsigned long long expectedUsage, Function<void (unsigned long long)>&& completionHandler)
 {
     if (!m_uiDelegate.m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler) {

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2017-05-30 21:01:59 UTC (rev 217571)
@@ -4091,7 +4091,7 @@
 }
 #endif
 
-void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply> reply)
+void WebPageProxy::runBeforeUnloadConfirmPanel(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply> reply)
 {
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
@@ -4099,7 +4099,7 @@
     // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
     m_process->responsivenessTimer().stop();
 
-    m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame, [reply](bool result) { reply->send(result); });
+    m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame, securityOrigin, [reply](bool result) { reply->send(result); });
 }
 
 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2017-05-30 21:01:59 UTC (rev 217571)
@@ -1297,7 +1297,7 @@
     void accessibilityScreenToRootView(const WebCore::IntPoint& screenPoint, WebCore::IntPoint& windowPoint);
     void rootViewToAccessibilityScreen(const WebCore::IntRect& viewRect, WebCore::IntRect& result);
 #endif
-    void runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply>);
+    void runBeforeUnloadConfirmPanel(uint64_t frameID, const WebCore::SecurityOriginData&, const String& message, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply>);
     void didChangeViewportProperties(const WebCore::ViewportAttributes&);
     void pageDidScroll();
     void runOpenPanel(uint64_t frameID, const WebCore::SecurityOriginData&, const WebCore::FileChooserSettings&);

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (217570 => 217571)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in	2017-05-30 21:01:59 UTC (rev 217571)
@@ -74,7 +74,7 @@
     RootViewToAccessibilityScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame)
 #endif
 
-    RunBeforeUnloadConfirmPanel(String message, uint64_t frameID) -> (bool shouldClose) Delayed
+    RunBeforeUnloadConfirmPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> (bool shouldClose) Delayed
     PageDidScroll()
     RunOpenPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebCore::FileChooserSettings parameters)
     PrintFrame(uint64_t frameID) -> ()

Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp (217570 => 217571)


--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp	2017-05-30 21:01:59 UTC (rev 217571)
@@ -367,7 +367,7 @@
 
     HangDetectionDisabler hangDetectionDisabler;
 
-    if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(message, webFrame->frameID()), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend))
+    if (!WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page.pageID(), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend))
         return false;
 
     return shouldClose;

Modified: trunk/Tools/ChangeLog (217570 => 217571)


--- trunk/Tools/ChangeLog	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Tools/ChangeLog	2017-05-30 21:01:59 UTC (rev 217571)
@@ -1,3 +1,33 @@
+2017-05-30  Daniel Bates  <[email protected]>
+
+        [WK2] Add runBeforeUnloadConfirmPanel WKUIDelegate SPI; support onbeforeunload confirm panel in MiniBrowser
+        https://bugs.webkit.org/show_bug.cgi?id=172603
+        <rdar://problem/32471306>
+
+        Reviewed by Brady Eidson.
+
+        Implement the -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: delegate
+        method in MiniBrowser to show a confirm panel as to whether to allow the unloading of the page when
+        unloading is initiated for a page that registered a onbeforeunload handler.
+
+        Modify TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm to test that the -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:
+        is called. Also fix style nit; pass YES instead of true to avoid implicit conversion from bool to BOOL
+        when invoking the completion handler in -_webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:.
+
+        Until we fix <https://bugs.webkit.org/show_bug.cgi?id=172614> the unit test in TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm
+        for -_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler: is only run on Mac
+        as we do not have the infrastructure to simulate a click/tap on iOS and a click/tap on the page that
+        registered an onbeforeunload handler is required to show a confirm panel when the page will be unloaded.
+
+        * MiniBrowser/mac/WK2BrowserWindowController.m:
+        (-[WK2BrowserWindowController _webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):
+        * TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm:
+        (sawDialog):
+        (-[ModalAlertsUIDelegate webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:]):
+        (-[ModalAlertsUIDelegate webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):
+        (-[ModalAlertsUIDelegate _webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:]):
+
 2017-05-30  Alex Christensen  <[email protected]>
 
         Update libwebrtc configuration

Modified: trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m (217570 => 217571)


--- trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m	2017-05-30 21:01:59 UTC (rev 217571)
@@ -515,6 +515,22 @@
     }];
 }
 
+- (void)_webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
+{
+    NSAlert *alert = [[NSAlert alloc] init];
+
+    alert.messageText = [NSString stringWithFormat:@"_javascript_ before unload dialog from %@.", [frame.request.URL absoluteString]];
+    alert.informativeText = message;
+
+    [alert addButtonWithTitle:@"Leave Page"];
+    [alert addButtonWithTitle:@"Stay On Page"];
+
+    [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
+        completionHandler(response == NSAlertFirstButtonReturn);
+        [alert release];
+    }];
+}
+
 - (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo
 {
     return WKDragDestinationActionAny;

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html (217570 => 217571)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2/modal-alerts-in-new-about-blank-window.html	2017-05-30 21:01:59 UTC (rev 217571)
@@ -7,6 +7,7 @@
 newWindow.alert("Testing alert");
 newWindow.confirm("Testing confirm");
 newWindow.prompt("Testing prompt", "Default text");
+newWindow._onbeforeunload_ = () => "Default text";
 
 </script>
 </head>

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm (217570 => 217571)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm	2017-05-30 20:56:41 UTC (rev 217570)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/ModalAlerts.mm	2017-05-30 21:01:59 UTC (rev 217571)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #include "config.h"
 
 #import "PlatformUtilities.h"
+#import "TestWKWebView.h"
 #import <WebKit/WKPreferences.h>
 #import <WebKit/WKUIDelegatePrivate.h>
 #import <WebKit/WKWebView.h>
@@ -37,15 +38,33 @@
 @class ModalAlertsUIDelegate;
 
 static bool isDone;
-static RetainPtr<WKWebView> openedWebView;
+static RetainPtr<TestWKWebView> openedWebView;
 static RetainPtr<ModalAlertsUIDelegate> sharedUIDelegate;
 
 static unsigned dialogsSeen;
+
+// FIXME: Remove this guard once we fix <https://bugs.webkit.org/show_bug.cgi?id=172614>.
+#if PLATFORM(MAC)
+static const unsigned dialogsExpected = 4;
+static const unsigned dialogsBeforeUnloadConfirmPanel = dialogsExpected - 1;
+#else
 static const unsigned dialogsExpected = 3;
+#endif
 
 static void sawDialog()
 {
-    if (++dialogsSeen == dialogsExpected)
+    ++dialogsSeen;
+
+    // FIXME: Remove this guard once we fix <https://bugs.webkit.org/show_bug.cgi?id=172614>.
+#if PLATFORM(MAC)
+    if (dialogsSeen == dialogsBeforeUnloadConfirmPanel) {
+        [openedWebView sendClicksAtPoint:NSMakePoint(5, 5) numberOfClicks:1];
+        [openedWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"data:text/html"]]];
+        return;
+    }
+#endif
+
+    if (dialogsSeen == dialogsExpected)
         isDone = true;
 }
 
@@ -56,7 +75,7 @@
 
 - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
 {
-    openedWebView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+    openedWebView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
     [openedWebView setUIDelegate:sharedUIDelegate.get()];
     return openedWebView.get();
 }
@@ -79,7 +98,7 @@
     EXPECT_STREQ([[[frame securityOrigin] host] UTF8String], "");
     EXPECT_EQ([[frame securityOrigin] port], 0);
 
-    completionHandler(true);
+    completionHandler(YES);
     sawDialog();
 }
 
@@ -94,6 +113,20 @@
     sawDialog();
 }
 
+// FIXME: Remove this guard once we fix <https://bugs.webkit.org/show_bug.cgi?id=172614>.
+#if PLATFORM(MAC)
+- (void)_webView:(WKWebView *)webView runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
+{
+    EXPECT_STREQ([[[[frame request] URL] absoluteString] UTF8String], "about:blank");
+    EXPECT_STREQ([[[frame securityOrigin] protocol] UTF8String], "file");
+    EXPECT_STREQ([[[frame securityOrigin] host] UTF8String], "");
+    EXPECT_EQ([[frame securityOrigin] port], 0);
+
+    completionHandler(NO);
+    sawDialog();
+}
+#endif
+
 @end
 
 TEST(WebKit2, ModalAlerts)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to