Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebKit / UIProcess / API / glib / WebKitWebView.cpp
1 /*
2  * Copyright (C) 2011 Igalia S.L.
3  * Portions Copyright (c) 2011 Motorola Mobility, Inc.  All rights reserved.
4  * Copyright (C) 2014 Collabora Ltd.
5  * Copyright (C) 2017 Igalia S.L.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24 #include "WebKitWebView.h"
25
26 #include "APIData.h"
27 #include "APINavigation.h"
28 #include "APISerializedScriptValue.h"
29 #include "DataReference.h"
30 #include "ImageOptions.h"
31 #include "WebCertificateInfo.h"
32 #include "WebContextMenuItem.h"
33 #include "WebContextMenuItemData.h"
34 #include "WebKitAuthenticationRequestPrivate.h"
35 #include "WebKitBackForwardListPrivate.h"
36 #include "WebKitContextMenuClient.h"
37 #include "WebKitContextMenuItemPrivate.h"
38 #include "WebKitContextMenuPrivate.h"
39 #include "WebKitDownloadPrivate.h"
40 #include "WebKitEditingCommands.h"
41 #include "WebKitEditorStatePrivate.h"
42 #include "WebKitEnumTypes.h"
43 #include "WebKitError.h"
44 #include "WebKitFaviconDatabasePrivate.h"
45 #include "WebKitFormClient.h"
46 #include "WebKitHitTestResultPrivate.h"
47 #include "WebKitIconLoadingClient.h"
48 #include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h"
49 #include "WebKitJavascriptResultPrivate.h"
50 #include "WebKitNavigationClient.h"
51 #include "WebKitNotificationPrivate.h"
52 #include "WebKitPrivate.h"
53 #include "WebKitResponsePolicyDecision.h"
54 #include "WebKitScriptDialogPrivate.h"
55 #include "WebKitSettingsPrivate.h"
56 #include "WebKitUIClient.h"
57 #include "WebKitURIRequestPrivate.h"
58 #include "WebKitURIResponsePrivate.h"
59 #include "WebKitWebContextPrivate.h"
60 #include "WebKitWebResourcePrivate.h"
61 #include "WebKitWebViewPrivate.h"
62 #include "WebKitWebViewSessionStatePrivate.h"
63 #include "WebKitWebsiteDataManagerPrivate.h"
64 #include "WebKitWindowPropertiesPrivate.h"
65 #include <JavaScriptCore/APICast.h>
66 #include <JavaScriptCore/JSRetainPtr.h>
67 #include <jsc/JSCContextPrivate.h>
68 #include <WebCore/CertificateInfo.h>
69 #include <WebCore/JSDOMExceptionHandling.h>
70 #include <WebCore/RefPtrCairo.h>
71 #include <glib/gi18n-lib.h>
72 #include <wtf/URL.h>
73 #include <wtf/glib/GRefPtr.h>
74 #include <wtf/glib/GUniquePtrSoup.h>
75 #include <wtf/glib/WTFGType.h>
76 #include <wtf/text/CString.h>
77 #include <wtf/text/StringBuilder.h>
78
79 #if PLATFORM(GTK)
80 #include "WebKitPrintOperationPrivate.h"
81 #include "WebKitWebInspectorPrivate.h"
82 #include "WebKitWebViewBasePrivate.h"
83 #include <WebCore/GUniquePtrGtk.h>
84 #endif
85
86 #if PLATFORM(WPE)
87 #include "APIViewClient.h"
88 #include "WPEView.h"
89 #include "WebKitWebViewBackendPrivate.h"
90 #endif
91
92 #if USE(LIBNOTIFY)
93 #include <libnotify/notify.h>
94 #endif
95
96 using namespace WebKit;
97 using namespace WebCore;
98
99 /**
100  * SECTION: WebKitWebView
101  * @Short_description: The central class of the WebKit2GTK+ API
102  * @Title: WebKitWebView
103  *
104  * #WebKitWebView is the central class of the WebKit2GTK+ API. It is
105  * responsible for managing the drawing of the content and forwarding
106  * of events. You can load any URI into the #WebKitWebView or a data
107  * string. With #WebKitSettings you can control various aspects of the
108  * rendering and loading of the content.
109  *
110  * Note that #WebKitWebView is scrollable by itself, so you don't need
111  * to embed it in a #GtkScrolledWindow.
112  */
113
114 enum {
115     LOAD_CHANGED,
116     LOAD_FAILED,
117     LOAD_FAILED_WITH_TLS_ERRORS,
118
119     CREATE,
120     READY_TO_SHOW,
121     RUN_AS_MODAL,
122     CLOSE,
123
124     SCRIPT_DIALOG,
125
126     DECIDE_POLICY,
127     PERMISSION_REQUEST,
128
129     MOUSE_TARGET_CHANGED,
130
131 #if PLATFORM(GTK)
132     PRINT,
133 #endif
134
135     RESOURCE_LOAD_STARTED,
136
137     ENTER_FULLSCREEN,
138     LEAVE_FULLSCREEN,
139
140     RUN_FILE_CHOOSER,
141
142     CONTEXT_MENU,
143     CONTEXT_MENU_DISMISSED,
144
145     SUBMIT_FORM,
146
147     INSECURE_CONTENT_DETECTED,
148
149 #if PLATFORM(GTK)
150     WEB_PROCESS_CRASHED,
151 #endif
152     WEB_PROCESS_TERMINATED,
153
154     AUTHENTICATE,
155
156     SHOW_NOTIFICATION,
157
158 #if PLATFORM(GTK)
159     RUN_COLOR_CHOOSER,
160
161     SHOW_OPTION_MENU,
162 #endif
163
164     LAST_SIGNAL
165 };
166
167 enum {
168     PROP_0,
169
170 #if PLATFORM(WPE)
171     PROP_BACKEND,
172 #endif
173
174     PROP_WEB_CONTEXT,
175     PROP_RELATED_VIEW,
176     PROP_SETTINGS,
177     PROP_USER_CONTENT_MANAGER,
178     PROP_TITLE,
179     PROP_ESTIMATED_LOAD_PROGRESS,
180
181 #if PLATFORM(GTK)
182     PROP_FAVICON,
183 #endif
184
185     PROP_URI,
186     PROP_ZOOM_LEVEL,
187     PROP_IS_LOADING,
188     PROP_IS_PLAYING_AUDIO,
189     PROP_IS_EPHEMERAL,
190     PROP_IS_CONTROLLED_BY_AUTOMATION,
191     PROP_EDITABLE
192 };
193
194 typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap;
195 typedef HashMap<uint64_t, GRefPtr<GTask> > SnapshotResultsMap;
196
197 class PageLoadStateObserver;
198
199 struct _WebKitWebViewPrivate {
200     ~_WebKitWebViewPrivate()
201     {
202         // For modal dialogs, make sure the main loop is stopped when finalizing the webView.
203         if (modalLoop && g_main_loop_is_running(modalLoop.get()))
204             g_main_loop_quit(modalLoop.get());
205     }
206
207 #if PLATFORM(WPE)
208     GRefPtr<WebKitWebViewBackend> backend;
209     std::unique_ptr<WKWPE::View> view;
210 #endif
211
212     WebKitWebView* relatedView;
213     CString title;
214     CString customTextEncoding;
215     CString activeURI;
216     bool isLoading;
217     bool isEphemeral;
218     bool isControlledByAutomation;
219
220     std::unique_ptr<PageLoadStateObserver> loadObserver;
221
222     GRefPtr<WebKitBackForwardList> backForwardList;
223     GRefPtr<WebKitSettings> settings;
224     GRefPtr<WebKitUserContentManager> userContentManager;
225     GRefPtr<WebKitWebContext> context;
226     GRefPtr<WebKitWindowProperties> windowProperties;
227     GRefPtr<WebKitEditorState> editorState;
228
229     GRefPtr<GMainLoop> modalLoop;
230
231     GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult;
232     WebEvent::Modifiers mouseTargetModifiers;
233
234     GRefPtr<WebKitFindController> findController;
235
236     GRefPtr<WebKitWebResource> mainResource;
237     LoadingResourcesMap loadingResourcesMap;
238
239     WebKitScriptDialog* currentScriptDialog;
240
241 #if PLATFORM(GTK)
242     GRefPtr<JSCContext> jsContext;
243
244     GRefPtr<WebKitWebInspector> inspector;
245
246     RefPtr<cairo_surface_t> favicon;
247     GRefPtr<GCancellable> faviconCancellable;
248
249     CString faviconURI;
250     unsigned long faviconChangedHandlerID;
251
252     SnapshotResultsMap snapshotResultsMap;
253 #endif
254
255     GRefPtr<WebKitAuthenticationRequest> authenticationRequest;
256
257     GRefPtr<WebKitWebsiteDataManager> websiteDataManager;
258 };
259
260 static guint signals[LAST_SIGNAL] = { 0, };
261
262 #if PLATFORM(GTK)
263 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, WEBKIT_TYPE_WEB_VIEW_BASE)
264 #elif PLATFORM(WPE)
265 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, G_TYPE_OBJECT)
266 #endif
267
268 static inline WebPageProxy& getPage(WebKitWebView* webView)
269 {
270 #if PLATFORM(GTK)
271     auto* page = webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView));
272     ASSERT(page);
273     return *page;
274 #elif PLATFORM(WPE)
275     ASSERT(webView->priv->view);
276     return webView->priv->view->page();
277 #endif
278 }
279
280 static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading)
281 {
282     if (webView->priv->isLoading == isLoading)
283         return;
284
285     webView->priv->isLoading = isLoading;
286     g_object_notify(G_OBJECT(webView), "is-loading");
287 }
288
289 void webkitWebViewIsPlayingAudioChanged(WebKitWebView* webView)
290 {
291     g_object_notify(G_OBJECT(webView), "is-playing-audio");
292 }
293
294 class PageLoadStateObserver final : public PageLoadState::Observer {
295 public:
296     PageLoadStateObserver(WebKitWebView* webView)
297         : m_webView(webView)
298     {
299     }
300
301 private:
302     void willChangeIsLoading() override
303     {
304         g_object_freeze_notify(G_OBJECT(m_webView));
305     }
306     void didChangeIsLoading() override
307     {
308         webkitWebViewSetIsLoading(m_webView, getPage(m_webView).pageLoadState().isLoading());
309         g_object_thaw_notify(G_OBJECT(m_webView));
310     }
311
312     void willChangeTitle() override
313     {
314         g_object_freeze_notify(G_OBJECT(m_webView));
315     }
316     void didChangeTitle() override
317     {
318         m_webView->priv->title = getPage(m_webView).pageLoadState().title().utf8();
319         g_object_notify(G_OBJECT(m_webView), "title");
320         g_object_thaw_notify(G_OBJECT(m_webView));
321     }
322
323     void willChangeActiveURL() override
324     {
325         g_object_freeze_notify(G_OBJECT(m_webView));
326     }
327     void didChangeActiveURL() override
328     {
329         m_webView->priv->activeURI = getPage(m_webView).pageLoadState().activeURL().utf8();
330         g_object_notify(G_OBJECT(m_webView), "uri");
331         g_object_thaw_notify(G_OBJECT(m_webView));
332     }
333
334     void willChangeHasOnlySecureContent() override { }
335     void didChangeHasOnlySecureContent() override { }
336
337     void willChangeEstimatedProgress() override
338     {
339         g_object_freeze_notify(G_OBJECT(m_webView));
340     }
341     void didChangeEstimatedProgress() override
342     {
343         g_object_notify(G_OBJECT(m_webView), "estimated-load-progress");
344         g_object_thaw_notify(G_OBJECT(m_webView));
345     }
346
347     void willChangeCanGoBack() override { }
348     void didChangeCanGoBack() override { }
349     void willChangeCanGoForward() override { }
350     void didChangeCanGoForward() override { }
351     void willChangeNetworkRequestsInProgress() override { }
352     void didChangeNetworkRequestsInProgress() override { }
353     void willChangeCertificateInfo() override { }
354     void didChangeCertificateInfo() override { }
355     void willChangeWebProcessIsResponsive() override { }
356     void didChangeWebProcessIsResponsive() override { }
357
358     WebKitWebView* m_webView;
359 };
360
361 #if PLATFORM(WPE)
362 class WebViewClient final : public API::ViewClient {
363 public:
364     explicit WebViewClient(WebKitWebView* webView)
365         : m_webView(webView)
366     {
367     }
368
369 private:
370     void handleDownloadRequest(WKWPE::View&, DownloadProxy& downloadProxy) override
371     {
372         webkitWebViewHandleDownloadRequest(m_webView, &downloadProxy);
373     }
374
375     WebKitWebView* m_webView;
376 };
377 #endif
378
379 static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
380 {
381     if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)
382         || g_error_matches(error, WEBKIT_POLICY_ERROR, WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE)
383         || g_error_matches(error, WEBKIT_PLUGIN_ERROR, WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD))
384         return FALSE;
385
386     GUniquePtr<char> htmlString(g_strdup_printf("<html><body>%s</body></html>", error->message));
387     webkit_web_view_load_alternate_html(webView, htmlString.get(), failingURI, 0);
388
389     return TRUE;
390 }
391
392 #if PLATFORM(GTK)
393 static GtkWidget* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
394 {
395     return nullptr;
396 }
397 #else
398 static WebKitWebView* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
399 {
400     return nullptr;
401 }
402 #endif
403
404 static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType)
405 {
406     if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) {
407         webkit_policy_decision_use(decision);
408         return TRUE;
409     }
410
411     WebKitURIResponse* response = webkit_response_policy_decision_get_response(WEBKIT_RESPONSE_POLICY_DECISION(decision));
412     const ResourceResponse& resourceResponse = webkitURIResponseGetResourceResponse(response);
413     if (resourceResponse.isAttachment()) {
414         webkit_policy_decision_download(decision);
415         return TRUE;
416     }
417
418     if (webkit_response_policy_decision_is_mime_type_supported(WEBKIT_RESPONSE_POLICY_DECISION(decision)))
419         webkit_policy_decision_use(decision);
420     else
421         webkit_policy_decision_ignore(decision);
422
423     return TRUE;
424 }
425
426 static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
427 {
428     webkit_permission_request_deny(request);
429     return TRUE;
430 }
431
432 static void allowModalDialogsChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
433 {
434     getPage(webView).setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
435 }
436
437 static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
438 {
439     auto& page = getPage(webView);
440     gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings);
441     gdouble pageZoomLevel = zoomTextOnly ? 1 : page.textZoomFactor();
442     gdouble textZoomLevel = zoomTextOnly ? page.pageZoomFactor() : 1;
443     page.setPageAndTextZoomFactors(pageZoomLevel, textZoomLevel);
444 }
445
446 static void userAgentChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
447 {
448     getPage(webView).setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
449 }
450
451 #if PLATFORM(GTK)
452 static void webkitWebViewUpdateFavicon(WebKitWebView* webView, cairo_surface_t* favicon)
453 {
454     WebKitWebViewPrivate* priv = webView->priv;
455     if (priv->favicon.get() == favicon)
456         return;
457
458     priv->favicon = favicon;
459     g_object_notify(G_OBJECT(webView), "favicon");
460 }
461
462 static void webkitWebViewCancelFaviconRequest(WebKitWebView* webView)
463 {
464     if (!webView->priv->faviconCancellable)
465         return;
466
467     g_cancellable_cancel(webView->priv->faviconCancellable.get());
468     webView->priv->faviconCancellable = 0;
469 }
470
471 static void gotFaviconCallback(GObject* object, GAsyncResult* result, gpointer userData)
472 {
473     GUniqueOutPtr<GError> error;
474     RefPtr<cairo_surface_t> favicon = adoptRef(webkit_favicon_database_get_favicon_finish(WEBKIT_FAVICON_DATABASE(object), result, &error.outPtr()));
475     if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
476         return;
477
478     WebKitWebView* webView = WEBKIT_WEB_VIEW(userData);
479     webkitWebViewUpdateFavicon(webView, favicon.get());
480     webView->priv->faviconCancellable = 0;
481 }
482
483 static void webkitWebViewRequestFavicon(WebKitWebView* webView)
484 {
485     webkitWebViewCancelFaviconRequest(webView);
486
487     WebKitWebViewPrivate* priv = webView->priv;
488     priv->faviconCancellable = adoptGRef(g_cancellable_new());
489     WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
490     webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), gotFaviconCallback, webView);
491 }
492
493 static void webkitWebViewUpdateFaviconURI(WebKitWebView* webView, const char* faviconURI)
494 {
495     if (webView->priv->faviconURI == faviconURI)
496         return;
497
498     webView->priv->faviconURI = faviconURI;
499     webkitWebViewRequestFavicon(webView);
500 }
501
502 static void faviconChangedCallback(WebKitFaviconDatabase*, const char* pageURI, const char* faviconURI, WebKitWebView* webView)
503 {
504     if (webView->priv->activeURI != pageURI)
505         return;
506
507     webkitWebViewUpdateFaviconURI(webView, faviconURI);
508 }
509 #endif
510
511 static bool webkitWebViewIsConstructed(WebKitWebView* webView)
512 {
513     // The loadObserver is set in webkitWebViewConstructed, right after the
514     // WebPageProxy is created, so we use it to check if the view has been
515     // constructed instead of adding a boolean member only for that.
516     return !!webView->priv->loadObserver;
517 }
518
519 static void webkitWebViewUpdateSettings(WebKitWebView* webView)
520 {
521     // The "settings" property is set on construction, and in that
522     // case webkit_web_view_set_settings() will be called *before* the
523     // WebPageProxy has been created so we should do an early return.
524     if (!webkitWebViewIsConstructed(webView))
525         return;
526
527     auto& page = getPage(webView);
528     WebKitSettings* settings = webView->priv->settings.get();
529     page.setPreferences(*webkitSettingsGetPreferences(settings));
530     page.setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
531     page.setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
532
533     g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView);
534     g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
535     g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView);
536 }
537
538 static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView)
539 {
540     if (!webkitWebViewIsConstructed(webView))
541         return;
542
543     WebKitSettings* settings = webView->priv->settings.get();
544     g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(allowModalDialogsChanged), webView);
545     g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView);
546     g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(userAgentChanged), webView);
547 }
548
549 #if PLATFORM(GTK)
550 static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView)
551 {
552     WebKitWebViewPrivate* priv = webView->priv;
553     if (priv->faviconChangedHandlerID)
554         return;
555
556     WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
557     priv->faviconChangedHandlerID = g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), webView);
558 }
559
560 static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* webView)
561 {
562     WebKitWebViewPrivate* priv = webView->priv;
563     if (priv->faviconChangedHandlerID)
564         g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context.get()), priv->faviconChangedHandlerID);
565     priv->faviconChangedHandlerID = 0;
566 }
567 #endif
568
569 #if USE(LIBNOTIFY)
570 static const char* gNotifyNotificationID = "wk-notify-notification";
571
572 static void notifyNotificationClosed(NotifyNotification*, WebKitNotification* webNotification)
573 {
574     g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
575     webkit_notification_close(webNotification);
576 }
577
578 static void notifyNotificationClicked(NotifyNotification*, char*, WebKitNotification* webNotification)
579 {
580     webkit_notification_clicked(webNotification);
581 }
582
583 static void webNotificationClosed(WebKitNotification* webNotification)
584 {
585     NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
586     if (!notification)
587         return;
588
589     notify_notification_close(notification, nullptr);
590     g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
591 }
592 #endif // USE(LIBNOTIFY)
593
594 static gboolean webkitWebViewShowNotification(WebKitWebView*, WebKitNotification* webNotification)
595 {
596 #if USE(LIBNOTIFY)
597     if (!notify_is_initted())
598         notify_init(g_get_prgname());
599
600     NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
601     if (!notification) {
602         notification = notify_notification_new(webkit_notification_get_title(webNotification),
603             webkit_notification_get_body(webNotification), nullptr);
604
605         notify_notification_add_action(notification, "default", _("Acknowledge"), NOTIFY_ACTION_CALLBACK(notifyNotificationClicked), webNotification, nullptr);
606
607         g_signal_connect_object(notification, "closed", G_CALLBACK(notifyNotificationClosed), webNotification, static_cast<GConnectFlags>(0));
608         g_signal_connect(webNotification, "closed", G_CALLBACK(webNotificationClosed), nullptr);
609         g_object_set_data_full(G_OBJECT(webNotification), gNotifyNotificationID, notification, static_cast<GDestroyNotify>(g_object_unref));
610     } else {
611         notify_notification_update(notification, webkit_notification_get_title(webNotification),
612             webkit_notification_get_body(webNotification), nullptr);
613     }
614
615     notify_notification_show(notification, nullptr);
616     return TRUE;
617 #else
618     UNUSED_PARAM(webNotification);
619     return FALSE;
620 #endif
621 }
622
623 static void webkitWebViewConstructed(GObject* object)
624 {
625     G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object);
626
627     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
628     WebKitWebViewPrivate* priv = webView->priv;
629     if (priv->relatedView) {
630         priv->context = webkit_web_view_get_context(priv->relatedView);
631         priv->isEphemeral = webkit_web_view_is_ephemeral(priv->relatedView);
632         priv->isControlledByAutomation = webkit_web_view_is_controlled_by_automation(priv->relatedView);
633     } else if (!priv->context)
634         priv->context = webkit_web_context_get_default();
635     else if (!priv->isEphemeral)
636         priv->isEphemeral = webkit_web_context_is_ephemeral(priv->context.get());
637
638     if (!priv->settings)
639         priv->settings = adoptGRef(webkit_settings_new());
640
641     if (!priv->userContentManager)
642         priv->userContentManager = adoptGRef(webkit_user_content_manager_new());
643
644     if (priv->isEphemeral && !webkit_web_context_is_ephemeral(priv->context.get())) {
645         priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new_ephemeral());
646         webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), webkitWebContextGetProcessPool(priv->context.get()));
647     }
648
649     webkitWebContextCreatePageForWebView(priv->context.get(), webView, priv->userContentManager.get(), priv->relatedView);
650
651     priv->loadObserver = std::make_unique<PageLoadStateObserver>(webView);
652     getPage(webView).pageLoadState().addObserver(*priv->loadObserver);
653
654     // The related view is only valid during the construction.
655     priv->relatedView = nullptr;
656
657     attachNavigationClientToView(webView);
658     attachUIClientToView(webView);
659     attachContextMenuClientToView(webView);
660     attachFormClientToView(webView);
661
662 #if PLATFORM(GTK)
663     attachIconLoadingClientToView(webView);
664 #endif
665
666 #if PLATFORM(WPE)
667     priv->view->setClient(std::make_unique<WebViewClient>(webView));
668 #endif
669
670     // This needs to be after attachUIClientToView() because WebPageProxy::setUIClient() calls setCanRunModal() with true.
671     // See https://bugs.webkit.org/show_bug.cgi?id=135412.
672     webkitWebViewUpdateSettings(webView);
673
674     priv->backForwardList = adoptGRef(webkitBackForwardListCreate(&getPage(webView).backForwardList()));
675     priv->windowProperties = adoptGRef(webkitWindowPropertiesCreate());
676 }
677
678 static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
679 {
680     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
681
682     switch (propId) {
683 #if PLATFORM(WPE)
684     case PROP_BACKEND: {
685         gpointer backend = g_value_get_boxed(value);
686         webView->priv->backend = backend ? adoptGRef(static_cast<WebKitWebViewBackend*>(backend)) : nullptr;
687         break;
688     }
689 #endif
690     case PROP_WEB_CONTEXT: {
691         gpointer webContext = g_value_get_object(value);
692         webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : nullptr;
693         break;
694     }
695     case PROP_RELATED_VIEW: {
696         gpointer relatedView = g_value_get_object(value);
697         webView->priv->relatedView = relatedView ? WEBKIT_WEB_VIEW(relatedView) : nullptr;
698         break;
699     }
700     case PROP_SETTINGS: {
701         if (gpointer settings = g_value_get_object(value))
702             webkit_web_view_set_settings(webView, WEBKIT_SETTINGS(settings));
703         break;
704     }
705     case PROP_USER_CONTENT_MANAGER: {
706         gpointer userContentManager = g_value_get_object(value);
707         webView->priv->userContentManager = userContentManager ? WEBKIT_USER_CONTENT_MANAGER(userContentManager) : nullptr;
708         break;
709     }
710     case PROP_ZOOM_LEVEL:
711         webkit_web_view_set_zoom_level(webView, g_value_get_double(value));
712         break;
713     case PROP_IS_EPHEMERAL:
714         webView->priv->isEphemeral = g_value_get_boolean(value);
715         break;
716     case PROP_IS_CONTROLLED_BY_AUTOMATION:
717         webView->priv->isControlledByAutomation = g_value_get_boolean(value);
718         break;
719     case PROP_EDITABLE:
720         webkit_web_view_set_editable(webView, g_value_get_boolean(value));
721         break;
722     default:
723         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
724     }
725 }
726
727 static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
728 {
729     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
730
731     switch (propId) {
732 #if PLATFORM(WPE)
733     case PROP_BACKEND:
734         g_value_set_static_boxed(value, webView->priv->backend.get());
735         break;
736 #endif
737     case PROP_WEB_CONTEXT:
738         g_value_set_object(value, webView->priv->context.get());
739         break;
740     case PROP_SETTINGS:
741         g_value_set_object(value, webkit_web_view_get_settings(webView));
742         break;
743     case PROP_USER_CONTENT_MANAGER:
744         g_value_set_object(value, webkit_web_view_get_user_content_manager(webView));
745         break;
746     case PROP_TITLE:
747         g_value_set_string(value, webView->priv->title.data());
748         break;
749     case PROP_ESTIMATED_LOAD_PROGRESS:
750         g_value_set_double(value, webkit_web_view_get_estimated_load_progress(webView));
751         break;
752 #if PLATFORM(GTK)
753     case PROP_FAVICON:
754         g_value_set_pointer(value, webkit_web_view_get_favicon(webView));
755         break;
756 #endif
757     case PROP_URI:
758         g_value_set_string(value, webkit_web_view_get_uri(webView));
759         break;
760     case PROP_ZOOM_LEVEL:
761         g_value_set_double(value, webkit_web_view_get_zoom_level(webView));
762         break;
763     case PROP_IS_LOADING:
764         g_value_set_boolean(value, webkit_web_view_is_loading(webView));
765         break;
766     case PROP_IS_PLAYING_AUDIO:
767         g_value_set_boolean(value, webkit_web_view_is_playing_audio(webView));
768         break;
769     case PROP_IS_EPHEMERAL:
770         g_value_set_boolean(value, webkit_web_view_is_ephemeral(webView));
771         break;
772     case PROP_IS_CONTROLLED_BY_AUTOMATION:
773         g_value_set_boolean(value, webkit_web_view_is_controlled_by_automation(webView));
774         break;
775     case PROP_EDITABLE:
776         g_value_set_boolean(value, webkit_web_view_is_editable(webView));
777         break;
778     default:
779         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
780     }
781 }
782
783 static void webkitWebViewDispose(GObject* object)
784 {
785     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
786
787 #if PLATFORM(GTK)
788     webkitWebViewCancelFaviconRequest(webView);
789     webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView);
790 #endif
791
792     webkitWebViewDisconnectSettingsSignalHandlers(webView);
793
794     if (webView->priv->loadObserver) {
795         getPage(webView).pageLoadState().removeObserver(*webView->priv->loadObserver);
796         webView->priv->loadObserver.reset();
797
798         // We notify the context here to ensure it's called only once. Ideally we should
799         // call this in finalize, not dispose, but finalize is used internally and we don't
800         // have access to the instance pointer from the private struct destructor.
801         webkitWebContextWebViewDestroyed(webView->priv->context.get(), webView);
802     }
803
804     if (webView->priv->websiteDataManager) {
805         webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get()));
806         webView->priv->websiteDataManager = nullptr;
807     }
808
809     if (webView->priv->currentScriptDialog) {
810         webkit_script_dialog_close(webView->priv->currentScriptDialog);
811         ASSERT(!webView->priv->currentScriptDialog);
812     }
813
814 #if PLATFORM(WPE)
815     webView->priv->view->close();
816 #endif
817
818     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
819 }
820
821 static gboolean webkitWebViewAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer)
822 {
823     void* object = g_value_get_object(handlerReturn);
824     if (object)
825         g_value_set_object(returnValue, object);
826
827     return !object;
828 }
829
830 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
831 {
832     GObjectClass* gObjectClass = G_OBJECT_CLASS(webViewClass);
833
834     gObjectClass->constructed = webkitWebViewConstructed;
835     gObjectClass->set_property = webkitWebViewSetProperty;
836     gObjectClass->get_property = webkitWebViewGetProperty;
837     gObjectClass->dispose = webkitWebViewDispose;
838
839     webViewClass->load_failed = webkitWebViewLoadFail;
840     webViewClass->create = webkitWebViewCreate;
841     webViewClass->script_dialog = webkitWebViewScriptDialog;
842     webViewClass->decide_policy = webkitWebViewDecidePolicy;
843     webViewClass->permission_request = webkitWebViewPermissionRequest;
844     webViewClass->run_file_chooser = webkitWebViewRunFileChooser;
845     webViewClass->authenticate = webkitWebViewAuthenticate;
846     webViewClass->show_notification = webkitWebViewShowNotification;
847
848 #if PLATFORM(WPE)
849     /**
850      * WebKitWebView:backend:
851      *
852      * The #WebKitWebViewBackend of the view.
853      *
854      * since: 2.20
855      */
856     g_object_class_install_property(
857         gObjectClass,
858         PROP_BACKEND,
859         g_param_spec_boxed(
860             "backend",
861             _("Backend"),
862             _("The backend for the web view"),
863             WEBKIT_TYPE_WEB_VIEW_BACKEND,
864             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
865 #endif
866
867     /**
868      * WebKitWebView:web-context:
869      *
870      * The #WebKitWebContext of the view.
871      */
872     g_object_class_install_property(gObjectClass,
873                                     PROP_WEB_CONTEXT,
874                                     g_param_spec_object("web-context",
875                                                         _("Web Context"),
876                                                         _("The web context for the view"),
877                                                         WEBKIT_TYPE_WEB_CONTEXT,
878                                                         static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
879     /**
880      * WebKitWebView:related-view:
881      *
882      * The related #WebKitWebView used when creating the view to share the
883      * same web process. This property is not readable because the related
884      * web view is only valid during the object construction.
885      *
886      * Since: 2.4
887      */
888     g_object_class_install_property(
889         gObjectClass,
890         PROP_RELATED_VIEW,
891         g_param_spec_object(
892             "related-view",
893             _("Related WebView"),
894             _("The related WebKitWebView used when creating the view to share the same web process"),
895             WEBKIT_TYPE_WEB_VIEW,
896             static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
897
898     /**
899      * WebKitWebView:settings:
900      *
901      * The #WebKitSettings of the view.
902      *
903      * Since: 2.6
904      */
905     g_object_class_install_property(
906         gObjectClass,
907         PROP_SETTINGS,
908         g_param_spec_object(
909             "settings",
910             _("WebView settings"),
911             _("The WebKitSettings of the view"),
912             WEBKIT_TYPE_SETTINGS,
913             static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT)));
914
915     /**
916      * WebKitWebView:user-content-manager:
917      *
918      * The #WebKitUserContentManager of the view.
919      *
920      * Since: 2.6
921      */
922     g_object_class_install_property(
923         gObjectClass,
924         PROP_USER_CONTENT_MANAGER,
925         g_param_spec_object(
926             "user-content-manager",
927             _("WebView user content manager"),
928             _("The WebKitUserContentManager of the view"),
929             WEBKIT_TYPE_USER_CONTENT_MANAGER,
930             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
931
932     /**
933      * WebKitWebView:title:
934      *
935      * The main frame document title of this #WebKitWebView. If
936      * the title has not been received yet, it will be %NULL.
937      */
938     g_object_class_install_property(gObjectClass,
939                                     PROP_TITLE,
940                                     g_param_spec_string("title",
941                                                         _("Title"),
942                                                         _("Main frame document title"),
943                                                         0,
944                                                         WEBKIT_PARAM_READABLE));
945
946     /**
947      * WebKitWebView:estimated-load-progress:
948      *
949      * An estimate of the percent completion for the current loading operation.
950      * This value will range from 0.0 to 1.0 and, once a load completes,
951      * will remain at 1.0 until a new load starts, at which point it
952      * will be reset to 0.0.
953      * The value is an estimate based on the total number of bytes expected
954      * to be received for a document, including all its possible subresources
955      * and child documents.
956      */
957     g_object_class_install_property(gObjectClass,
958                                     PROP_ESTIMATED_LOAD_PROGRESS,
959                                     g_param_spec_double("estimated-load-progress",
960                                                         _("Estimated Load Progress"),
961                                                         _("An estimate of the percent completion for a document load"),
962                                                         0.0, 1.0, 0.0,
963                                                         WEBKIT_PARAM_READABLE));
964 #if PLATFORM(GTK)
965     /**
966      * WebKitWebView:favicon:
967      *
968      * The favicon currently associated to the #WebKitWebView.
969      * See webkit_web_view_get_favicon() for more details.
970      */
971     g_object_class_install_property(gObjectClass,
972                                     PROP_FAVICON,
973                                     g_param_spec_pointer("favicon",
974                                                          _("Favicon"),
975                                                          _("The favicon associated to the view, if any"),
976                                                          WEBKIT_PARAM_READABLE));
977 #endif
978
979     /**
980      * WebKitWebView:uri:
981      *
982      * The current active URI of the #WebKitWebView.
983      * See webkit_web_view_get_uri() for more details.
984      */
985     g_object_class_install_property(gObjectClass,
986                                     PROP_URI,
987                                     g_param_spec_string("uri",
988                                                         _("URI"),
989                                                         _("The current active URI of the view"),
990                                                         0,
991                                                         WEBKIT_PARAM_READABLE));
992
993     /**
994      * WebKitWebView:zoom-level:
995      *
996      * The zoom level of the #WebKitWebView content.
997      * See webkit_web_view_set_zoom_level() for more details.
998      */
999     g_object_class_install_property(
1000         gObjectClass,
1001         PROP_ZOOM_LEVEL,
1002         g_param_spec_double(
1003             "zoom-level",
1004             _("Zoom level"),
1005             _("The zoom level of the view content"),
1006             0, G_MAXDOUBLE, 1,
1007             WEBKIT_PARAM_READWRITE));
1008
1009     /**
1010      * WebKitWebView:is-loading:
1011      *
1012      * Whether the #WebKitWebView is currently loading a page. This property becomes
1013      * %TRUE as soon as a new load operation is requested and before the
1014      * #WebKitWebView::load-changed signal is emitted with %WEBKIT_LOAD_STARTED and
1015      * at that point the active URI is the requested one.
1016      * When the load operation finishes the property is set to %FALSE before
1017      * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_FINISHED.
1018      */
1019     g_object_class_install_property(
1020         gObjectClass,
1021         PROP_IS_LOADING,
1022         g_param_spec_boolean(
1023             "is-loading",
1024             _("Is Loading"),
1025             _("Whether the view is loading a page"),
1026             FALSE,
1027             WEBKIT_PARAM_READABLE));
1028
1029     /**
1030      * WebKitWebView:is-playing-audio:
1031      *
1032      * Whether the #WebKitWebView is currently playing audio from a page.
1033      * This property becomes %TRUE as soon as web content starts playing any
1034      * kind of audio. When a page is no longer playing any kind of sound,
1035      * the property is set back to %FALSE.
1036      *
1037      * Since: 2.8
1038      */
1039     g_object_class_install_property(
1040         gObjectClass,
1041         PROP_IS_PLAYING_AUDIO,
1042         g_param_spec_boolean(
1043             "is-playing-audio",
1044             "Is Playing Audio",
1045             _("Whether the view is playing audio"),
1046             FALSE,
1047             WEBKIT_PARAM_READABLE));
1048
1049     /**
1050      * WebKitWebView:is-ephemeral:
1051      *
1052      * Whether the #WebKitWebView is ephemeral. An ephemeral web view never writes
1053      * website data to the client storage, no matter what #WebKitWebsiteDataManager
1054      * its context is using. This is normally used to implement private browsing mode.
1055      * This is a %G_PARAM_CONSTRUCT_ONLY property, so you have to create a ephemeral
1056      * #WebKitWebView and it can't be changed. Note that all #WebKitWebView<!-- -->s
1057      * created with an ephemeral #WebKitWebContext will be ephemeral automatically.
1058      * See also webkit_web_context_new_ephemeral().
1059      *
1060      * Since: 2.16
1061      */
1062     g_object_class_install_property(
1063         gObjectClass,
1064         PROP_IS_EPHEMERAL,
1065         g_param_spec_boolean(
1066             "is-ephemeral",
1067             "Is Ephemeral",
1068             _("Whether the web view is ephemeral"),
1069             FALSE,
1070             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1071
1072     /**
1073      * WebKitWebView:is-controlled-by-automation:
1074      *
1075      * Whether the #WebKitWebView is controlled by automation. This should only be used when
1076      * creating a new #WebKitWebView as a response to #WebKitAutomationSession::create-web-view
1077      * signal request.
1078      *
1079      * Since: 2.18
1080      */
1081     g_object_class_install_property(
1082         gObjectClass,
1083         PROP_IS_CONTROLLED_BY_AUTOMATION,
1084         g_param_spec_boolean(
1085             "is-controlled-by-automation",
1086             "Is Controlled By Automation",
1087             _("Whether the web view is controlled by automation"),
1088             FALSE,
1089             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1090
1091     /**
1092      * WebKitWebView:editable:
1093      *
1094      * Whether the pages loaded inside #WebKitWebView are editable. For more
1095      * information see webkit_web_view_set_editable().
1096      *
1097      * Since: 2.8
1098      */
1099     g_object_class_install_property(
1100         gObjectClass,
1101         PROP_EDITABLE,
1102         g_param_spec_boolean(
1103             "editable",
1104             _("Editable"),
1105             _("Whether the content can be modified by the user."),
1106             FALSE,
1107             WEBKIT_PARAM_READWRITE));
1108
1109     /**
1110      * WebKitWebView::load-changed:
1111      * @web_view: the #WebKitWebView on which the signal is emitted
1112      * @load_event: the #WebKitLoadEvent
1113      *
1114      * Emitted when a load operation in @web_view changes.
1115      * The signal is always emitted with %WEBKIT_LOAD_STARTED when a
1116      * new load request is made and %WEBKIT_LOAD_FINISHED when the load
1117      * finishes successfully or due to an error. When the ongoing load
1118      * operation fails #WebKitWebView::load-failed signal is emitted
1119      * before #WebKitWebView::load-changed is emitted with
1120      * %WEBKIT_LOAD_FINISHED.
1121      * If a redirection is received from the server, this signal is emitted
1122      * with %WEBKIT_LOAD_REDIRECTED after the initial emission with
1123      * %WEBKIT_LOAD_STARTED and before %WEBKIT_LOAD_COMMITTED.
1124      * When the page content starts arriving the signal is emitted with
1125      * %WEBKIT_LOAD_COMMITTED event.
1126      *
1127      * You can handle this signal and use a switch to track any ongoing
1128      * load operation.
1129      *
1130      * <informalexample><programlisting>
1131      * static void web_view_load_changed (WebKitWebView  *web_view,
1132      *                                    WebKitLoadEvent load_event,
1133      *                                    gpointer        user_data)
1134      * {
1135      *     switch (load_event) {
1136      *     case WEBKIT_LOAD_STARTED:
1137      *         /<!-- -->* New load, we have now a provisional URI *<!-- -->/
1138      *         provisional_uri = webkit_web_view_get_uri (web_view);
1139      *         /<!-- -->* Here we could start a spinner or update the
1140      *          <!-- -->* location bar with the provisional URI *<!-- -->/
1141      *         break;
1142      *     case WEBKIT_LOAD_REDIRECTED:
1143      *         redirected_uri = webkit_web_view_get_uri (web_view);
1144      *         break;
1145      *     case WEBKIT_LOAD_COMMITTED:
1146      *         /<!-- -->* The load is being performed. Current URI is
1147      *          <!-- -->* the final one and it won't change unless a new
1148      *          <!-- -->* load is requested or a navigation within the
1149      *          <!-- -->* same page is performed *<!-- -->/
1150      *         uri = webkit_web_view_get_uri (web_view);
1151      *         break;
1152      *     case WEBKIT_LOAD_FINISHED:
1153      *         /<!-- -->* Load finished, we can now stop the spinner *<!-- -->/
1154      *         break;
1155      *     }
1156      * }
1157      * </programlisting></informalexample>
1158      */
1159     signals[LOAD_CHANGED] =
1160         g_signal_new("load-changed",
1161                      G_TYPE_FROM_CLASS(webViewClass),
1162                      G_SIGNAL_RUN_LAST,
1163                      G_STRUCT_OFFSET(WebKitWebViewClass, load_changed),
1164                      0, 0,
1165                      g_cclosure_marshal_VOID__ENUM,
1166                      G_TYPE_NONE, 1,
1167                      WEBKIT_TYPE_LOAD_EVENT);
1168
1169     /**
1170      * WebKitWebView::load-failed:
1171      * @web_view: the #WebKitWebView on which the signal is emitted
1172      * @load_event: the #WebKitLoadEvent of the load operation
1173      * @failing_uri: the URI that failed to load
1174      * @error: the #GError that was triggered
1175      *
1176      * Emitted when an error occurs during a load operation.
1177      * If the error happened when starting to load data for a page
1178      * @load_event will be %WEBKIT_LOAD_STARTED. If it happened while
1179      * loading a committed data source @load_event will be %WEBKIT_LOAD_COMMITTED.
1180      * Since a load error causes the load operation to finish, the signal
1181      * WebKitWebView::load-changed will always be emitted with
1182      * %WEBKIT_LOAD_FINISHED event right after this one.
1183      *
1184      * By default, if the signal is not handled, a stock error page will be displayed.
1185      * You need to handle the signal if you want to provide your own error page.
1186      *
1187      * Returns: %TRUE to stop other handlers from being invoked for the event.
1188      *    %FALSE to propagate the event further.
1189      */
1190     signals[LOAD_FAILED] =
1191         g_signal_new(
1192             "load-failed",
1193             G_TYPE_FROM_CLASS(webViewClass),
1194             G_SIGNAL_RUN_LAST,
1195             G_STRUCT_OFFSET(WebKitWebViewClass, load_failed),
1196             g_signal_accumulator_true_handled, 0,
1197             g_cclosure_marshal_generic,
1198             G_TYPE_BOOLEAN, 3,
1199             WEBKIT_TYPE_LOAD_EVENT,
1200             G_TYPE_STRING,
1201             G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE);
1202
1203     /**
1204      * WebKitWebView::load-failed-with-tls-errors:
1205      * @web_view: the #WebKitWebView on which the signal is emitted
1206      * @failing_uri: the URI that failed to load
1207      * @certificate: a #GTlsCertificate
1208      * @errors: a #GTlsCertificateFlags with the verification status of @certificate
1209      *
1210      * Emitted when a TLS error occurs during a load operation.
1211      * To allow an exception for this @certificate
1212      * and the host of @failing_uri use webkit_web_context_allow_tls_certificate_for_host().
1213      *
1214      * To handle this signal asynchronously you should call g_object_ref() on @certificate
1215      * and return %TRUE.
1216      *
1217      * If %FALSE is returned, #WebKitWebView::load-failed will be emitted. The load
1218      * will finish regardless of the returned value.
1219      *
1220      * Returns: %TRUE to stop other handlers from being invoked for the event.
1221      *   %FALSE to propagate the event further.
1222      *
1223      * Since: 2.6
1224      */
1225     signals[LOAD_FAILED_WITH_TLS_ERRORS] =
1226         g_signal_new("load-failed-with-tls-errors",
1227             G_TYPE_FROM_CLASS(webViewClass),
1228             G_SIGNAL_RUN_LAST,
1229             G_STRUCT_OFFSET(WebKitWebViewClass, load_failed_with_tls_errors),
1230             g_signal_accumulator_true_handled, 0 /* accumulator data */,
1231             g_cclosure_marshal_generic,
1232             G_TYPE_BOOLEAN, 3,
1233             G_TYPE_STRING,
1234             G_TYPE_TLS_CERTIFICATE,
1235             G_TYPE_TLS_CERTIFICATE_FLAGS);
1236
1237     /**
1238      * WebKitWebView::create:
1239      * @web_view: the #WebKitWebView on which the signal is emitted
1240      * @navigation_action: a #WebKitNavigationAction
1241      *
1242      * Emitted when the creation of a new #WebKitWebView is requested.
1243      * If this signal is handled the signal handler should return the
1244      * newly created #WebKitWebView.
1245      *
1246      * The #WebKitNavigationAction parameter contains information about the
1247      * navigation action that triggered this signal.
1248      *
1249      * When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES
1250      * process model, the new #WebKitWebView should be related to
1251      * @web_view to share the same web process, see webkit_web_view_new_with_related_view()
1252      * for more details.
1253      *
1254      * The new #WebKitWebView should not be displayed to the user
1255      * until the #WebKitWebView::ready-to-show signal is emitted.
1256      *
1257      * Returns: (transfer full): a newly allocated #WebKitWebView widget
1258      *    or %NULL to propagate the event further.
1259      */
1260     signals[CREATE] = g_signal_new(
1261         "create",
1262         G_TYPE_FROM_CLASS(webViewClass),
1263         G_SIGNAL_RUN_LAST,
1264         G_STRUCT_OFFSET(WebKitWebViewClass, create),
1265         webkitWebViewAccumulatorObjectHandled, 0,
1266         g_cclosure_marshal_generic,
1267 #if PLATFORM(GTK)
1268         GTK_TYPE_WIDGET,
1269 #else
1270         WEBKIT_TYPE_WEB_VIEW,
1271 #endif
1272         1,
1273         WEBKIT_TYPE_NAVIGATION_ACTION | G_SIGNAL_TYPE_STATIC_SCOPE);
1274
1275     /**
1276      * WebKitWebView::ready-to-show:
1277      * @web_view: the #WebKitWebView on which the signal is emitted
1278      *
1279      * Emitted after #WebKitWebView::create on the newly created #WebKitWebView
1280      * when it should be displayed to the user. When this signal is emitted
1281      * all the information about how the window should look, including
1282      * size, position, whether the location, status and scrollbars
1283      * should be displayed, is already set on the #WebKitWindowProperties
1284      * of @web_view. See also webkit_web_view_get_window_properties().
1285      */
1286     signals[READY_TO_SHOW] =
1287         g_signal_new("ready-to-show",
1288                      G_TYPE_FROM_CLASS(webViewClass),
1289                      G_SIGNAL_RUN_LAST,
1290                      G_STRUCT_OFFSET(WebKitWebViewClass, ready_to_show),
1291                      0, 0,
1292                      g_cclosure_marshal_VOID__VOID,
1293                      G_TYPE_NONE, 0);
1294
1295      /**
1296      * WebKitWebView::run-as-modal:
1297      * @web_view: the #WebKitWebView on which the signal is emitted
1298      *
1299      * Emitted after #WebKitWebView::ready-to-show on the newly
1300      * created #WebKitWebView when JavaScript code calls
1301      * <function>window.showModalDialog</function>. The purpose of
1302      * this signal is to allow the client application to prepare the
1303      * new view to behave as modal. Once the signal is emitted a new
1304      * main loop will be run to block user interaction in the parent
1305      * #WebKitWebView until the new dialog is closed.
1306      */
1307     signals[RUN_AS_MODAL] =
1308             g_signal_new("run-as-modal",
1309                          G_TYPE_FROM_CLASS(webViewClass),
1310                          G_SIGNAL_RUN_LAST,
1311                          G_STRUCT_OFFSET(WebKitWebViewClass, run_as_modal),
1312                          0, 0,
1313                          g_cclosure_marshal_VOID__VOID,
1314                          G_TYPE_NONE, 0);
1315
1316     /**
1317      * WebKitWebView::close:
1318      * @web_view: the #WebKitWebView on which the signal is emitted
1319      *
1320      * Emitted when closing a #WebKitWebView is requested. This occurs when a
1321      * call is made from JavaScript's <function>window.close</function> function or
1322      * after trying to close the @web_view with webkit_web_view_try_close().
1323      * It is the owner's responsibility to handle this signal to hide or
1324      * destroy the #WebKitWebView, if necessary.
1325      */
1326     signals[CLOSE] =
1327         g_signal_new("close",
1328                      G_TYPE_FROM_CLASS(webViewClass),
1329                      G_SIGNAL_RUN_LAST,
1330                      G_STRUCT_OFFSET(WebKitWebViewClass, close),
1331                      0, 0,
1332                      g_cclosure_marshal_VOID__VOID,
1333                      G_TYPE_NONE, 0);
1334
1335     /**
1336      * WebKitWebView::script-dialog:
1337      * @web_view: the #WebKitWebView on which the signal is emitted
1338      * @dialog: the #WebKitScriptDialog to show
1339      *
1340      * Emitted when JavaScript code calls <function>window.alert</function>,
1341      * <function>window.confirm</function> or <function>window.prompt</function>,
1342      * or when <function>onbeforeunload</function> event is fired.
1343      * The @dialog parameter should be used to build the dialog.
1344      * If the signal is not handled a different dialog will be built and shown depending
1345      * on the dialog type:
1346      * <itemizedlist>
1347      * <listitem><para>
1348      *  %WEBKIT_SCRIPT_DIALOG_ALERT: message dialog with a single Close button.
1349      * </para></listitem>
1350      * <listitem><para>
1351      *  %WEBKIT_SCRIPT_DIALOG_CONFIRM: message dialog with OK and Cancel buttons.
1352      * </para></listitem>
1353      * <listitem><para>
1354      *  %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and
1355      *  a text entry with the default text.
1356      * </para></listitem>
1357      * <listitem><para>
1358      *  %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: message dialog with Stay and Leave buttons.
1359      * </para></listitem>
1360      * </itemizedlist>
1361      *
1362      * It is possible to handle the script dialog request asynchronously, by simply
1363      * caling webkit_script_dialog_ref() on the @dialog argument and calling
1364      * webkit_script_dialog_close() when done.
1365      * If the last reference is removed on a #WebKitScriptDialog and the dialog has not been
1366      * closed, webkit_script_dialog_close() will be called.
1367      *
1368      * Returns: %TRUE to stop other handlers from being invoked for the event.
1369      *    %FALSE to propagate the event further.
1370      */
1371     signals[SCRIPT_DIALOG] = g_signal_new(
1372         "script-dialog",
1373         G_TYPE_FROM_CLASS(webViewClass),
1374         G_SIGNAL_RUN_LAST,
1375         G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog),
1376         g_signal_accumulator_true_handled, nullptr,
1377         g_cclosure_marshal_generic,
1378         G_TYPE_BOOLEAN, 1,
1379         WEBKIT_TYPE_SCRIPT_DIALOG);
1380
1381     /**
1382      * WebKitWebView::decide-policy:
1383      * @web_view: the #WebKitWebView on which the signal is emitted
1384      * @decision: the #WebKitPolicyDecision
1385      * @decision_type: a #WebKitPolicyDecisionType denoting the type of @decision
1386      *
1387      * This signal is emitted when WebKit is requesting the client to decide a policy
1388      * decision, such as whether to navigate to a page, open a new window or whether or
1389      * not to download a resource. The #WebKitNavigationPolicyDecision passed in the
1390      * @decision argument is a generic type, but should be casted to a more
1391      * specific type when making the decision. For example:
1392      *
1393      * <informalexample><programlisting>
1394      * static gboolean
1395      * decide_policy_cb (WebKitWebView *web_view,
1396      *                   WebKitPolicyDecision *decision,
1397      *                   WebKitPolicyDecisionType type)
1398      * {
1399      *     switch (type) {
1400      *     case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: {
1401      *         WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1402      *         /<!-- -->* Make a policy decision here. *<!-- -->/
1403      *         break;
1404      *     }
1405      *     case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION: {
1406      *         WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1407      *         /<!-- -->* Make a policy decision here. *<!-- -->/
1408      *         break;
1409      *     }
1410      *     case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
1411      *         WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
1412      *         /<!-- -->* Make a policy decision here. *<!-- -->/
1413      *         break;
1414      *     default:
1415      *         /<!-- -->* Making no decision results in webkit_policy_decision_use(). *<!-- -->/
1416      *         return FALSE;
1417      *     }
1418      *     return TRUE;
1419      * }
1420      * </programlisting></informalexample>
1421      *
1422      * It is possible to make policy decision asynchronously, by simply calling g_object_ref()
1423      * on the @decision argument and returning %TRUE to block the default signal handler.
1424      * If the last reference is removed on a #WebKitPolicyDecision and no decision has been
1425      * made explicitly, webkit_policy_decision_use() will be the default policy decision. The
1426      * default signal handler will simply call webkit_policy_decision_use(). Only the first
1427      * policy decision chosen for a given #WebKitPolicyDecision will have any affect.
1428      *
1429      * Returns: %TRUE to stop other handlers from being invoked for the event.
1430      *   %FALSE to propagate the event further.
1431      *
1432      */
1433     signals[DECIDE_POLICY] = g_signal_new(
1434         "decide-policy",
1435         G_TYPE_FROM_CLASS(webViewClass),
1436         G_SIGNAL_RUN_LAST,
1437         G_STRUCT_OFFSET(WebKitWebViewClass, decide_policy),
1438         g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1439         g_cclosure_marshal_generic,
1440         G_TYPE_BOOLEAN, 2, /* number of parameters */
1441         WEBKIT_TYPE_POLICY_DECISION,
1442         WEBKIT_TYPE_POLICY_DECISION_TYPE);
1443
1444     /**
1445      * WebKitWebView::permission-request:
1446      * @web_view: the #WebKitWebView on which the signal is emitted
1447      * @request: the #WebKitPermissionRequest
1448      *
1449      * This signal is emitted when WebKit is requesting the client to
1450      * decide about a permission request, such as allowing the browser
1451      * to switch to fullscreen mode, sharing its location or similar
1452      * operations.
1453      *
1454      * A possible way to use this signal could be through a dialog
1455      * allowing the user decide what to do with the request:
1456      *
1457      * <informalexample><programlisting>
1458      * static gboolean permission_request_cb (WebKitWebView *web_view,
1459      *                                        WebKitPermissionRequest *request,
1460      *                                        GtkWindow *parent_window)
1461      * {
1462      *     GtkWidget *dialog = gtk_message_dialog_new (parent_window,
1463      *                                                 GTK_DIALOG_MODAL,
1464      *                                                 GTK_MESSAGE_QUESTION,
1465      *                                                 GTK_BUTTONS_YES_NO,
1466      *                                                 "Allow Permission Request?");
1467      *     gtk_widget_show (dialog);
1468      *     gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1469      *
1470      *     switch (result) {
1471      *     case GTK_RESPONSE_YES:
1472      *         webkit_permission_request_allow (request);
1473      *         break;
1474      *     default:
1475      *         webkit_permission_request_deny (request);
1476      *         break;
1477      *     }
1478      *     gtk_widget_destroy (dialog);
1479      *
1480      *     return TRUE;
1481      * }
1482      * </programlisting></informalexample>
1483      *
1484      * It is possible to handle permission requests asynchronously, by
1485      * simply calling g_object_ref() on the @request argument and
1486      * returning %TRUE to block the default signal handler.  If the
1487      * last reference is removed on a #WebKitPermissionRequest and the
1488      * request has not been handled, webkit_permission_request_deny()
1489      * will be the default action.
1490      *
1491      * If the signal is not handled, the @request will be completed automatically
1492      * by the specific #WebKitPermissionRequest that could allow or deny it. Check the
1493      * documentation of classes implementing #WebKitPermissionRequest interface to know
1494      * their default action.
1495      *
1496      * Returns: %TRUE to stop other handlers from being invoked for the event.
1497      *   %FALSE to propagate the event further.
1498      *
1499      */
1500     signals[PERMISSION_REQUEST] = g_signal_new(
1501         "permission-request",
1502         G_TYPE_FROM_CLASS(webViewClass),
1503         G_SIGNAL_RUN_LAST,
1504         G_STRUCT_OFFSET(WebKitWebViewClass, permission_request),
1505         g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1506         g_cclosure_marshal_generic,
1507         G_TYPE_BOOLEAN, 1, /* number of parameters */
1508         WEBKIT_TYPE_PERMISSION_REQUEST);
1509     /**
1510      * WebKitWebView::mouse-target-changed:
1511      * @web_view: the #WebKitWebView on which the signal is emitted
1512      * @hit_test_result: a #WebKitHitTestResult
1513      * @modifiers: a bitmask of #GdkModifierType
1514      *
1515      * This signal is emitted when the mouse cursor moves over an
1516      * element such as a link, image or a media element. To determine
1517      * what type of element the mouse cursor is over, a Hit Test is performed
1518      * on the current mouse coordinates and the result is passed in the
1519      * @hit_test_result argument. The @modifiers argument is a bitmask of
1520      * #GdkModifierType flags indicating the state of modifier keys.
1521      * The signal is emitted again when the mouse is moved out of the
1522      * current element with a new @hit_test_result.
1523      */
1524     signals[MOUSE_TARGET_CHANGED] = g_signal_new(
1525         "mouse-target-changed",
1526         G_TYPE_FROM_CLASS(webViewClass),
1527         G_SIGNAL_RUN_LAST,
1528         G_STRUCT_OFFSET(WebKitWebViewClass, mouse_target_changed),
1529         nullptr, nullptr,
1530         g_cclosure_marshal_generic,
1531         G_TYPE_NONE, 2,
1532         WEBKIT_TYPE_HIT_TEST_RESULT,
1533         G_TYPE_UINT);
1534
1535 #if PLATFORM(GTK)
1536     /**
1537      * WebKitWebView::print:
1538      * @web_view: the #WebKitWebView on which the signal is emitted
1539      * @print_operation: the #WebKitPrintOperation that will handle the print request
1540      *
1541      * Emitted when printing is requested on @web_view, usually by a JavaScript call,
1542      * before the print dialog is shown. This signal can be used to set the initial
1543      * print settings and page setup of @print_operation to be used as default values in
1544      * the print dialog. You can call webkit_print_operation_set_print_settings() and
1545      * webkit_print_operation_set_page_setup() and then return %FALSE to propagate the
1546      * event so that the print dialog is shown.
1547      *
1548      * You can connect to this signal and return %TRUE to cancel the print operation
1549      * or implement your own print dialog.
1550      *
1551      * Returns: %TRUE to stop other handlers from being invoked for the event.
1552      *    %FALSE to propagate the event further.
1553      */
1554     signals[PRINT] = g_signal_new(
1555         "print",
1556         G_TYPE_FROM_CLASS(webViewClass),
1557         G_SIGNAL_RUN_LAST,
1558         G_STRUCT_OFFSET(WebKitWebViewClass, print),
1559         g_signal_accumulator_true_handled, nullptr,
1560         g_cclosure_marshal_generic,
1561         G_TYPE_BOOLEAN, 1,
1562         WEBKIT_TYPE_PRINT_OPERATION);
1563 #endif // PLATFORM(GTK)
1564
1565     /**
1566      * WebKitWebView::resource-load-started:
1567      * @web_view: the #WebKitWebView on which the signal is emitted
1568      * @resource: a #WebKitWebResource
1569      * @request: a #WebKitURIRequest
1570      *
1571      * Emitted when a new resource is going to be loaded. The @request parameter
1572      * contains the #WebKitURIRequest that will be sent to the server.
1573      * You can monitor the load operation by connecting to the different signals
1574      * of @resource.
1575      */
1576     signals[RESOURCE_LOAD_STARTED] = g_signal_new(
1577         "resource-load-started",
1578         G_TYPE_FROM_CLASS(webViewClass),
1579         G_SIGNAL_RUN_LAST,
1580         G_STRUCT_OFFSET(WebKitWebViewClass, resource_load_started),
1581         nullptr, nullptr,
1582         g_cclosure_marshal_generic,
1583         G_TYPE_NONE, 2,
1584         WEBKIT_TYPE_WEB_RESOURCE,
1585                      WEBKIT_TYPE_URI_REQUEST);
1586
1587     /**
1588      * WebKitWebView::enter-fullscreen:
1589      * @web_view: the #WebKitWebView on which the signal is emitted.
1590      *
1591      * Emitted when JavaScript code calls
1592      * <function>element.webkitRequestFullScreen</function>. If the
1593      * signal is not handled the #WebKitWebView will proceed to full screen
1594      * its top level window. This signal can be used by client code to
1595      * request permission to the user prior doing the full screen
1596      * transition and eventually prepare the top-level window
1597      * (e.g. hide some widgets that would otherwise be part of the
1598      * full screen window).
1599      *
1600      * Returns: %TRUE to stop other handlers from being invoked for the event.
1601      *    %FALSE to continue emission of the event.
1602      */
1603     signals[ENTER_FULLSCREEN] = g_signal_new(
1604         "enter-fullscreen",
1605         G_TYPE_FROM_CLASS(webViewClass),
1606         G_SIGNAL_RUN_LAST,
1607         G_STRUCT_OFFSET(WebKitWebViewClass, enter_fullscreen),
1608         g_signal_accumulator_true_handled, nullptr,
1609         g_cclosure_marshal_generic,
1610         G_TYPE_BOOLEAN, 0);
1611
1612     /**
1613      * WebKitWebView::leave-fullscreen:
1614      * @web_view: the #WebKitWebView on which the signal is emitted.
1615      *
1616      * Emitted when the #WebKitWebView is about to restore its top level
1617      * window out of its full screen state. This signal can be used by
1618      * client code to restore widgets hidden during the
1619      * #WebKitWebView::enter-fullscreen stage for instance.
1620      *
1621      * Returns: %TRUE to stop other handlers from being invoked for the event.
1622      *    %FALSE to continue emission of the event.
1623      */
1624     signals[LEAVE_FULLSCREEN] = g_signal_new(
1625         "leave-fullscreen",
1626         G_TYPE_FROM_CLASS(webViewClass),
1627         G_SIGNAL_RUN_LAST,
1628         G_STRUCT_OFFSET(WebKitWebViewClass, leave_fullscreen),
1629         g_signal_accumulator_true_handled, nullptr,
1630         g_cclosure_marshal_generic,
1631         G_TYPE_BOOLEAN, 0);
1632
1633      /**
1634      * WebKitWebView::run-file-chooser:
1635      * @web_view: the #WebKitWebView on which the signal is emitted
1636      * @request: a #WebKitFileChooserRequest
1637      *
1638      * This signal is emitted when the user interacts with a &lt;input
1639      * type='file' /&gt; HTML element, requesting from WebKit to show
1640      * a dialog to select one or more files to be uploaded. To let the
1641      * application know the details of the file chooser, as well as to
1642      * allow the client application to either cancel the request or
1643      * perform an actual selection of files, the signal will pass an
1644      * instance of the #WebKitFileChooserRequest in the @request
1645      * argument.
1646      *
1647      * The default signal handler will asynchronously run a regular
1648      * #GtkFileChooserDialog for the user to interact with.
1649      *
1650      * Returns: %TRUE to stop other handlers from being invoked for the event.
1651      *   %FALSE to propagate the event further.
1652      *
1653      */
1654     signals[RUN_FILE_CHOOSER] = g_signal_new(
1655         "run-file-chooser",
1656         G_TYPE_FROM_CLASS(webViewClass),
1657         G_SIGNAL_RUN_LAST,
1658         G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
1659         g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1660         g_cclosure_marshal_generic,
1661         G_TYPE_BOOLEAN, 1, /* number of parameters */
1662         WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
1663
1664     /**
1665      * WebKitWebView::context-menu:
1666      * @web_view: the #WebKitWebView on which the signal is emitted
1667      * @context_menu: the proposed #WebKitContextMenu
1668      * @event: the #GdkEvent that triggered the context menu
1669      * @hit_test_result: a #WebKitHitTestResult
1670      *
1671      * Emitted when a context menu is about to be displayed to give the application
1672      * a chance to customize the proposed menu, prevent the menu from being displayed,
1673      * or build its own context menu.
1674      * <itemizedlist>
1675      * <listitem><para>
1676      *  To customize the proposed menu you can use webkit_context_menu_prepend(),
1677      *  webkit_context_menu_append() or webkit_context_menu_insert() to add new
1678      *  #WebKitContextMenuItem<!-- -->s to @context_menu, webkit_context_menu_move_item()
1679      *  to reorder existing items, or webkit_context_menu_remove() to remove an
1680      *  existing item. The signal handler should return %FALSE, and the menu represented
1681      *  by @context_menu will be shown.
1682      * </para></listitem>
1683      * <listitem><para>
1684      *  To prevent the menu from being displayed you can just connect to this signal
1685      *  and return %TRUE so that the proposed menu will not be shown.
1686      * </para></listitem>
1687      * <listitem><para>
1688      *  To build your own menu, you can remove all items from the proposed menu with
1689      *  webkit_context_menu_remove_all(), add your own items and return %FALSE so
1690      *  that the menu will be shown. You can also ignore the proposed #WebKitContextMenu,
1691      *  build your own #GtkMenu and return %TRUE to prevent the proposed menu from being shown.
1692      * </para></listitem>
1693      * <listitem><para>
1694      *  If you just want the default menu to be shown always, simply don't connect to this
1695      *  signal because showing the proposed context menu is the default behaviour.
1696      * </para></listitem>
1697      * </itemizedlist>
1698      *
1699      * The @event is expected to be one of the following types:
1700      * <itemizedlist>
1701      * <listitem><para>
1702      * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu
1703      * was triggered with mouse.
1704      * </para></listitem>
1705      * <listitem><para>
1706      * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show
1707      * the menu.
1708      * </para></listitem>
1709      * <listitem><para>
1710      * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget::popup-menu
1711      * signal was used to show the context menu.
1712      * </para></listitem>
1713      * </itemizedlist>
1714      *
1715      * If the signal handler returns %FALSE the context menu represented by @context_menu
1716      * will be shown, if it return %TRUE the context menu will not be shown.
1717      *
1718      * The proposed #WebKitContextMenu passed in @context_menu argument is only valid
1719      * during the signal emission.
1720      *
1721      * Returns: %TRUE to stop other handlers from being invoked for the event.
1722      *    %FALSE to propagate the event further.
1723      */
1724     signals[CONTEXT_MENU] = g_signal_new(
1725         "context-menu",
1726         G_TYPE_FROM_CLASS(webViewClass),
1727         G_SIGNAL_RUN_LAST,
1728         G_STRUCT_OFFSET(WebKitWebViewClass, context_menu),
1729         g_signal_accumulator_true_handled, nullptr,
1730         g_cclosure_marshal_generic,
1731         G_TYPE_BOOLEAN, 3,
1732         WEBKIT_TYPE_CONTEXT_MENU,
1733 #if PLATFORM(GTK)
1734         GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1735 #elif PLATFORM(WPE)
1736         G_TYPE_POINTER, // FIXME: use a wpe thing here. I'm not sure we want to expose libwpe in the API.
1737 #endif
1738         WEBKIT_TYPE_HIT_TEST_RESULT);
1739
1740     /**
1741      * WebKitWebView::context-menu-dismissed:
1742      * @web_view: the #WebKitWebView on which the signal is emitted
1743      *
1744      * Emitted after #WebKitWebView::context-menu signal, if the context menu is shown,
1745      * to notify that the context menu is dismissed.
1746      */
1747     signals[CONTEXT_MENU_DISMISSED] =
1748         g_signal_new("context-menu-dismissed",
1749                      G_TYPE_FROM_CLASS(webViewClass),
1750                      G_SIGNAL_RUN_LAST,
1751                      G_STRUCT_OFFSET(WebKitWebViewClass, context_menu_dismissed),
1752                      0, 0,
1753                      g_cclosure_marshal_VOID__VOID,
1754                      G_TYPE_NONE, 0);
1755
1756     /**
1757      * WebKitWebView::submit-form:
1758      * @web_view: the #WebKitWebView on which the signal is emitted
1759      * @request: a #WebKitFormSubmissionRequest
1760      *
1761      * This signal is emitted when a form is about to be submitted. The @request
1762      * argument passed contains information about the text fields of the form. This
1763      * is typically used to store login information that can be used later to
1764      * pre-fill the form.
1765      * The form will not be submitted until webkit_form_submission_request_submit() is called.
1766      *
1767      * It is possible to handle the form submission request asynchronously, by
1768      * simply calling g_object_ref() on the @request argument and calling
1769      * webkit_form_submission_request_submit() when done to continue with the form submission.
1770      * If the last reference is removed on a #WebKitFormSubmissionRequest and the
1771      * form has not been submitted, webkit_form_submission_request_submit() will be called.
1772      */
1773     signals[SUBMIT_FORM] =
1774         g_signal_new("submit-form",
1775                      G_TYPE_FROM_CLASS(webViewClass),
1776                      G_SIGNAL_RUN_LAST,
1777                      G_STRUCT_OFFSET(WebKitWebViewClass, submit_form),
1778                      0, 0,
1779                      g_cclosure_marshal_VOID__OBJECT,
1780                      G_TYPE_NONE, 1,
1781                      WEBKIT_TYPE_FORM_SUBMISSION_REQUEST);
1782
1783     /**
1784      * WebKitWebView::insecure-content-detected:
1785      * @web_view: the #WebKitWebView on which the signal is emitted
1786      * @event: the #WebKitInsecureContentEvent
1787      *
1788      * This signal is emitted when insecure content has been detected
1789      * in a page loaded through a secure connection. This typically
1790      * means that a external resource from an unstrusted source has
1791      * been run or displayed, resulting in a mix of HTTPS and
1792      * non-HTTPS content.
1793      *
1794      * You can check the @event parameter to know exactly which kind
1795      * of event has been detected (see #WebKitInsecureContentEvent).
1796      */
1797     signals[INSECURE_CONTENT_DETECTED] =
1798         g_signal_new("insecure-content-detected",
1799             G_TYPE_FROM_CLASS(webViewClass),
1800             G_SIGNAL_RUN_LAST,
1801             G_STRUCT_OFFSET(WebKitWebViewClass, insecure_content_detected),
1802             0, 0,
1803             g_cclosure_marshal_VOID__ENUM,
1804             G_TYPE_NONE, 1,
1805             WEBKIT_TYPE_INSECURE_CONTENT_EVENT);
1806
1807 #if PLATFORM(GTK)
1808     /**
1809      * WebKitWebView::web-process-crashed:
1810      * @web_view: the #WebKitWebView
1811      *
1812      * This signal is emitted when the web process crashes.
1813      *
1814      * Returns: %TRUE to stop other handlers from being invoked for the event.
1815      *    %FALSE to propagate the event further.
1816      *
1817      * Deprecated: 2.20: Use WebKitWebView::web-process-terminated instead.
1818      */
1819     signals[WEB_PROCESS_CRASHED] = g_signal_new(
1820         "web-process-crashed",
1821         G_TYPE_FROM_CLASS(webViewClass),
1822         G_SIGNAL_RUN_LAST,
1823         G_STRUCT_OFFSET(WebKitWebViewClass, web_process_crashed),
1824         g_signal_accumulator_true_handled, nullptr,
1825         g_cclosure_marshal_generic,
1826         G_TYPE_BOOLEAN, 0);
1827 #endif
1828
1829     /**
1830      * WebKitWebView::web-process-terminated:
1831      * @web_view: the #WebKitWebView
1832      * @reason: the a #WebKitWebProcessTerminationReason
1833      *
1834      * This signal is emitted when the web process terminates abnormally due
1835      * to @reason.
1836      *
1837      * Since: 2.20
1838      */
1839     signals[WEB_PROCESS_TERMINATED] = g_signal_new(
1840         "web-process-terminated",
1841         G_TYPE_FROM_CLASS(webViewClass),
1842         G_SIGNAL_RUN_LAST,
1843         G_STRUCT_OFFSET(WebKitWebViewClass, web_process_terminated),
1844         0, 0,
1845         g_cclosure_marshal_VOID__ENUM,
1846         G_TYPE_NONE, 1,
1847         WEBKIT_TYPE_WEB_PROCESS_TERMINATION_REASON);
1848
1849     /**
1850      * WebKitWebView::authenticate:
1851      * @web_view: the #WebKitWebView on which the signal is emitted
1852      * @request: a #WebKitAuthenticationRequest
1853      *
1854      * This signal is emitted when the user is challenged with HTTP
1855      * authentication. To let the  application access or supply
1856      * the credentials as well as to allow the client application
1857      * to either cancel the request or perform the authentication,
1858      * the signal will pass an instance of the
1859      * #WebKitAuthenticationRequest in the @request argument.
1860      * To handle this signal asynchronously you should keep a ref
1861      * of the request and return %TRUE. To disable HTTP authentication
1862      * entirely, connect to this signal and simply return %TRUE.
1863      *
1864      * The default signal handler will run a default authentication
1865      * dialog asynchronously for the user to interact with.
1866      *
1867      * Returns: %TRUE to stop other handlers from being invoked for the event.
1868      *   %FALSE to propagate the event further.
1869      *
1870      * Since: 2.2
1871      */
1872     signals[AUTHENTICATE] = g_signal_new(
1873         "authenticate",
1874         G_TYPE_FROM_CLASS(webViewClass),
1875         G_SIGNAL_RUN_LAST,
1876         G_STRUCT_OFFSET(WebKitWebViewClass, authenticate),
1877         g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1878         g_cclosure_marshal_generic,
1879         G_TYPE_BOOLEAN, 1, /* number of parameters */
1880         WEBKIT_TYPE_AUTHENTICATION_REQUEST);
1881
1882     /**
1883      * WebKitWebView::show-notification:
1884      * @web_view: the #WebKitWebView
1885      * @notification: a #WebKitNotification
1886      *
1887      * This signal is emitted when a notification should be presented to the
1888      * user. The @notification is kept alive until either: 1) the web page cancels it
1889      * or 2) a navigation happens.
1890      *
1891      * The default handler will emit a notification using libnotify, if built with
1892      * support for it.
1893      *
1894      * Returns: %TRUE to stop other handlers from being invoked. %FALSE otherwise.
1895      *
1896      * Since: 2.8
1897      */
1898     signals[SHOW_NOTIFICATION] = g_signal_new(
1899         "show-notification",
1900         G_TYPE_FROM_CLASS(gObjectClass),
1901         G_SIGNAL_RUN_LAST,
1902         G_STRUCT_OFFSET(WebKitWebViewClass, show_notification),
1903         g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1904         g_cclosure_marshal_generic,
1905         G_TYPE_BOOLEAN, 1,
1906         WEBKIT_TYPE_NOTIFICATION);
1907
1908 #if PLATFORM(GTK)
1909      /**
1910       * WebKitWebView::run-color-chooser:
1911       * @web_view: the #WebKitWebView on which the signal is emitted
1912       * @request: a #WebKitColorChooserRequest
1913       *
1914       * This signal is emitted when the user interacts with a &lt;input
1915       * type='color' /&gt; HTML element, requesting from WebKit to show
1916       * a dialog to select a color. To let the application know the details of
1917       * the color chooser, as well as to allow the client application to either
1918       * cancel the request or perform an actual color selection, the signal will
1919       * pass an instance of the #WebKitColorChooserRequest in the @request
1920       * argument.
1921       *
1922       * It is possible to handle this request asynchronously by increasing the
1923       * reference count of the request.
1924       *
1925       * The default signal handler will asynchronously run a regular
1926       * #GtkColorChooser for the user to interact with.
1927       *
1928       * Returns: %TRUE to stop other handlers from being invoked for the event.
1929       *   %FALSE to propagate the event further.
1930       *
1931       * Since: 2.8
1932       */
1933     signals[RUN_COLOR_CHOOSER] = g_signal_new(
1934         "run-color-chooser",
1935         G_TYPE_FROM_CLASS(webViewClass),
1936         G_SIGNAL_RUN_LAST,
1937         G_STRUCT_OFFSET(WebKitWebViewClass, run_color_chooser),
1938         g_signal_accumulator_true_handled, nullptr,
1939         g_cclosure_marshal_generic,
1940         G_TYPE_BOOLEAN, 1,
1941         WEBKIT_TYPE_COLOR_CHOOSER_REQUEST);
1942
1943     /**
1944      * WebKitWebView::show-option-menu:
1945      * @web_view: the #WebKitWebView on which the signal is emitted
1946      * @menu: the #WebKitOptionMenu
1947      * @event: the #GdkEvent that triggered the menu, or %NULL
1948      * @rectangle: the option element area
1949      *
1950      * This signal is emitted when a select element in @web_view needs to display a
1951      * dropdown menu. This signal can be used to show a custom menu, using @menu to get
1952      * the details of all items that should be displayed. The area of the element in the
1953      * #WebKitWebView is given as @rectangle parameter, it can be used to position the
1954      * menu. If this was triggered by a user interaction, like a mouse click,
1955      * @event parameter provides the #GdkEvent.
1956      * To handle this signal asynchronously you should keep a ref of the @menu.
1957      *
1958      * The default signal handler will pop up a #GtkMenu.
1959      *
1960      * Returns: %TRUE to stop other handlers from being invoked for the event.
1961      *   %FALSE to propagate the event further.
1962      *
1963      * Since: 2.18
1964      */
1965     signals[SHOW_OPTION_MENU] = g_signal_new(
1966         "show-option-menu",
1967         G_TYPE_FROM_CLASS(webViewClass),
1968         G_SIGNAL_RUN_LAST,
1969         G_STRUCT_OFFSET(WebKitWebViewClass, show_option_menu),
1970         g_signal_accumulator_true_handled, nullptr,
1971         g_cclosure_marshal_generic,
1972         G_TYPE_BOOLEAN, 3,
1973         WEBKIT_TYPE_OPTION_MENU,
1974         GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1975         GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
1976 #endif // PLATFORM(GTK)
1977 }
1978
1979 static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)
1980 {
1981     if (!webView->priv->authenticationRequest)
1982         return;
1983
1984     webkit_authentication_request_cancel(webView->priv->authenticationRequest.get());
1985     webView->priv->authenticationRequest.clear();
1986 }
1987
1988 void webkitWebViewCreatePage(WebKitWebView* webView, Ref<API::PageConfiguration>&& configuration)
1989 {
1990 #if PLATFORM(GTK)
1991     webkitWebViewBaseCreateWebPage(WEBKIT_WEB_VIEW_BASE(webView), WTFMove(configuration));
1992 #elif PLATFORM(WPE)
1993     webView->priv->view.reset(WKWPE::View::create(webkit_web_view_backend_get_wpe_backend(webView->priv->backend.get()), configuration.get()));
1994 #endif
1995 }
1996
1997 WebPageProxy& webkitWebViewGetPage(WebKitWebView* webView)
1998 {
1999     return getPage(webView);
2000 }
2001
2002 void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
2003 {
2004     WebKitWebViewPrivate* priv = webView->priv;
2005     switch (loadEvent) {
2006     case WEBKIT_LOAD_STARTED:
2007 #if PLATFORM(GTK)
2008         webkitWebViewCancelFaviconRequest(webView);
2009         webkitWebViewWatchForChangesInFavicon(webView);
2010 #endif
2011         webkitWebViewCancelAuthenticationRequest(webView);
2012         priv->loadingResourcesMap.clear();
2013         priv->mainResource = nullptr;
2014         break;
2015 #if PLATFORM(GTK)
2016     case WEBKIT_LOAD_COMMITTED: {
2017         WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
2018         GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data()));
2019         webkitWebViewUpdateFaviconURI(webView, faviconURI.get());
2020         break;
2021     }
2022 #endif
2023     case WEBKIT_LOAD_FINISHED:
2024         webkitWebViewCancelAuthenticationRequest(webView);
2025         break;
2026     default:
2027         break;
2028     }
2029
2030     g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent);
2031 }
2032
2033 void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error)
2034 {
2035     webkitWebViewCancelAuthenticationRequest(webView);
2036
2037     gboolean returnValue;
2038     g_signal_emit(webView, signals[LOAD_FAILED], 0, loadEvent, failingURI, error, &returnValue);
2039     g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
2040 }
2041
2042 void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError* error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate)
2043 {
2044     webkitWebViewCancelAuthenticationRequest(webView);
2045
2046     WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context.get());
2047     if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) {
2048         gboolean returnValue;
2049         g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, failingURI, certificate, tlsErrors, &returnValue);
2050         if (!returnValue)
2051             g_signal_emit(webView, signals[LOAD_FAILED], 0, WEBKIT_LOAD_STARTED, failingURI, error, &returnValue);
2052     }
2053
2054     g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
2055 }
2056
2057 #if PLATFORM(GTK)
2058 void webkitWebViewGetLoadDecisionForIcon(WebKitWebView* webView, const LinkIcon& icon, Function<void(bool)>&& completionHandler)
2059 {
2060     WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
2061     webkitFaviconDatabaseGetLoadDecisionForIcon(database, icon, getPage(webView).pageLoadState().activeURL(), WTFMove(completionHandler));
2062 }
2063
2064 void webkitWebViewSetIcon(WebKitWebView* webView, const LinkIcon& icon, API::Data& iconData)
2065 {
2066     WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
2067     webkitFaviconDatabaseSetIconForPageURL(database, icon, iconData, getPage(webView).pageLoadState().activeURL());
2068 }
2069 #endif
2070
2071 WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, const WindowFeatures& windowFeatures, WebKitNavigationAction* navigationAction)
2072 {
2073     WebKitWebView* newWebView;
2074     g_signal_emit(webView, signals[CREATE], 0, navigationAction, &newWebView);
2075     if (!newWebView)
2076         return 0;
2077
2078     webkitWindowPropertiesUpdateFromWebWindowFeatures(newWebView->priv->windowProperties.get(), windowFeatures);
2079
2080     RefPtr<WebPageProxy> newPage = &getPage(newWebView);
2081     return newPage.leakRef();
2082 }
2083
2084 void webkitWebViewReadyToShowPage(WebKitWebView* webView)
2085 {
2086     g_signal_emit(webView, signals[READY_TO_SHOW], 0, NULL);
2087 }
2088
2089 void webkitWebViewRunAsModal(WebKitWebView* webView)
2090 {
2091     g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL);
2092
2093     webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE));
2094
2095 #if PLATFORM(GTK)
2096 // This is to suppress warnings about gdk_threads_leave and gdk_threads_enter.
2097     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
2098     gdk_threads_leave();
2099 #endif
2100
2101     g_main_loop_run(webView->priv->modalLoop.get());
2102
2103 #if PLATFORM(GTK)
2104     gdk_threads_enter();
2105     ALLOW_DEPRECATED_DECLARATIONS_END
2106 #endif
2107 }
2108
2109 void webkitWebViewClosePage(WebKitWebView* webView)
2110 {
2111     g_signal_emit(webView, signals[CLOSE], 0, NULL);
2112 }
2113
2114 void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message, Function<void()>&& completionHandler)
2115 {
2116     ASSERT(!webView->priv->currentScriptDialog);
2117     webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_ALERT, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool, const String&) {
2118         completionHandler();
2119         webView->priv->currentScriptDialog = nullptr;
2120     });
2121     gboolean returnValue;
2122     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
2123     webkit_script_dialog_unref(webView->priv->currentScriptDialog);
2124 }
2125
2126 void webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message, Function<void(bool)>&& completionHandler)
2127 {
2128     ASSERT(!webView->priv->currentScriptDialog);
2129     webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_CONFIRM, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool result, const String&) {
2130         completionHandler(result);
2131         webView->priv->currentScriptDialog = nullptr;
2132     });
2133     gboolean returnValue;
2134     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
2135     webkit_script_dialog_unref(webView->priv->currentScriptDialog);
2136 }
2137
2138 void webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText, Function<void(const String&)>&& completionHandler)
2139 {
2140     ASSERT(!webView->priv->currentScriptDialog);
2141     webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText, [webView, completionHandler = WTFMove(completionHandler)](bool, const String& result) {
2142         completionHandler(result);
2143         webView->priv->currentScriptDialog = nullptr;
2144     });
2145     gboolean returnValue;
2146     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
2147     webkit_script_dialog_unref(webView->priv->currentScriptDialog);
2148 }
2149
2150 void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message, Function<void(bool)>&& completionHandler)
2151 {
2152     ASSERT(!webView->priv->currentScriptDialog);
2153     webView->priv->currentScriptDialog = webkitScriptDialogCreate(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message, { }, [webView, completionHandler = WTFMove(completionHandler)](bool result, const String&) {
2154         completionHandler(result);
2155         webView->priv->currentScriptDialog = nullptr;
2156     });
2157     gboolean returnValue;
2158     g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, webView->priv->currentScriptDialog, &returnValue);
2159     webkit_script_dialog_unref(webView->priv->currentScriptDialog);
2160 }
2161
2162 bool webkitWebViewIsShowingScriptDialog(WebKitWebView* webView)
2163 {
2164     if (!webView->priv->currentScriptDialog)
2165         return false;
2166
2167     // FIXME: Add API to ask the user in case default implementation is not being used.
2168     return webkitScriptDialogIsRunning(webView->priv->currentScriptDialog);
2169 }
2170
2171 String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView* webView)
2172 {
2173     if (!webView->priv->currentScriptDialog)
2174         return { };
2175
2176     return String::fromUTF8(webView->priv->currentScriptDialog->message);
2177 }
2178
2179 void webkitWebViewSetCurrentScriptDialogUserInput(WebKitWebView* webView, const String& userInput)
2180 {
2181     if (!webView->priv->currentScriptDialog)
2182         return;
2183
2184     // FIXME: Add API to ask the user in case default implementation is not being used.
2185     if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2186         webkitScriptDialogSetUserInput(webView->priv->currentScriptDialog, userInput);
2187 }
2188
2189 void webkitWebViewAcceptCurrentScriptDialog(WebKitWebView* webView)
2190 {
2191     if (!webView->priv->currentScriptDialog)
2192         return;
2193
2194     // FIXME: Add API to ask the user in case default implementation is not being used.
2195     if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2196         webkitScriptDialogAccept(webView->priv->currentScriptDialog);
2197 }
2198
2199 void webkitWebViewDismissCurrentScriptDialog(WebKitWebView* webView)
2200 {
2201     if (!webView->priv->currentScriptDialog)
2202         return;
2203
2204     // FIXME: Add API to ask the user in case default implementation is not being used.
2205     if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2206         webkitScriptDialogDismiss(webView->priv->currentScriptDialog);
2207 }
2208
2209 std::optional<WebKitScriptDialogType> webkitWebViewGetCurrentScriptDialogType(WebKitWebView* webView)
2210 {
2211     if (!webView->priv->currentScriptDialog)
2212         return std::nullopt;
2213
2214     return static_cast<WebKitScriptDialogType>(webView->priv->currentScriptDialog->type);
2215 }
2216
2217 void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
2218 {
2219     gboolean returnValue;
2220     g_signal_emit(webView, signals[DECIDE_POLICY], 0, decision, type, &returnValue);
2221 }
2222
2223 void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermissionRequest* request)
2224 {
2225     gboolean returnValue;
2226     g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue);
2227 }
2228
2229 void webkitWebViewMouseTargetChanged(WebKitWebView* webView, const WebHitTestResultData& hitTestResult, WebEvent::Modifiers modifiers)
2230 {
2231 #if PLATFORM(GTK)
2232     webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult.elementBoundingBox);
2233 #endif
2234
2235     WebKitWebViewPrivate* priv = webView->priv;
2236     if (priv->mouseTargetHitTestResult
2237         && priv->mouseTargetModifiers == modifiers
2238         && webkitHitTestResultCompare(priv->mouseTargetHitTestResult.get(), hitTestResult))
2239         return;
2240
2241     priv->mouseTargetModifiers = modifiers;
2242     priv->mouseTargetHitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResult));
2243     g_signal_emit(webView, signals[MOUSE_TARGET_CHANGED], 0, priv->mouseTargetHitTestResult.get(), toPlatformModifiers(modifiers));
2244 }
2245
2246 void webkitWebViewHandleDownloadRequest(WebKitWebView* webView, DownloadProxy* downloadProxy)
2247 {
2248     ASSERT(downloadProxy);
2249     GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy);
2250     webkitDownloadSetWebView(download.get(), webView);
2251 }
2252
2253 #if PLATFORM(GTK)
2254 void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame)
2255 {
2256     auto printOperation = adoptGRef(webkit_print_operation_new(webView));
2257     webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync);
2258     gboolean returnValue;
2259     g_signal_emit(webView, signals[PRINT], 0, printOperation.get(), &returnValue);
2260     if (returnValue)
2261         return;
2262
2263     WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, frame);
2264     if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL)
2265         return;
2266     g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
2267 }
2268 #endif
2269
2270 void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request)
2271 {
2272     WebKitWebViewPrivate* priv = webView->priv;
2273     bool isMainResource = frame->isMainFrame() && !priv->mainResource;
2274     WebKitWebResource* resource = webkitWebResourceCreate(frame, request, isMainResource);
2275     if (isMainResource)
2276         priv->mainResource = resource;
2277     priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
2278     g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
2279 }
2280
2281 WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2282 {
2283     GRefPtr<WebKitWebResource> resource = webView->priv->loadingResourcesMap.get(resourceIdentifier);
2284     return resource.get();
2285 }
2286
2287 void webkitWebViewRemoveLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2288 {
2289     WebKitWebViewPrivate* priv = webView->priv;
2290     ASSERT(priv->loadingResourcesMap.contains(resourceIdentifier));
2291     priv->loadingResourcesMap.remove(resourceIdentifier);
2292 }
2293
2294 void webkitWebViewEnterFullScreen(WebKitWebView* webView)
2295 {
2296 #if ENABLE(FULLSCREEN_API)
2297     gboolean returnValue;
2298     g_signal_emit(webView, signals[ENTER_FULLSCREEN], 0, &returnValue);
2299 #if PLATFORM(GTK)
2300     if (!returnValue)
2301         webkitWebViewBaseEnterFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2302 #endif
2303 #endif
2304 }
2305
2306 void webkitWebViewExitFullScreen(WebKitWebView* webView)
2307 {
2308 #if ENABLE(FULLSCREEN_API)
2309     gboolean returnValue;
2310     g_signal_emit(webView, signals[LEAVE_FULLSCREEN], 0, &returnValue);
2311 #if PLATFORM(GTK)
2312     if (!returnValue)
2313         webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2314 #endif
2315 #endif
2316 }
2317
2318 void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChooserRequest* request)
2319 {
2320     gboolean returnValue;
2321     g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
2322 }
2323
2324 #if PLATFORM(GTK)
2325 static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView)
2326 {
2327     g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL);
2328 }
2329
2330 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2331 {
2332     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
2333     WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase);
2334     ASSERT(contextMenuProxy);
2335
2336     GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2337     if (userData)
2338         webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2339
2340     GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2341     GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase));
2342     gboolean returnValue;
2343     g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue);
2344     if (returnValue)
2345         return;
2346
2347     Vector<WebContextMenuItemGlib> contextMenuItems;
2348     webkitContextMenuPopulate(contextMenu.get(), contextMenuItems);
2349     contextMenuProxy->populate(contextMenuItems);
2350
2351     g_signal_connect(contextMenuProxy->gtkMenu(), "deactivate", G_CALLBACK(contextMenuDismissed), webView);
2352
2353     // Clear the menu to make sure it's useless after signal emission.
2354     webkit_context_menu_remove_all(contextMenu.get());
2355 }
2356 #elif PLATFORM(WPE)
2357 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2358 {
2359     GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2360     if (userData)
2361         webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2362     GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2363     gboolean returnValue;
2364     g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), nullptr, hitTestResult.get(), &returnValue);
2365 }
2366 #endif
2367
2368 void webkitWebViewSubmitFormRequest(WebKitWebView* webView, WebKitFormSubmissionRequest* request)
2369 {
2370     g_signal_emit(webView, signals[SUBMIT_FORM], 0, request);
2371 }
2372
2373 void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge)
2374 {
2375 #if PLATFORM(GTK)
2376     G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2377     gboolean privateBrowsingEnabled = webView->priv->isEphemeral || webkit_settings_get_enable_private_browsing(webView->priv->settings.get());
2378     G_GNUC_END_IGNORE_DEPRECATIONS;
2379 #else
2380     gboolean privateBrowsingEnabled = webView->priv->isEphemeral;
2381 #endif
2382     webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled));
2383     gboolean returnValue;
2384     g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue);
2385 }
2386
2387 void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecureContentEvent type)
2388 {
2389     g_signal_emit(webView, signals[INSECURE_CONTENT_DETECTED], 0, type);
2390 }
2391
2392 bool webkitWebViewEmitShowNotification(WebKitWebView* webView, WebKitNotification* webNotification)
2393 {
2394     gboolean handled;
2395     g_signal_emit(webView, signals[SHOW_NOTIFICATION], 0, webNotification, &handled);
2396     return handled;
2397 }
2398
2399 #if PLATFORM(GTK)
2400 bool webkitWebViewEmitRunColorChooser(WebKitWebView* webView, WebKitColorChooserRequest* request)
2401 {
2402     gboolean handled;
2403     g_signal_emit(webView, signals[RUN_COLOR_CHOOSER], 0, request, &handled);
2404     return handled;
2405 }
2406 #endif
2407
2408 void webkitWebViewSelectionDidChange(WebKitWebView* webView)
2409 {
2410     if (!webView->priv->editorState)
2411         return;
2412
2413     webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView).editorState());
2414 }
2415
2416 void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView* webView, InstallMissingMediaPluginsPermissionRequest& request)
2417 {
2418 #if ENABLE(VIDEO)
2419     GRefPtr<WebKitInstallMissingMediaPluginsPermissionRequest> installMediaPluginsPermissionRequest = adoptGRef(webkitInstallMissingMediaPluginsPermissionRequestCreate(request));
2420     webkitWebViewMakePermissionRequest(webView, WEBKIT_PERMISSION_REQUEST(installMediaPluginsPermissionRequest.get()));
2421 #else
2422     ASSERT_NOT_REACHED();
2423 #endif
2424 }
2425
2426 WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webView)
2427 {
2428     return webView->priv->websiteDataManager.get();
2429 }
2430
2431 #if PLATFORM(GTK)
2432 bool webkitWebViewShowOptionMenu(WebKitWebView* webView, const IntRect& rect, WebKitOptionMenu* menu, const GdkEvent* event)
2433 {
2434     GdkRectangle menuRect = rect;
2435     gboolean handled;
2436     g_signal_emit(webView, signals[SHOW_OPTION_MENU], 0, menu, event, &menuRect, &handled);
2437     return handled;
2438 }
2439 #endif
2440
2441 #if PLATFORM(WPE)
2442 /**
2443  * webkit_web_view_get_backend:
2444  * @web_view: a #WebKitWebView
2445  *
2446  * Get the #WebKitWebViewBackend of @web_view
2447  *
2448  * Returns: (transfer none): the #WebKitWebViewBackend of @web_view
2449  *
2450  * Since: 2.20
2451  */
2452 WebKitWebViewBackend* webkit_web_view_get_backend(WebKitWebView* webView)
2453 {
2454     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2455
2456     return webView->priv->backend.get();
2457 }
2458 #endif
2459
2460 /**
2461  * webkit_web_view_get_context:
2462  * @web_view: a #WebKitWebView
2463  *
2464  * Gets the web context of @web_view.
2465  *
2466  * Returns: (transfer none): the #WebKitWebContext of the view
2467  */
2468 WebKitWebContext* webkit_web_view_get_context(WebKitWebView *webView)
2469 {
2470     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2471
2472     return webView->priv->context.get();
2473 }
2474
2475 /**
2476  * webkit_web_view_get_user_content_manager:
2477  * @web_view: a #WebKitWebView
2478  *
2479  * Gets the user content manager associated to @web_view.
2480  *
2481  * Returns: (transfer none): the #WebKitUserContentManager associated with the view
2482  *
2483  * Since: 2.6
2484  */
2485 WebKitUserContentManager* webkit_web_view_get_user_content_manager(WebKitWebView* webView)
2486 {
2487     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2488
2489     return webView->priv->userContentManager.get();
2490 }
2491
2492 /**
2493  * webkit_web_view_is_ephemeral:
2494  * @web_view: a #WebKitWebView
2495  *
2496  * Get whether a #WebKitWebView is ephemeral. To create an ephemeral #WebKitWebView you need to
2497  * use g_object_new() and pass is-ephemeral property with %TRUE value. See
2498  * #WebKitWebView:is-ephemeral for more details.
2499  * If @web_view was created with a ephemeral #WebKitWebView:related-view or an
2500  * ephemeral #WebKitWebView:web-context it will also be ephemeral.
2501  *
2502  * Returns: %TRUE if @web_view is ephemeral or %FALSE otherwise.
2503  *
2504  * Since: 2.16
2505  */
2506 gboolean webkit_web_view_is_ephemeral(WebKitWebView* webView)
2507 {
2508     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2509
2510     return webView->priv->isEphemeral;
2511 }
2512
2513 /**
2514  * webkit_web_view_is_controlled_by_automation:
2515  * @web_view: a #WebKitWebView
2516  *
2517  * Get whether a #WebKitWebView was created with #WebKitWebView:is-controlled-by-automation
2518  * property enabled. Only #WebKitWebView<!-- -->s controlled by automation can be used in an
2519  * automation session.
2520  *
2521  * Returns: %TRUE if @web_view is controlled by automation, or %FALSE otherwise.
2522  *
2523  * Since: 2.18
2524  */
2525 gboolean webkit_web_view_is_controlled_by_automation(WebKitWebView* webView)
2526 {
2527     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2528
2529     return webView->priv->isControlledByAutomation;
2530 }
2531
2532 /**
2533  * webkit_web_view_get_website_data_manager:
2534  * @web_view: a #WebKitWebView
2535  *
2536  * Get the #WebKitWebsiteDataManager associated to @web_view. If @web_view is not ephemeral,
2537  * the returned #WebKitWebsiteDataManager will be the same as the #WebKitWebsiteDataManager
2538  * of @web_view's #WebKitWebContext.
2539  *
2540  * Returns: (transfer none): a #WebKitWebsiteDataManager
2541  *
2542  * Since: 2.16
2543  */
2544 WebKitWebsiteDataManager* webkit_web_view_get_website_data_manager(WebKitWebView* webView)
2545 {
2546     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2547
2548     if (webView->priv->websiteDataManager)
2549         return webView->priv->websiteDataManager.get();
2550
2551     return webkit_web_context_get_website_data_manager(webView->priv->context.get());
2552 }
2553
2554 /**
2555  * webkit_web_view_try_close:
2556  * @web_view: a #WebKitWebView
2557  *
2558  * Tries to close the @web_view. This will fire the onbeforeunload event
2559  * to ask the user for confirmation to close the page. If there isn't an
2560  * onbeforeunload event handler or the user confirms to close the page,
2561  * the #WebKitWebView::close signal is emitted, otherwise nothing happens.
2562  *
2563  * Since: 2.12
2564  */
2565 void webkit_web_view_try_close(WebKitWebView *webView)
2566 {
2567     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2568     if (getPage(webView).tryClose())
2569         webkitWebViewClosePage(webView);
2570 }
2571
2572 /**
2573  * webkit_web_view_load_uri:
2574  * @web_view: a #WebKitWebView
2575  * @uri: an URI string
2576  *
2577  * Requests loading of the specified URI string.
2578  * You can monitor the load operation by connecting to
2579  * #WebKitWebView::load-changed signal.
2580  */
2581 void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri)
2582 {
2583     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2584     g_return_if_fail(uri);
2585
2586     GUniquePtr<SoupURI> soupURI(soup_uri_new(uri));
2587     getPage(webView).loadRequest(URL(soupURI.get()));
2588 }
2589
2590 /**
2591  * webkit_web_view_load_html:
2592  * @web_view: a #WebKitWebView
2593  * @content: The HTML string to load
2594  * @base_uri: (allow-none): The base URI for relative locations or %NULL
2595  *
2596  * Load the given @content string with the specified @base_uri.
2597  * If @base_uri is not %NULL, relative URLs in the @content will be
2598  * resolved against @base_uri and absolute local paths must be children of the @base_uri.
2599  * For security reasons absolute local paths that are not children of @base_uri
2600  * will cause the web process to terminate.
2601  * If you need to include URLs in @content that are local paths in a different
2602  * directory than @base_uri you can build a data URI for them. When @base_uri is %NULL,
2603  * it defaults to "about:blank". The mime type of the document will be "text/html".
2604  * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2605  */
2606 void webkit_web_view_load_html(WebKitWebView* webView, const gchar* content, const gchar* baseURI)
2607 {
2608     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2609     g_return_if_fail(content);
2610
2611     getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(content), content ? strlen(content) : 0 }, "text/html"_s, "UTF-8"_s, String::fromUTF8(baseURI));
2612 }
2613
2614 /**
2615  * webkit_web_view_load_alternate_html:
2616  * @web_view: a #WebKitWebView
2617  * @content: the new content to display as the main page of the @web_view
2618  * @content_uri: the URI for the alternate page content
2619  * @base_uri: (allow-none): the base URI for relative locations or %NULL
2620  *
2621  * Load the given @content string for the URI @content_uri.
2622  * This allows clients to display page-loading errors in the #WebKitWebView itself.
2623  * When this method is called from #WebKitWebView::load-failed signal to show an
2624  * error page, then the back-forward list is maintained appropriately.
2625  * For everything else this method works the same way as webkit_web_view_load_html().
2626  */
2627 void webkit_web_view_load_alternate_html(WebKitWebView* webView, const gchar* content, const gchar* contentURI, const gchar* baseURI)
2628 {
2629     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2630     g_return_if_fail(content);
2631     g_return_if_fail(contentURI);
2632
2633     getPage(webView).loadAlternateHTML({ reinterpret_cast<const uint8_t*>(content), content ? strlen(content) : 0 }, "UTF-8"_s, URL(URL(), String::fromUTF8(baseURI)), URL(URL(), String::fromUTF8(contentURI)));
2634 }
2635
2636 /**
2637  * webkit_web_view_load_plain_text:
2638  * @web_view: a #WebKitWebView
2639  * @plain_text: The plain text to load
2640  *
2641  * Load the specified @plain_text string into @web_view. The mime type of
2642  * document will be "text/plain". You can monitor the load
2643  * operation by connecting to #WebKitWebView::load-changed signal.
2644  */
2645 void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainText)
2646 {
2647     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2648     g_return_if_fail(plainText);
2649
2650     getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(plainText), plainText ? strlen(plainText) : 0 }, "text/plain"_s, "UTF-8"_s, WTF::blankURL().string());
2651 }
2652
2653 /**
2654  * webkit_web_view_load_bytes:
2655  * @web_view: a #WebKitWebView
2656  * @bytes: input data to load
2657  * @mime_type: (allow-none): the MIME type of @bytes, or %NULL
2658  * @encoding: (allow-none): the character encoding of @bytes, or %NULL
2659  * @base_uri: (allow-none): the base URI for relative locations or %NULL
2660  *
2661  * Load the specified @bytes into @web_view using the given @mime_type and @encoding.
2662  * When @mime_type is %NULL, it defaults to "text/html".
2663  * When @encoding is %NULL, it defaults to "UTF-8".
2664  * When @base_uri is %NULL, it defaults to "about:blank".
2665  * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2666  *
2667  * Since: 2.6
2668  */
2669 void webkit_web_view_load_bytes(WebKitWebView* webView, GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI)
2670 {
2671     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2672     g_return_if_fail(bytes);
2673
2674     gsize bytesDataSize;
2675     gconstpointer bytesData = g_bytes_get_data(bytes, &bytesDataSize);
2676     g_return_if_fail(bytesDataSize);
2677
2678     getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(bytesData), bytesDataSize }, mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
2679         encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), String::fromUTF8(baseURI));
2680 }
2681
2682 /**
2683  * webkit_web_view_load_request:
2684  * @web_view: a #WebKitWebView
2685  * @request: a #WebKitURIRequest to load
2686  *
2687  * Requests loading of the specified #WebKitURIRequest.
2688  * You can monitor the load operation by connecting to
2689  * #WebKitWebView::load-changed signal.
2690  */
2691 void webkit_web_view_load_request(WebKitWebView* webView, WebKitURIRequest* request)
2692 {
2693     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2694     g_return_if_fail(WEBKIT_IS_URI_REQUEST(request));
2695
2696     ResourceRequest resourceRequest;
2697     webkitURIRequestGetResourceRequest(request, resourceRequest);
2698     getPage(webView).loadRequest(WTFMove(resourceRequest));
2699 }
2700
2701 /**
2702  * webkit_web_view_get_page_id:
2703  * @web_view: a #WebKitWebView
2704  *
2705  * Get the identifier of the #WebKitWebPage corresponding to
2706  * the #WebKitWebView
2707  *
2708  * Returns: the page ID of @web_view.
2709  */
2710 guint64 webkit_web_view_get_page_id(WebKitWebView* webView)
2711 {
2712     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2713
2714     return getPage(webView).pageID();
2715 }
2716
2717 /**
2718  * webkit_web_view_get_title:
2719  * @web_view: a #WebKitWebView
2720  *
2721  * Gets the value of the #WebKitWebView:title property.
2722  * You can connect to notify::title signal of @web_view to
2723  * be notified when the title has been received.
2724  *
2725  * Returns: The main frame document title of @web_view.
2726  */
2727 const gchar* webkit_web_view_get_title(WebKitWebView* webView)
2728 {
2729     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2730
2731     return webView->priv->title.data();
2732 }
2733
2734 /**
2735  * webkit_web_view_reload:
2736  * @web_view: a #WebKitWebView
2737  *
2738  * Reloads the current contents of @web_view.
2739  * See also webkit_web_view_reload_bypass_cache().
2740  */
2741 void webkit_web_view_reload(WebKitWebView* webView)
2742 {
2743     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2744
2745     getPage(webView).reload({ });
2746 }
2747
2748 /**
2749  * webkit_web_view_reload_bypass_cache:
2750  * @web_view: a #WebKitWebView
2751  *
2752  * Reloads the current contents of @web_view without
2753  * using any cached data.
2754  */
2755 void webkit_web_view_reload_bypass_cache(WebKitWebView* webView)
2756 {
2757     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2758
2759     getPage(webView).reload(ReloadOption::FromOrigin);
2760 }
2761
2762 /**
2763  * webkit_web_view_stop_loading:
2764  * @web_view: a #WebKitWebView
2765  *
2766  * Stops any ongoing loading operation in @web_view.
2767  * This method does nothing if no content is being loaded.
2768  * If there is a loading operation in progress, it will be cancelled and
2769  * #WebKitWebView::load-failed signal will be emitted with
2770  * %WEBKIT_NETWORK_ERROR_CANCELLED error.
2771  */
2772 void webkit_web_view_stop_loading(WebKitWebView* webView)
2773 {
2774     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2775
2776     getPage(webView).stopLoading();
2777 }
2778
2779 /**
2780  * webkit_web_view_is_loading:
2781  * @web_view: a #WebKitWebView
2782  *
2783  * Gets the value of the #WebKitWebView:is-loading property.
2784  * You can monitor when a #WebKitWebView is loading a page by connecting to
2785  * notify::is-loading signal of @web_view. This is useful when you are
2786  * interesting in knowing when the view is loading something but not in the
2787  * details about the status of the load operation, for example to start a spinner
2788  * when the view is loading a page and stop it when it finishes.
2789  *
2790  * Returns: %TRUE if @web_view is loading a page or %FALSE otherwise.
2791  */
2792 gboolean webkit_web_view_is_loading(WebKitWebView* webView)
2793 {
2794     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2795
2796     return webView->priv->isLoading;
2797 }
2798
2799 /**
2800  * webkit_web_view_is_playing_audio:
2801  * @web_view: a #WebKitWebView
2802  *
2803  * Gets the value of the #WebKitWebView:is-playing-audio property.
2804  * You can monitor when a page in a #WebKitWebView is playing audio by
2805  * connecting to the notify::is-playing-audio signal of @web_view. This
2806  * is useful when the application wants to provide visual feedback when a
2807  * page is producing sound.
2808  *
2809  * Returns: %TRUE if a page in @web_view is playing audio or %FALSE otherwise.
2810  *
2811  * Since: 2.8
2812  */
2813 gboolean webkit_web_view_is_playing_audio(WebKitWebView* webView)
2814 {
2815     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2816
2817     return getPage(webView).isPlayingAudio();
2818 }
2819
2820 /**
2821  * webkit_web_view_go_back:
2822  * @web_view: a #WebKitWebView
2823  *
2824  * Loads the previous history item.
2825  * You can monitor the load operation by connecting to
2826  * #WebKitWebView::load-changed signal.
2827  */
2828 void webkit_web_view_go_back(WebKitWebView* webView)
2829 {
2830     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2831
2832     getPage(webView).goBack();
2833 }
2834
2835 /**
2836  * webkit_web_view_can_go_back:
2837  * @web_view: a #WebKitWebView
2838  *
2839  * Determines whether @web_view has a previous history item.
2840  *
2841  * Returns: %TRUE if able to move back or %FALSE otherwise.
2842  */
2843 gboolean webkit_web_view_can_go_back(WebKitWebView* webView)
2844 {
2845     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2846
2847     return !!getPage(webView).backForwardList().backItem();
2848 }
2849
2850 /**
2851  * webkit_web_view_go_forward:
2852  * @web_view: a #WebKitWebView
2853  *
2854  * Loads the next history item.
2855  * You can monitor the load operation by connecting to
2856  * #WebKitWebView::load-changed signal.
2857  */
2858 void webkit_web_view_go_forward(WebKitWebView* webView)
2859 {
2860     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2861
2862     getPage(webView).goForward();
2863 }
2864
2865 /**
2866  * webkit_web_view_can_go_forward:
2867  * @web_view: a #WebKitWebView
2868  *
2869  * Determines whether @web_view has a next history item.
2870  *
2871  * Returns: %TRUE if able to move forward or %FALSE otherwise.
2872  */
2873 gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
2874 {
2875     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2876
2877     return !!getPage(webView).backForwardList().forwardItem();
2878 }
2879
2880 /**
2881  * webkit_web_view_get_uri:
2882  * @web_view: a #WebKitWebView
2883  *
2884  * Returns the current active URI of @web_view. The active URI might change during
2885  * a load operation:
2886  *
2887  * <orderedlist>
2888  * <listitem><para>
2889  *   When nothing has been loaded yet on @web_view the active URI is %NULL.
2890  * </para></listitem>
2891  * <listitem><para>
2892  *   When a new load operation starts the active URI is the requested URI:
2893  *   <itemizedlist>
2894  *   <listitem><para>
2895  *     If the load operation was started by webkit_web_view_load_uri(),
2896  *     the requested URI is the given one.
2897  *   </para></listitem>
2898  *   <listitem><para>
2899  *     If the load operation was started by webkit_web_view_load_html(),
2900  *     the requested URI is "about:blank".
2901  *   </para></listitem>
2902  *   <listitem><para>
2903  *     If the load operation was started by webkit_web_view_load_alternate_html(),
2904  *     the requested URI is content URI provided.
2905  *   </para></listitem>
2906  *   <listitem><para>
2907  *     If the load operation was started by webkit_web_view_go_back() or
2908  *     webkit_web_view_go_forward(), the requested URI is the original URI
2909  *     of the previous/next item in the #WebKitBackForwardList of @web_view.
2910  *   </para></listitem>
2911  *   <listitem><para>
2912  *     If the load operation was started by
2913  *     webkit_web_view_go_to_back_forward_list_item(), the requested URI
2914  *     is the opriginal URI of the given #WebKitBackForwardListItem.
2915  *   </para></listitem>
2916  *   </itemizedlist>
2917  * </para></listitem>
2918  * <listitem><para>
2919  *   If there is a server redirection during the load operation,
2920  *   the active URI is the redirected URI. When the signal
2921  *   #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_REDIRECTED
2922  *   event, the active URI is already updated to the redirected URI.
2923  * </para></listitem>
2924  * <listitem><para>
2925  *   When the signal #WebKitWebView::load-changed is emitted
2926  *   with %WEBKIT_LOAD_COMMITTED event, the active URI is the final
2927  *   one and it will not change unless a new load operation is started
2928  *   or a navigation action within the same page is performed.
2929  * </para></listitem>
2930  * </orderedlist>
2931  *
2932  * You can monitor the active URI by connecting to the notify::uri
2933  * signal of @web_view.
2934  *
2935  * Returns: the current active URI of @web_view or %NULL
2936  *    if nothing has been loaded yet.
2937  */
2938 const gchar* webkit_web_view_get_uri(WebKitWebView* webView)
2939 {
2940     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2941
2942     return webView->priv->activeURI.data();
2943 }
2944
2945 #if PLATFORM(GTK)
2946 /**
2947  * webkit_web_view_get_favicon:
2948  * @web_view: a #WebKitWebView
2949  *
2950  * Returns favicon currently associated to @web_view, if any. You can
2951  * connect to notify::favicon signal of @web_view to be notified when
2952  * the favicon is available.
2953  *
2954  * Returns: (transfer none): a pointer to a #cairo_surface_t with the
2955  *    favicon or %NULL if there's no icon associated with @web_view.
2956  */
2957 cairo_surface_t* webkit_web_view_get_favicon(WebKitWebView* webView)
2958 {
2959     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2960     if (webView->priv->activeURI.isNull())
2961         return 0;
2962
2963     return webView->priv->favicon.get();
2964 }
2965 #endif
2966
2967 /**
2968  * webkit_web_view_get_custom_charset:
2969  * @web_view: a #WebKitWebView
2970  *
2971  * Returns the current custom character encoding name of @web_view.
2972  *
2973  * Returns: the current custom character encoding name or %NULL if no
2974  *    custom character encoding has been set.
2975  */
2976 const gchar* webkit_web_view_get_custom_charset(WebKitWebView* webView)
2977 {
2978     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2979
2980     String customTextEncoding = getPage(webView).customTextEncodingName();
2981     if (customTextEncoding.isEmpty())
2982         return 0;
2983
2984     webView->priv->customTextEncoding = customTextEncoding.utf8();
2985     return webView->priv->customTextEncoding.data();
2986 }
2987
2988 /**
2989  * webkit_web_view_set_custom_charset:
2990  * @web_view: a #WebKitWebView
2991  * @charset: (allow-none): a character encoding name or %NULL
2992  *
2993  * Sets the current custom character encoding override of @web_view. The custom
2994  * character encoding will override any text encoding detected via HTTP headers or
2995  * META tags. Calling this method will stop any current load operation and reload the
2996  * current page. Setting the custom character encoding to %NULL removes the character
2997  * encoding override.
2998  */
2999 void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* charset)
3000 {
3001     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3002
3003     getPage(webView).setCustomTextEncodingName(String::fromUTF8(charset));
3004 }
3005
3006 /**
3007  * webkit_web_view_get_estimated_load_progress:
3008  * @web_view: a #WebKitWebView
3009  *
3010  * Gets the value of the #WebKitWebView:estimated-load-progress property.
3011  * You can monitor the estimated progress of a load operation by
3012  * connecting to the notify::estimated-load-progress signal of @web_view.
3013  *
3014  * Returns: an estimate of the of the percent complete for a document
3015  *     load as a range from 0.0 to 1.0.
3016  */
3017 gdouble webkit_web_view_get_estimated_load_progress(WebKitWebView* webView)
3018 {
3019     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3020     return getPage(webView).pageLoadState().estimatedProgress();
3021 }
3022
3023 /**
3024  * webkit_web_view_get_back_forward_list:
3025  * @web_view: a #WebKitWebView
3026  *
3027  * Obtains the #WebKitBackForwardList associated with the given #WebKitWebView. The
3028  * #WebKitBackForwardList is owned by the #WebKitWebView.
3029  *
3030  * Returns: (transfer none): the #WebKitBackForwardList
3031  */
3032 WebKitBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView)
3033 {
3034     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3035
3036     return webView->priv->backForwardList.get();
3037 }
3038
3039 /**
3040  * webkit_web_view_go_to_back_forward_list_item:
3041  * @web_view: a #WebKitWebView
3042  * @list_item: a #WebKitBackForwardListItem
3043  *
3044  * Loads the specific history item @list_item.
3045  * You can monitor the load operation by connecting to
3046  * #WebKitWebView::load-changed signal.
3047  */
3048 void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKitBackForwardListItem* listItem)
3049 {
3050     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3051     g_return_if_fail(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(listItem));
3052
3053     getPage(webView).goToBackForwardItem(*webkitBackForwardListItemGetItem(listItem));
3054 }
3055
3056 /**
3057  * webkit_web_view_set_settings:
3058  * @web_view: a #WebKitWebView
3059  * @settings: a #WebKitSettings
3060  *
3061  * Sets the #WebKitSettings to be applied to @web_view. The
3062  * existing #WebKitSettings of @web_view will be replaced by
3063  * @settings. New settings are applied immediately on @web_view.
3064  * The same #WebKitSettings object can be shared
3065  * by multiple #WebKitWebView<!-- -->s.
3066  */
3067 void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings)
3068 {
3069     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3070     g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
3071
3072     if (webView->priv->settings == settings)
3073         return;
3074
3075     // The "settings" property is set on construction, and in that
3076     // case webkit_web_view_set_settings() will be called *before*
3077     // any settings have been assigned. In that case there are no
3078     // signal handlers to disconnect.
3079     if (webView->priv->settings)
3080         webkitWebViewDisconnectSettingsSignalHandlers(webView);
3081
3082     webView->priv->settings = settings;
3083     webkitWebViewUpdateSettings(webView);
3084     g_object_notify(G_OBJECT(webView), "settings");
3085 }
3086
3087 /**
3088  * webkit_web_view_get_settings:
3089  * @web_view: a #WebKitWebView
3090  *
3091  * Gets the #WebKitSettings currently applied to @web_view.
3092  * If no other #WebKitSettings have been explicitly applied to
3093  * @web_view with webkit_web_view_set_settings(), the default
3094  * #WebKitSettings will be returned. This method always returns
3095  * a valid #WebKitSettings object.
3096  * To modify any of the @web_view settings, you can either create
3097  * a new #WebKitSettings object with webkit_settings_new(), setting
3098  * the desired preferences, and then replace the existing @web_view
3099  * settings with webkit_web_view_set_settings() or get the existing
3100  * @web_view settings and update it directly. #WebKitSettings objects
3101  * can be shared by multiple #WebKitWebView<!-- -->s, so modifying
3102  * the settings of a #WebKitWebView would affect other
3103  * #WebKitWebView<!-- -->s using the same #WebKitSettings.
3104  *
3105  * Returns: (transfer none): the #WebKitSettings attached to @web_view
3106  */
3107 WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView)
3108 {
3109     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3110     return webView->priv->settings.get();
3111 }
3112
3113 /**
3114  * webkit_web_view_get_window_properties:
3115  * @web_view: a #WebKitWebView
3116  *
3117  * Get the #WebKitWindowProperties object containing the properties
3118  * that the window containing @web_view should have.
3119  *
3120  * Returns: (transfer none): the #WebKitWindowProperties of @web_view
3121  */
3122 WebKitWindowProperties* webkit_web_view_get_window_properties(WebKitWebView* webView)
3123 {
3124     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3125
3126     return webView->priv->windowProperties.get();
3127 }
3128
3129 /**
3130  * webkit_web_view_set_zoom_level:
3131  * @web_view: a #WebKitWebView
3132  * @zoom_level: the zoom level
3133  *
3134  * Set the zoom level of @web_view, i.e. the factor by which the
3135  * view contents are scaled with respect to their original size.
3136  */
3137 void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel)
3138 {
3139     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3140
3141     if (webkit_web_view_get_zoom_level(webView) == zoomLevel)
3142         return;
3143
3144     auto& page = getPage(webView);
3145     page.scalePage(1.0, IntPoint()); // Reset page scale when zoom level is changed
3146     if (webkit_settings_get_zoom_text_only(webView->priv->settings.get()))
3147         page.setTextZoomFactor(zoomLevel);
3148     else
3149         page.setPageZoomFactor(zoomLevel);
3150     g_object_notify(G_OBJECT(webView), "zoom-level");
3151 }
3152
3153 /**
3154  * webkit_web_view_get_zoom_level:
3155  * @web_view: a #WebKitWebView
3156  *
3157  * Get the zoom level of @web_view, i.e. the factor by which the
3158  * view contents are scaled with respect to their original size.
3159  *
3160  * Returns: the current zoom level of @web_view
3161  */
3162 gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView)
3163 {
3164     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1);
3165
3166     auto& page = getPage(webView);
3167     gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get());
3168     return zoomTextOnly ? page.textZoomFactor() : page.pageZoomFactor();
3169 }
3170
3171 /**
3172  * webkit_web_view_can_execute_editing_command:
3173  * @web_view: a #WebKitWebView
3174  * @command: the command to check
3175  * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3176  * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3177  * @user_data: (closure): the data to pass to callback function
3178  *
3179  * Asynchronously check if it is possible to execute the given editing command.
3180  *
3181  * When the operation is finished, @callback will be called. You can then call
3182  * webkit_web_view_can_execute_editing_command_finish() to get the result of the operation.
3183  */
3184 void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const char* command, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3185 {
3186     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3187     g_return_if_fail(command);
3188
3189     GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
3190     getPage(webView).validateCommand(String::fromUTF8(command), [task = WTFMove(task)](const String&, bool isEnabled, int32_t, WebKit::CallbackBase::Error) {
3191         g_task_return_boolean(task.get(), isEnabled);
3192     });
3193 }
3194
3195 /**
3196  * webkit_web_view_can_execute_editing_command_finish:
3197  * @web_view: a #WebKitWebView
3198  * @result: a #GAsyncResult
3199  * @error: return location for error or %NULL to ignore
3200  *
3201  * Finish an asynchronous operation started with webkit_web_view_can_execute_editing_command().
3202  *
3203  * Returns: %TRUE if the editing command can be executed or %FALSE otherwise
3204  */
3205 gboolean webkit_web_view_can_execute_editing_command_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3206 {
3207     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3208     g_return_val_if_fail(g_task_is_valid(result, webView), FALSE);
3209
3210     return g_task_propagate_boolean(G_TASK(result), error);
3211 }
3212
3213 /**
3214  * webkit_web_view_execute_editing_command:
3215  * @web_view: a #WebKitWebView
3216  * @command: the command to execute
3217  *
3218  * Request to execute the given @command for @web_view. You can use
3219  * webkit_web_view_can_execute_editing_command() to check whether
3220  * it's possible to execute the command.
3221  */
3222 void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* command)
3223 {
3224     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3225     g_return_if_fail(command);
3226
3227     getPage(webView).executeEditCommand(String::fromUTF8(command));
3228 }
3229
3230 /**
3231  * webkit_web_view_execute_editing_command_with_argument:
3232  * @web_view: a #WebKitWebView
3233  * @command: the command to execute
3234  * @argument: the command argument
3235  *
3236  * Request to execute the given @command with @argument for @web_view. You can use
3237  * webkit_web_view_can_execute_editing_command() to check whether
3238  * it's possible to execute the command.
3239  *
3240  * Since: 2.10
3241  */
3242 void webkit_web_view_execute_editing_command_with_argument(WebKitWebView* webView, const char* command, const char* argument)
3243 {
3244     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3245     g_return_if_fail(command);
3246     g_return_if_fail(argument);
3247
3248     getPage(webView).executeEditCommand(String::fromUTF8(command), String::fromUTF8(argument));
3249 }
3250
3251 /**
3252  * webkit_web_view_get_find_controller:
3253  * @web_view: the #WebKitWebView
3254  *
3255  * Gets the #WebKitFindController that will allow the caller to query
3256  * the #WebKitWebView for the text to look for.
3257  *
3258  * Returns: (transfer none): the #WebKitFindController associated to
3259  * this particular #WebKitWebView.
3260  */
3261 WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView)
3262 {
3263     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3264
3265     if (!webView->priv->findController)
3266         webView->priv->findController = adoptGRef(WEBKIT_FIND_CONTROLLER(g_object_new(WEBKIT_TYPE_FIND_CONTROLLER, "web-view", webView, NULL)));
3267
3268     return webView->priv->findController.get();
3269 }
3270
3271 #if PLATFORM(GTK)
3272 /**
3273  * webkit_web_view_get_javascript_global_context: (skip)
3274  * @web_view: a #WebKitWebView
3275  *
3276  * Get the global JavaScript context used by @web_view to deserialize the
3277  * result values of scripts executed with webkit_web_view_run_javascript().
3278  *
3279  * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
3280  *    the result values of scripts.
3281  *
3282  * Deprecated: 2.22: Use jsc_value_get_context() instead.
3283  */
3284 JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
3285 {
3286     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3287
3288     // We keep a reference to the js context in the view only when this method is called
3289     // for backwards compatibility.
3290     if (!webView->priv->jsContext)
3291         webView->priv->jsContext = SharedJavascriptContext::singleton().getOrCreateContext();
3292     return jscContextGetJSContext(webView->priv->jsContext.get());
3293 }
3294 #endif
3295
3296 static void webkitWebViewRunJavaScriptCallback(API::SerializedScriptValue* wkSerializedScriptValue, const ExceptionDetails& exceptionDetails, GTask* task)
3297 {
3298     if (g_task_return_error_if_cancelled(task))
3299         return;
3300
3301     if (!wkSerializedScriptValue) {
3302         StringBuilder builder;
3303         if (!exceptionDetails.sourceURL.isEmpty()) {
3304             builder.append(exceptionDetails.sourceURL);
3305             if (exceptionDetails.lineNumber > 0) {
3306                 builder.append(':');
3307                 builder.appendNumber(exceptionDetails.lineNumber);
3308             }
3309             if (exceptionDetails.columnNumber > 0) {
3310                 builder.append(':');
3311                 builder.appendNumber(exceptionDetails.columnNumber);
3312             }
3313             builder.appendLiteral(": ");
3314         }
3315         builder.append(exceptionDetails.message);
3316         g_task_return_new_error(task, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED,
3317             "%s", builder.toString().utf8().data());
3318         return;
3319     }
3320
3321     g_task_return_pointer(task, webkitJavascriptResultCreate(wkSerializedScriptValue->internalRepresentation()),
3322         reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
3323 }
3324
3325 /**
3326  * webkit_web_view_run_javascript:
3327  * @web_view: a #WebKitWebView
3328  * @script: the script to run
3329  * @cancellable: (allow-none): a #GCancellable or %NULL to ignore