Optimizing loads when creating new pages
[WebKit-https.git] / Source / WebKit / UIProcess / API / glib / WebKitUIClient.cpp
1 /*
2  * Copyright (C) 2011, 2012 Igalia S.L.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "WebKitUIClient.h"
22
23 #include "APIUIClient.h"
24 #include "DrawingAreaProxy.h"
25 #include "WebKitDeviceInfoPermissionRequestPrivate.h"
26 #include "WebKitFileChooserRequestPrivate.h"
27 #include "WebKitGeolocationPermissionRequestPrivate.h"
28 #include "WebKitNavigationActionPrivate.h"
29 #include "WebKitNotificationPermissionRequestPrivate.h"
30 #include "WebKitURIRequestPrivate.h"
31 #include "WebKitUserMediaPermissionRequestPrivate.h"
32 #include "WebKitWebViewPrivate.h"
33 #include "WebKitWindowPropertiesPrivate.h"
34 #include "WebPageProxy.h"
35 #include "WebProcessProxy.h"
36 #include "WebsiteDataStore.h"
37 #include <wtf/glib/GRefPtr.h>
38
39 #if PLATFORM(GTK)
40 #include <WebCore/GtkUtilities.h>
41 #endif
42
43 using namespace WebKit;
44
45 class UIClient : public API::UIClient {
46 public:
47     explicit UIClient(WebKitWebView* webView)
48         : m_webView(webView)
49     {
50     }
51
52 private:
53     void createNewPage(WebPageProxy& page, WebCore::WindowFeatures&& windowFeatures, Ref<API::NavigationAction>&& apiNavigationAction, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler) final
54     {
55         WebKitNavigationAction navigationAction(WTFMove(apiNavigationAction));
56         completionHandler(webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction));
57     }
58
59     void showPage(WebPageProxy*) final
60     {
61         webkitWebViewReadyToShowPage(m_webView);
62     }
63
64     void close(WebPageProxy*) final
65     {
66         webkitWebViewClosePage(m_webView);
67     }
68
69     void runJavaScriptAlert(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void()>&& completionHandler) final
70     {
71         webkitWebViewRunJavaScriptAlert(m_webView, message.utf8(), WTFMove(completionHandler));
72     }
73
74     void runJavaScriptConfirm(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
75     {
76         webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
77     }
78
79     void runJavaScriptPrompt(WebPageProxy*, const String& message, const String& defaultValue, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(const String&)>&& completionHandler) final
80     {
81         webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
82     }
83
84     bool canRunBeforeUnloadConfirmPanel() const final { return true; }
85
86     void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
87     {
88         webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
89     }
90
91     void mouseDidMoveOverElement(WebPageProxy&, const WebHitTestResultData& data, OptionSet<WebEvent::Modifier> modifiers, API::Object*) final
92     {
93         webkitWebViewMouseTargetChanged(m_webView, data, modifiers);
94     }
95
96     void toolbarsAreVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
97     {
98         completionHandler(webkit_window_properties_get_toolbar_visible(webkit_web_view_get_window_properties(m_webView)));
99     }
100
101     void setToolbarsAreVisible(WebPageProxy&, bool visible) final
102     {
103         webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
104     }
105
106     void menuBarIsVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
107     {
108         completionHandler(webkit_window_properties_get_menubar_visible(webkit_web_view_get_window_properties(m_webView)));
109     }
110
111     void setMenuBarIsVisible(WebPageProxy&, bool visible) final
112     {
113         webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
114     }
115
116     void statusBarIsVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
117     {
118         completionHandler(webkit_window_properties_get_statusbar_visible(webkit_web_view_get_window_properties(m_webView)));
119     }
120
121     void setStatusBarIsVisible(WebPageProxy&, bool visible) final
122     {
123         webkitWindowPropertiesSetStatusbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
124     }
125
126     void setIsResizable(WebPageProxy&, bool resizable) final
127     {
128         webkitWindowPropertiesSetResizable(webkit_web_view_get_window_properties(m_webView), resizable);
129     }
130
131     void setWindowFrame(WebPageProxy&, const WebCore::FloatRect& frame) final
132     {
133 #if PLATFORM(GTK)
134         GdkRectangle geometry = WebCore::IntRect(frame);
135         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
136         if (webkit_web_view_is_controlled_by_automation(m_webView) && WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) {
137             if (geometry.x >= 0 && geometry.y >= 0)
138                 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
139             if (geometry.width > 0 && geometry.height > 0)
140                 gtk_window_resize(GTK_WINDOW(window), geometry.width, geometry.height);
141         } else
142             webkitWindowPropertiesSetGeometry(webkit_web_view_get_window_properties(m_webView), &geometry);
143 #endif
144     }
145
146     void windowFrame(WebPageProxy&, Function<void(WebCore::FloatRect)>&& completionHandler) final
147     {
148 #if PLATFORM(GTK)
149         GdkRectangle geometry = { 0, 0, 0, 0 };
150         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
151         if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) {
152             gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y);
153             gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height);
154         }
155         completionHandler(WebCore::FloatRect(geometry));
156 #elif PLATFORM(WPE)
157         // FIXME: I guess this is actually the view size in WPE. We need more refactoring here.
158         WebCore::FloatRect rect;
159         auto& page = webkitWebViewGetPage(m_webView);
160         if (page.drawingArea())
161             rect.setSize(page.drawingArea()->size());
162         completionHandler(WTFMove(rect));
163 #endif
164     }
165
166     void exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, const String&, const String&, unsigned long long /*currentQuota*/, unsigned long long /*currentOriginUsage*/, unsigned long long /*currentDatabaseUsage*/, unsigned long long /*expectedUsage*/, Function<void(unsigned long long)>&& completionHandler) final
167     {
168         static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
169         // FIXME: Provide API for this.
170         completionHandler(defaultQuota);
171     }
172
173     bool runOpenPanel(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) final
174     {
175         GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener));
176         webkitWebViewRunFileChooserRequest(m_webView, request.get());
177         return true;
178     }
179
180     void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin&, Function<void(bool)>& completionHandler) final
181     {
182         GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(GeolocationPermissionRequest::create(std::exchange(completionHandler, nullptr)).ptr()));
183         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get()));
184     }
185
186     void decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) final
187     {
188         GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, userMediaDocumentOrigin, topLevelDocumentOrigin));
189         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(userMediaPermissionRequest.get()));
190     }
191
192     void checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& permissionRequest) override
193     {
194         auto deviceInfoPermissionRequest = adoptGRef(webkitDeviceInfoPermissionRequestCreate(permissionRequest, &page.websiteDataStore().deviceIdHashSaltStorage()));
195         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(deviceInfoPermissionRequest.get()));
196     }
197
198     void decidePolicyForNotificationPermissionRequest(WebPageProxy&, API::SecurityOrigin&, Function<void(bool)>&& completionHandler) final
199     {
200         GRefPtr<WebKitNotificationPermissionRequest> notificationPermissionRequest = adoptGRef(webkitNotificationPermissionRequestCreate(NotificationPermissionRequest::create(WTFMove(completionHandler)).ptr()));
201         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(notificationPermissionRequest.get()));
202     }
203
204 #if PLATFORM(GTK)
205     void printFrame(WebPageProxy&, WebFrameProxy& frame) final
206     {
207         webkitWebViewPrintFrame(m_webView, &frame);
208     }
209 #endif
210
211     bool canRunModal() const final { return true; }
212
213     void runModal(WebPageProxy&) final
214     {
215         webkitWebViewRunAsModal(m_webView);
216     }
217
218     void isPlayingMediaDidChange(WebPageProxy&) final
219     {
220         webkitWebViewIsPlayingAudioChanged(m_webView);
221     }
222
223     WebKitWebView* m_webView;
224 };
225
226 void attachUIClientToView(WebKitWebView* webView)
227 {
228     webkitWebViewGetPage(webView).setUIClient(std::make_unique<UIClient>(webView));
229 }
230