c12eda0d76c1dfc76874349b1815521c93cea87d
[WebKit-https.git] / Source / WebKit / UIProcess / API / gtk / WebKitWebViewGtk.cpp
1 /*
2  * Copyright (C) 2017 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 "WebKitWebView.h"
22
23 #include "WebKitAuthenticationDialog.h"
24 #include "WebKitScriptDialogPrivate.h"
25 #include "WebKitWebViewBasePrivate.h"
26 #include "WebKitWebViewPrivate.h"
27 #include <WebCore/GtkUtilities.h>
28 #include <glib/gi18n-lib.h>
29 #include <gtk/gtk.h>
30
31 gboolean webkitWebViewAuthenticate(WebKitWebView* webView, WebKitAuthenticationRequest* request)
32 {
33     CredentialStorageMode credentialStorageMode = webkit_authentication_request_can_save_credentials(request) ? AllowPersistentStorage : DisallowPersistentStorage;
34     webkitWebViewBaseAddAuthenticationDialog(WEBKIT_WEB_VIEW_BASE(webView), webkitAuthenticationDialogNew(request, credentialStorageMode));
35
36     return TRUE;
37 }
38
39 gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDialog* scriptDialog)
40 {
41     webkitScriptDialogRun(scriptDialog, webView);
42     return TRUE;
43 }
44
45 static void fileChooserDialogResponseCallback(GtkFileChooser* dialog, gint responseID, WebKitFileChooserRequest* request)
46 {
47     GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
48     if (responseID == GTK_RESPONSE_ACCEPT) {
49         GUniquePtr<GSList> filesList(gtk_file_chooser_get_filenames(dialog));
50         GRefPtr<GPtrArray> filesArray = adoptGRef(g_ptr_array_new());
51         for (GSList* file = filesList.get(); file; file = g_slist_next(file))
52             g_ptr_array_add(filesArray.get(), file->data);
53         g_ptr_array_add(filesArray.get(), 0);
54         webkit_file_chooser_request_select_files(adoptedRequest.get(), reinterpret_cast<const gchar* const*>(filesArray->pdata));
55     } else
56         webkit_file_chooser_request_cancel(adoptedRequest.get());
57
58 #if GTK_CHECK_VERSION(3, 20, 0)
59     g_object_unref(dialog);
60 #else
61     gtk_widget_destroy(GTK_WIDGET(dialog));
62 #endif
63 }
64
65 gboolean webkitWebViewRunFileChooser(WebKitWebView* webView, WebKitFileChooserRequest* request)
66 {
67     GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webView));
68     if (!WebCore::widgetIsOnscreenToplevelWindow(toplevel))
69         toplevel = 0;
70
71     gboolean allowsMultipleSelection = webkit_file_chooser_request_get_select_multiple(request);
72
73 #if GTK_CHECK_VERSION(3, 20, 0)
74     GtkFileChooserNative* dialog = gtk_file_chooser_native_new(allowsMultipleSelection ? _("Select Files") : _("Select File"),
75         toplevel ? GTK_WINDOW(toplevel) : nullptr, GTK_FILE_CHOOSER_ACTION_OPEN, nullptr, nullptr);
76     if (toplevel)
77         gtk_native_dialog_set_modal(GTK_NATIVE_DIALOG(dialog), TRUE);
78 #else
79     GtkWidget* dialog = gtk_file_chooser_dialog_new(allowsMultipleSelection ? _("Select Files") : _("Select File"),
80         toplevel ? GTK_WINDOW(toplevel) : nullptr,
81         GTK_FILE_CHOOSER_ACTION_OPEN,
82         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
83         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
84         nullptr);
85     if (toplevel)
86         gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
87 #endif
88
89     if (GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(request))
90         gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
91     gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), allowsMultipleSelection);
92
93     if (const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(request))
94         gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), selectedFiles[0]);
95
96     g_signal_connect(dialog, "response", G_CALLBACK(fileChooserDialogResponseCallback), g_object_ref(request));
97
98 #if GTK_CHECK_VERSION(3, 20, 0)
99     gtk_native_dialog_show(GTK_NATIVE_DIALOG(dialog));
100 #else
101     gtk_widget_show(dialog);
102 #endif
103
104     return TRUE;
105 }
106
107 /**
108  * webkit_web_view_new:
109  *
110  * Creates a new #WebKitWebView with the default #WebKitWebContext and
111  * no #WebKitUserContentManager associated with it.
112  * See also webkit_web_view_new_with_context(),
113  * webkit_web_view_new_with_user_content_manager(), and
114  * webkit_web_view_new_with_settings().
115  *
116  * Returns: The newly created #WebKitWebView widget
117  */
118 GtkWidget* webkit_web_view_new()
119 {
120     return webkit_web_view_new_with_context(webkit_web_context_get_default());
121 }
122
123 /**
124  * webkit_web_view_new_with_context:
125  * @context: the #WebKitWebContext to be used by the #WebKitWebView
126  *
127  * Creates a new #WebKitWebView with the given #WebKitWebContext and
128  * no #WebKitUserContentManager associated with it.
129  * See also webkit_web_view_new_with_user_content_manager() and
130  * webkit_web_view_new_with_settings().
131  *
132  * Returns: The newly created #WebKitWebView widget
133  */
134 GtkWidget* webkit_web_view_new_with_context(WebKitWebContext* context)
135 {
136     g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0);
137
138     return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW,
139         "is-ephemeral", webkit_web_context_is_ephemeral(context),
140         "web-context", context,
141         nullptr));
142 }
143
144 /**
145  * webkit_web_view_new_with_related_view: (constructor)
146  * @web_view: the related #WebKitWebView
147  *
148  * Creates a new #WebKitWebView sharing the same web process with @web_view.
149  * This method doesn't have any effect when %WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS
150  * process model is used, because a single web process is shared for all the web views in the
151  * same #WebKitWebContext. When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES process model,
152  * this method should always be used when creating the #WebKitWebView in the #WebKitWebView::create signal.
153  * You can also use this method to implement other process models based on %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES,
154  * like for example, sharing the same web process for all the views in the same security domain.
155  *
156  * The newly created #WebKitWebView will also have the same #WebKitUserContentManager
157  * and #WebKitSettings as @web_view.
158  *
159  * Returns: (transfer full): The newly created #WebKitWebView widget
160  *
161  * Since: 2.4
162  */
163 GtkWidget* webkit_web_view_new_with_related_view(WebKitWebView* webView)
164 {
165     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
166
167     return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW,
168         "user-content-manager", webkit_web_view_get_user_content_manager(webView),
169         "settings", webkit_web_view_get_settings(webView),
170         "related-view", webView,
171         nullptr));
172 }
173
174 /**
175  * webkit_web_view_new_with_settings:
176  * @settings: a #WebKitSettings
177  *
178  * Creates a new #WebKitWebView with the given #WebKitSettings.
179  * See also webkit_web_view_new_with_context(), and
180  * webkit_web_view_new_with_user_content_manager().
181  *
182  * Returns: The newly created #WebKitWebView widget
183  *
184  * Since: 2.6
185  */
186 GtkWidget* webkit_web_view_new_with_settings(WebKitSettings* settings)
187 {
188     g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), nullptr);
189     return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "settings", settings, nullptr));
190 }
191
192 /**
193  * webkit_web_view_new_with_user_content_manager:
194  * @user_content_manager: a #WebKitUserContentManager.
195  *
196  * Creates a new #WebKitWebView with the given #WebKitUserContentManager.
197  * The content loaded in the view may be affected by the content injected
198  * in the view by the user content manager.
199  *
200  * Returns: The newly created #WebKitWebView widget
201  *
202  * Since: 2.6
203  */
204 GtkWidget* webkit_web_view_new_with_user_content_manager(WebKitUserContentManager* userContentManager)
205 {
206     g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(userContentManager), nullptr);
207
208     return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "user-content-manager", userContentManager, nullptr));
209 }