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 (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 (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 | |
231 | |