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.
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.
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.
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.
24 #include "WebKitWebView.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/GUniquePtrSoup.h>
70 #include <WebCore/JSDOMExceptionHandling.h>
71 #include <WebCore/RefPtrCairo.h>
72 #include <WebCore/URL.h>
73 #include <glib/gi18n-lib.h>
74 #include <wtf/SetForScope.h>
75 #include <wtf/glib/GRefPtr.h>
76 #include <wtf/glib/WTFGType.h>
77 #include <wtf/text/CString.h>
78 #include <wtf/text/StringBuilder.h>
81 #include "WebKitPrintOperationPrivate.h"
82 #include "WebKitWebInspectorPrivate.h"
83 #include "WebKitWebViewBasePrivate.h"
84 #include <WebCore/GUniquePtrGtk.h>
88 #include "APIViewClient.h"
90 #include "WebKitWebViewBackendPrivate.h"
94 #include <libnotify/notify.h>
97 using namespace WebKit;
98 using namespace WebCore;
101 * SECTION: WebKitWebView
102 * @Short_description: The central class of the WebKit2GTK+ API
103 * @Title: WebKitWebView
105 * #WebKitWebView is the central class of the WebKit2GTK+ API. It is
106 * responsible for managing the drawing of the content and forwarding
107 * of events. You can load any URI into the #WebKitWebView or a data
108 * string. With #WebKitSettings you can control various aspects of the
109 * rendering and loading of the content.
111 * Note that #WebKitWebView is scrollable by itself, so you don't need
112 * to embed it in a #GtkScrolledWindow.
118 LOAD_FAILED_WITH_TLS_ERRORS,
130 MOUSE_TARGET_CHANGED,
136 RESOURCE_LOAD_STARTED,
144 CONTEXT_MENU_DISMISSED,
148 INSECURE_CONTENT_DETECTED,
153 WEB_PROCESS_TERMINATED,
178 PROP_USER_CONTENT_MANAGER,
180 PROP_ESTIMATED_LOAD_PROGRESS,
189 PROP_IS_PLAYING_AUDIO,
191 PROP_IS_CONTROLLED_BY_AUTOMATION,
195 typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap;
196 typedef HashMap<uint64_t, GRefPtr<GTask> > SnapshotResultsMap;
198 class PageLoadStateObserver;
200 struct _WebKitWebViewPrivate {
201 ~_WebKitWebViewPrivate()
203 // For modal dialogs, make sure the main loop is stopped when finalizing the webView.
204 if (modalLoop && g_main_loop_is_running(modalLoop.get()))
205 g_main_loop_quit(modalLoop.get());
209 GRefPtr<WebKitWebViewBackend> backend;
210 std::unique_ptr<WKWPE::View> view;
213 WebKitWebView* relatedView;
215 CString customTextEncoding;
219 bool isControlledByAutomation;
221 std::unique_ptr<PageLoadStateObserver> loadObserver;
223 GRefPtr<WebKitBackForwardList> backForwardList;
224 GRefPtr<WebKitSettings> settings;
225 GRefPtr<WebKitUserContentManager> userContentManager;
226 GRefPtr<WebKitWebContext> context;
227 GRefPtr<WebKitWindowProperties> windowProperties;
228 GRefPtr<WebKitEditorState> editorState;
230 GRefPtr<GMainLoop> modalLoop;
232 GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult;
233 WebEvent::Modifiers mouseTargetModifiers;
235 GRefPtr<WebKitFindController> findController;
237 GRefPtr<WebKitWebResource> mainResource;
238 LoadingResourcesMap loadingResourcesMap;
240 WebKitScriptDialog* currentScriptDialog;
243 GRefPtr<JSCContext> jsContext;
245 GRefPtr<WebKitWebInspector> inspector;
247 RefPtr<cairo_surface_t> favicon;
248 GRefPtr<GCancellable> faviconCancellable;
251 unsigned long faviconChangedHandlerID;
253 SnapshotResultsMap snapshotResultsMap;
256 GRefPtr<WebKitAuthenticationRequest> authenticationRequest;
258 GRefPtr<WebKitWebsiteDataManager> websiteDataManager;
261 static guint signals[LAST_SIGNAL] = { 0, };
264 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, WEBKIT_TYPE_WEB_VIEW_BASE)
266 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, G_TYPE_OBJECT)
269 static inline WebPageProxy& getPage(WebKitWebView* webView)
272 auto* page = webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView));
276 ASSERT(webView->priv->view);
277 return webView->priv->view->page();
281 static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading)
283 if (webView->priv->isLoading == isLoading)
286 webView->priv->isLoading = isLoading;
287 g_object_notify(G_OBJECT(webView), "is-loading");
290 void webkitWebViewIsPlayingAudioChanged(WebKitWebView* webView)
292 g_object_notify(G_OBJECT(webView), "is-playing-audio");
295 class PageLoadStateObserver final : public PageLoadState::Observer {
297 PageLoadStateObserver(WebKitWebView* webView)
303 void willChangeIsLoading() override
305 g_object_freeze_notify(G_OBJECT(m_webView));
307 void didChangeIsLoading() override
309 webkitWebViewSetIsLoading(m_webView, getPage(m_webView).pageLoadState().isLoading());
310 g_object_thaw_notify(G_OBJECT(m_webView));
313 void willChangeTitle() override
315 g_object_freeze_notify(G_OBJECT(m_webView));
317 void didChangeTitle() override
319 m_webView->priv->title = getPage(m_webView).pageLoadState().title().utf8();
320 g_object_notify(G_OBJECT(m_webView), "title");
321 g_object_thaw_notify(G_OBJECT(m_webView));
324 void willChangeActiveURL() override
326 g_object_freeze_notify(G_OBJECT(m_webView));
328 void didChangeActiveURL() override
330 m_webView->priv->activeURI = getPage(m_webView).pageLoadState().activeURL().utf8();
331 g_object_notify(G_OBJECT(m_webView), "uri");
332 g_object_thaw_notify(G_OBJECT(m_webView));
335 void willChangeHasOnlySecureContent() override { }
336 void didChangeHasOnlySecureContent() override { }
338 void willChangeEstimatedProgress() override
340 g_object_freeze_notify(G_OBJECT(m_webView));
342 void didChangeEstimatedProgress() override
344 g_object_notify(G_OBJECT(m_webView), "estimated-load-progress");
345 g_object_thaw_notify(G_OBJECT(m_webView));
348 void willChangeCanGoBack() override { }
349 void didChangeCanGoBack() override { }
350 void willChangeCanGoForward() override { }
351 void didChangeCanGoForward() override { }
352 void willChangeNetworkRequestsInProgress() override { }
353 void didChangeNetworkRequestsInProgress() override { }
354 void willChangeCertificateInfo() override { }
355 void didChangeCertificateInfo() override { }
356 void willChangeWebProcessIsResponsive() override { }
357 void didChangeWebProcessIsResponsive() override { }
359 WebKitWebView* m_webView;
363 class WebViewClient final : public API::ViewClient {
365 explicit WebViewClient(WebKitWebView* webView)
371 void handleDownloadRequest(WKWPE::View&, DownloadProxy& downloadProxy) override
373 webkitWebViewHandleDownloadRequest(m_webView, &downloadProxy);
376 WebKitWebView* m_webView;
380 static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
382 if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)
383 || g_error_matches(error, WEBKIT_POLICY_ERROR, WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE)
384 || g_error_matches(error, WEBKIT_PLUGIN_ERROR, WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD))
387 GUniquePtr<char> htmlString(g_strdup_printf("<html><body>%s</body></html>", error->message));
388 webkit_web_view_load_alternate_html(webView, htmlString.get(), failingURI, 0);
394 static GtkWidget* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
399 static WebKitWebView* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
405 static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType)
407 if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) {
408 webkit_policy_decision_use(decision);
412 WebKitURIResponse* response = webkit_response_policy_decision_get_response(WEBKIT_RESPONSE_POLICY_DECISION(decision));
413 const ResourceResponse& resourceResponse = webkitURIResponseGetResourceResponse(response);
414 if (resourceResponse.isAttachment()) {
415 webkit_policy_decision_download(decision);
419 if (webkit_response_policy_decision_is_mime_type_supported(WEBKIT_RESPONSE_POLICY_DECISION(decision)))
420 webkit_policy_decision_use(decision);
422 webkit_policy_decision_ignore(decision);
427 static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
429 webkit_permission_request_deny(request);
433 static void allowModalDialogsChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
435 getPage(webView).setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
438 static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
440 auto& page = getPage(webView);
441 gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings);
442 gdouble pageZoomLevel = zoomTextOnly ? 1 : page.textZoomFactor();
443 gdouble textZoomLevel = zoomTextOnly ? page.pageZoomFactor() : 1;
444 page.setPageAndTextZoomFactors(pageZoomLevel, textZoomLevel);
447 static void userAgentChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
449 getPage(webView).setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
453 static void webkitWebViewUpdateFavicon(WebKitWebView* webView, cairo_surface_t* favicon)
455 WebKitWebViewPrivate* priv = webView->priv;
456 if (priv->favicon.get() == favicon)
459 priv->favicon = favicon;
460 g_object_notify(G_OBJECT(webView), "favicon");
463 static void webkitWebViewCancelFaviconRequest(WebKitWebView* webView)
465 if (!webView->priv->faviconCancellable)
468 g_cancellable_cancel(webView->priv->faviconCancellable.get());
469 webView->priv->faviconCancellable = 0;
472 static void gotFaviconCallback(GObject* object, GAsyncResult* result, gpointer userData)
474 GUniqueOutPtr<GError> error;
475 RefPtr<cairo_surface_t> favicon = adoptRef(webkit_favicon_database_get_favicon_finish(WEBKIT_FAVICON_DATABASE(object), result, &error.outPtr()));
476 if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
479 WebKitWebView* webView = WEBKIT_WEB_VIEW(userData);
480 webkitWebViewUpdateFavicon(webView, favicon.get());
481 webView->priv->faviconCancellable = 0;
484 static void webkitWebViewRequestFavicon(WebKitWebView* webView)
486 webkitWebViewCancelFaviconRequest(webView);
488 WebKitWebViewPrivate* priv = webView->priv;
489 priv->faviconCancellable = adoptGRef(g_cancellable_new());
490 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
491 webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), gotFaviconCallback, webView);
494 static void webkitWebViewUpdateFaviconURI(WebKitWebView* webView, const char* faviconURI)
496 if (webView->priv->faviconURI == faviconURI)
499 webView->priv->faviconURI = faviconURI;
500 webkitWebViewRequestFavicon(webView);
503 static void faviconChangedCallback(WebKitFaviconDatabase*, const char* pageURI, const char* faviconURI, WebKitWebView* webView)
505 if (webView->priv->activeURI != pageURI)
508 webkitWebViewUpdateFaviconURI(webView, faviconURI);
512 static bool webkitWebViewIsConstructed(WebKitWebView* webView)
514 // The loadObserver is set in webkitWebViewConstructed, right after the
515 // WebPageProxy is created, so we use it to check if the view has been
516 // constructed instead of adding a boolean member only for that.
517 return !!webView->priv->loadObserver;
520 static void webkitWebViewUpdateSettings(WebKitWebView* webView)
522 // The "settings" property is set on construction, and in that
523 // case webkit_web_view_set_settings() will be called *before* the
524 // WebPageProxy has been created so we should do an early return.
525 if (!webkitWebViewIsConstructed(webView))
528 auto& page = getPage(webView);
529 WebKitSettings* settings = webView->priv->settings.get();
530 page.setPreferences(*webkitSettingsGetPreferences(settings));
531 page.setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
532 page.setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
534 g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView);
535 g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
536 g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView);
539 static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView)
541 if (!webkitWebViewIsConstructed(webView))
544 WebKitSettings* settings = webView->priv->settings.get();
545 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(allowModalDialogsChanged), webView);
546 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView);
547 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(userAgentChanged), webView);
551 static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView)
553 WebKitWebViewPrivate* priv = webView->priv;
554 if (priv->faviconChangedHandlerID)
557 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
558 priv->faviconChangedHandlerID = g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), webView);
561 static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* webView)
563 WebKitWebViewPrivate* priv = webView->priv;
564 if (priv->faviconChangedHandlerID)
565 g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context.get()), priv->faviconChangedHandlerID);
566 priv->faviconChangedHandlerID = 0;
571 static const char* gNotifyNotificationID = "wk-notify-notification";
573 static void notifyNotificationClosed(NotifyNotification*, WebKitNotification* webNotification)
575 g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
576 webkit_notification_close(webNotification);
579 static void notifyNotificationClicked(NotifyNotification*, char*, WebKitNotification* webNotification)
581 webkit_notification_clicked(webNotification);
584 static void webNotificationClosed(WebKitNotification* webNotification)
586 NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
590 notify_notification_close(notification, nullptr);
591 g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
593 #endif // USE(LIBNOTIFY)
595 static gboolean webkitWebViewShowNotification(WebKitWebView*, WebKitNotification* webNotification)
598 if (!notify_is_initted())
599 notify_init(g_get_prgname());
601 NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
603 notification = notify_notification_new(webkit_notification_get_title(webNotification),
604 webkit_notification_get_body(webNotification), nullptr);
606 notify_notification_add_action(notification, "default", _("Acknowledge"), NOTIFY_ACTION_CALLBACK(notifyNotificationClicked), webNotification, nullptr);
608 g_signal_connect_object(notification, "closed", G_CALLBACK(notifyNotificationClosed), webNotification, static_cast<GConnectFlags>(0));
609 g_signal_connect(webNotification, "closed", G_CALLBACK(webNotificationClosed), nullptr);
610 g_object_set_data_full(G_OBJECT(webNotification), gNotifyNotificationID, notification, static_cast<GDestroyNotify>(g_object_unref));
612 notify_notification_update(notification, webkit_notification_get_title(webNotification),
613 webkit_notification_get_body(webNotification), nullptr);
616 notify_notification_show(notification, nullptr);
619 UNUSED_PARAM(webNotification);
624 static void webkitWebViewConstructed(GObject* object)
626 G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object);
628 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
629 WebKitWebViewPrivate* priv = webView->priv;
630 if (priv->relatedView) {
631 priv->context = webkit_web_view_get_context(priv->relatedView);
632 priv->isEphemeral = webkit_web_view_is_ephemeral(priv->relatedView);
633 priv->isControlledByAutomation = webkit_web_view_is_controlled_by_automation(priv->relatedView);
634 } else if (!priv->context)
635 priv->context = webkit_web_context_get_default();
636 else if (!priv->isEphemeral)
637 priv->isEphemeral = webkit_web_context_is_ephemeral(priv->context.get());
640 priv->settings = adoptGRef(webkit_settings_new());
642 if (!priv->userContentManager)
643 priv->userContentManager = adoptGRef(webkit_user_content_manager_new());
645 if (priv->isEphemeral && !webkit_web_context_is_ephemeral(priv->context.get())) {
646 priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new_ephemeral());
647 webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), webkitWebContextGetProcessPool(priv->context.get()));
650 webkitWebContextCreatePageForWebView(priv->context.get(), webView, priv->userContentManager.get(), priv->relatedView);
652 priv->loadObserver = std::make_unique<PageLoadStateObserver>(webView);
653 getPage(webView).pageLoadState().addObserver(*priv->loadObserver);
655 // The related view is only valid during the construction.
656 priv->relatedView = nullptr;
658 attachNavigationClientToView(webView);
659 attachUIClientToView(webView);
660 attachContextMenuClientToView(webView);
661 attachFormClientToView(webView);
664 attachIconLoadingClientToView(webView);
668 priv->view->setClient(std::make_unique<WebViewClient>(webView));
671 // This needs to be after attachUIClientToView() because WebPageProxy::setUIClient() calls setCanRunModal() with true.
672 // See https://bugs.webkit.org/show_bug.cgi?id=135412.
673 webkitWebViewUpdateSettings(webView);
675 priv->backForwardList = adoptGRef(webkitBackForwardListCreate(&getPage(webView).backForwardList()));
676 priv->windowProperties = adoptGRef(webkitWindowPropertiesCreate());
679 static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
681 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
686 gpointer backend = g_value_get_boxed(value);
687 webView->priv->backend = backend ? adoptGRef(static_cast<WebKitWebViewBackend*>(backend)) : nullptr;
691 case PROP_WEB_CONTEXT: {
692 gpointer webContext = g_value_get_object(value);
693 webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : nullptr;
696 case PROP_RELATED_VIEW: {
697 gpointer relatedView = g_value_get_object(value);
698 webView->priv->relatedView = relatedView ? WEBKIT_WEB_VIEW(relatedView) : nullptr;
701 case PROP_SETTINGS: {
702 if (gpointer settings = g_value_get_object(value))
703 webkit_web_view_set_settings(webView, WEBKIT_SETTINGS(settings));
706 case PROP_USER_CONTENT_MANAGER: {
707 gpointer userContentManager = g_value_get_object(value);
708 webView->priv->userContentManager = userContentManager ? WEBKIT_USER_CONTENT_MANAGER(userContentManager) : nullptr;
711 case PROP_ZOOM_LEVEL:
712 webkit_web_view_set_zoom_level(webView, g_value_get_double(value));
714 case PROP_IS_EPHEMERAL:
715 webView->priv->isEphemeral = g_value_get_boolean(value);
717 case PROP_IS_CONTROLLED_BY_AUTOMATION:
718 webView->priv->isControlledByAutomation = g_value_get_boolean(value);
721 webkit_web_view_set_editable(webView, g_value_get_boolean(value));
724 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
728 static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
730 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
735 g_value_set_static_boxed(value, webView->priv->backend.get());
738 case PROP_WEB_CONTEXT:
739 g_value_set_object(value, webView->priv->context.get());
742 g_value_set_object(value, webkit_web_view_get_settings(webView));
744 case PROP_USER_CONTENT_MANAGER:
745 g_value_set_object(value, webkit_web_view_get_user_content_manager(webView));
748 g_value_set_string(value, webView->priv->title.data());
750 case PROP_ESTIMATED_LOAD_PROGRESS:
751 g_value_set_double(value, webkit_web_view_get_estimated_load_progress(webView));
755 g_value_set_pointer(value, webkit_web_view_get_favicon(webView));
759 g_value_set_string(value, webkit_web_view_get_uri(webView));
761 case PROP_ZOOM_LEVEL:
762 g_value_set_double(value, webkit_web_view_get_zoom_level(webView));
764 case PROP_IS_LOADING:
765 g_value_set_boolean(value, webkit_web_view_is_loading(webView));
767 case PROP_IS_PLAYING_AUDIO:
768 g_value_set_boolean(value, webkit_web_view_is_playing_audio(webView));
770 case PROP_IS_EPHEMERAL:
771 g_value_set_boolean(value, webkit_web_view_is_ephemeral(webView));
773 case PROP_IS_CONTROLLED_BY_AUTOMATION:
774 g_value_set_boolean(value, webkit_web_view_is_controlled_by_automation(webView));
777 g_value_set_boolean(value, webkit_web_view_is_editable(webView));
780 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
784 static void webkitWebViewDispose(GObject* object)
786 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
789 webkitWebViewCancelFaviconRequest(webView);
790 webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView);
793 webkitWebViewDisconnectSettingsSignalHandlers(webView);
795 if (webView->priv->loadObserver) {
796 getPage(webView).pageLoadState().removeObserver(*webView->priv->loadObserver);
797 webView->priv->loadObserver.reset();
799 // We notify the context here to ensure it's called only once. Ideally we should
800 // call this in finalize, not dispose, but finalize is used internally and we don't
801 // have access to the instance pointer from the private struct destructor.
802 webkitWebContextWebViewDestroyed(webView->priv->context.get(), webView);
805 if (webView->priv->websiteDataManager) {
806 webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get()));
807 webView->priv->websiteDataManager = nullptr;
811 webView->priv->view->close();
814 G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
817 static gboolean webkitWebViewAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer)
819 void* object = g_value_get_object(handlerReturn);
821 g_value_set_object(returnValue, object);
826 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
828 GObjectClass* gObjectClass = G_OBJECT_CLASS(webViewClass);
830 gObjectClass->constructed = webkitWebViewConstructed;
831 gObjectClass->set_property = webkitWebViewSetProperty;
832 gObjectClass->get_property = webkitWebViewGetProperty;
833 gObjectClass->dispose = webkitWebViewDispose;
835 webViewClass->load_failed = webkitWebViewLoadFail;
836 webViewClass->create = webkitWebViewCreate;
837 webViewClass->script_dialog = webkitWebViewScriptDialog;
838 webViewClass->decide_policy = webkitWebViewDecidePolicy;
839 webViewClass->permission_request = webkitWebViewPermissionRequest;
840 webViewClass->run_file_chooser = webkitWebViewRunFileChooser;
841 webViewClass->authenticate = webkitWebViewAuthenticate;
842 webViewClass->show_notification = webkitWebViewShowNotification;
846 * WebKitWebView:backend:
848 * The #WebKitWebViewBackend of the view.
852 g_object_class_install_property(
858 _("The backend for the web view"),
859 WEBKIT_TYPE_WEB_VIEW_BACKEND,
860 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
864 * WebKitWebView:web-context:
866 * The #WebKitWebContext of the view.
868 g_object_class_install_property(gObjectClass,
870 g_param_spec_object("web-context",
872 _("The web context for the view"),
873 WEBKIT_TYPE_WEB_CONTEXT,
874 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
876 * WebKitWebView:related-view:
878 * The related #WebKitWebView used when creating the view to share the
879 * same web process. This property is not readable because the related
880 * web view is only valid during the object construction.
884 g_object_class_install_property(
889 _("Related WebView"),
890 _("The related WebKitWebView used when creating the view to share the same web process"),
891 WEBKIT_TYPE_WEB_VIEW,
892 static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
895 * WebKitWebView:settings:
897 * The #WebKitSettings of the view.
901 g_object_class_install_property(
906 _("WebView settings"),
907 _("The WebKitSettings of the view"),
908 WEBKIT_TYPE_SETTINGS,
909 static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT)));
912 * WebKitWebView:user-content-manager:
914 * The #WebKitUserContentManager of the view.
918 g_object_class_install_property(
920 PROP_USER_CONTENT_MANAGER,
922 "user-content-manager",
923 _("WebView user content manager"),
924 _("The WebKitUserContentManager of the view"),
925 WEBKIT_TYPE_USER_CONTENT_MANAGER,
926 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
929 * WebKitWebView:title:
931 * The main frame document title of this #WebKitWebView. If
932 * the title has not been received yet, it will be %NULL.
934 g_object_class_install_property(gObjectClass,
936 g_param_spec_string("title",
938 _("Main frame document title"),
940 WEBKIT_PARAM_READABLE));
943 * WebKitWebView:estimated-load-progress:
945 * An estimate of the percent completion for the current loading operation.
946 * This value will range from 0.0 to 1.0 and, once a load completes,
947 * will remain at 1.0 until a new load starts, at which point it
948 * will be reset to 0.0.
949 * The value is an estimate based on the total number of bytes expected
950 * to be received for a document, including all its possible subresources
951 * and child documents.
953 g_object_class_install_property(gObjectClass,
954 PROP_ESTIMATED_LOAD_PROGRESS,
955 g_param_spec_double("estimated-load-progress",
956 _("Estimated Load Progress"),
957 _("An estimate of the percent completion for a document load"),
959 WEBKIT_PARAM_READABLE));
962 * WebKitWebView:favicon:
964 * The favicon currently associated to the #WebKitWebView.
965 * See webkit_web_view_get_favicon() for more details.
967 g_object_class_install_property(gObjectClass,
969 g_param_spec_pointer("favicon",
971 _("The favicon associated to the view, if any"),
972 WEBKIT_PARAM_READABLE));
978 * The current active URI of the #WebKitWebView.
979 * See webkit_web_view_get_uri() for more details.
981 g_object_class_install_property(gObjectClass,
983 g_param_spec_string("uri",
985 _("The current active URI of the view"),
987 WEBKIT_PARAM_READABLE));
990 * WebKitWebView:zoom-level:
992 * The zoom level of the #WebKitWebView content.
993 * See webkit_web_view_set_zoom_level() for more details.
995 g_object_class_install_property(
1001 _("The zoom level of the view content"),
1003 WEBKIT_PARAM_READWRITE));
1006 * WebKitWebView:is-loading:
1008 * Whether the #WebKitWebView is currently loading a page. This property becomes
1009 * %TRUE as soon as a new load operation is requested and before the
1010 * #WebKitWebView::load-changed signal is emitted with %WEBKIT_LOAD_STARTED and
1011 * at that point the active URI is the requested one.
1012 * When the load operation finishes the property is set to %FALSE before
1013 * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_FINISHED.
1015 g_object_class_install_property(
1018 g_param_spec_boolean(
1021 _("Whether the view is loading a page"),
1023 WEBKIT_PARAM_READABLE));
1026 * WebKitWebView:is-playing-audio:
1028 * Whether the #WebKitWebView is currently playing audio from a page.
1029 * This property becomes %TRUE as soon as web content starts playing any
1030 * kind of audio. When a page is no longer playing any kind of sound,
1031 * the property is set back to %FALSE.
1035 g_object_class_install_property(
1037 PROP_IS_PLAYING_AUDIO,
1038 g_param_spec_boolean(
1041 _("Whether the view is playing audio"),
1043 WEBKIT_PARAM_READABLE));
1046 * WebKitWebView:is-ephemeral:
1048 * Whether the #WebKitWebView is ephemeral. An ephemeral web view never writes
1049 * website data to the client storage, no matter what #WebKitWebsiteDataManager
1050 * its context is using. This is normally used to implement private browsing mode.
1051 * This is a %G_PARAM_CONSTRUCT_ONLY property, so you have to create a ephemeral
1052 * #WebKitWebView and it can't be changed. Note that all #WebKitWebView<!-- -->s
1053 * created with an ephemeral #WebKitWebContext will be ephemeral automatically.
1054 * See also webkit_web_context_new_ephemeral().
1058 g_object_class_install_property(
1061 g_param_spec_boolean(
1064 _("Whether the web view is ephemeral"),
1066 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1069 * WebKitWebView:is-controlled-by-automation:
1071 * Whether the #WebKitWebView is controlled by automation. This should only be used when
1072 * creating a new #WebKitWebView as a response to #WebKitAutomationSession::create-web-view
1077 g_object_class_install_property(
1079 PROP_IS_CONTROLLED_BY_AUTOMATION,
1080 g_param_spec_boolean(
1081 "is-controlled-by-automation",
1082 "Is Controlled By Automation",
1083 _("Whether the web view is controlled by automation"),
1085 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1088 * WebKitWebView:editable:
1090 * Whether the pages loaded inside #WebKitWebView are editable. For more
1091 * information see webkit_web_view_set_editable().
1095 g_object_class_install_property(
1098 g_param_spec_boolean(
1101 _("Whether the content can be modified by the user."),
1103 WEBKIT_PARAM_READWRITE));
1106 * WebKitWebView::load-changed:
1107 * @web_view: the #WebKitWebView on which the signal is emitted
1108 * @load_event: the #WebKitLoadEvent
1110 * Emitted when a load operation in @web_view changes.
1111 * The signal is always emitted with %WEBKIT_LOAD_STARTED when a
1112 * new load request is made and %WEBKIT_LOAD_FINISHED when the load
1113 * finishes successfully or due to an error. When the ongoing load
1114 * operation fails #WebKitWebView::load-failed signal is emitted
1115 * before #WebKitWebView::load-changed is emitted with
1116 * %WEBKIT_LOAD_FINISHED.
1117 * If a redirection is received from the server, this signal is emitted
1118 * with %WEBKIT_LOAD_REDIRECTED after the initial emission with
1119 * %WEBKIT_LOAD_STARTED and before %WEBKIT_LOAD_COMMITTED.
1120 * When the page content starts arriving the signal is emitted with
1121 * %WEBKIT_LOAD_COMMITTED event.
1123 * You can handle this signal and use a switch to track any ongoing
1126 * <informalexample><programlisting>
1127 * static void web_view_load_changed (WebKitWebView *web_view,
1128 * WebKitLoadEvent load_event,
1129 * gpointer user_data)
1131 * switch (load_event) {
1132 * case WEBKIT_LOAD_STARTED:
1133 * /<!-- -->* New load, we have now a provisional URI *<!-- -->/
1134 * provisional_uri = webkit_web_view_get_uri (web_view);
1135 * /<!-- -->* Here we could start a spinner or update the
1136 * <!-- -->* location bar with the provisional URI *<!-- -->/
1138 * case WEBKIT_LOAD_REDIRECTED:
1139 * redirected_uri = webkit_web_view_get_uri (web_view);
1141 * case WEBKIT_LOAD_COMMITTED:
1142 * /<!-- -->* The load is being performed. Current URI is
1143 * <!-- -->* the final one and it won't change unless a new
1144 * <!-- -->* load is requested or a navigation within the
1145 * <!-- -->* same page is performed *<!-- -->/
1146 * uri = webkit_web_view_get_uri (web_view);
1148 * case WEBKIT_LOAD_FINISHED:
1149 * /<!-- -->* Load finished, we can now stop the spinner *<!-- -->/
1153 * </programlisting></informalexample>
1155 signals[LOAD_CHANGED] =
1156 g_signal_new("load-changed",
1157 G_TYPE_FROM_CLASS(webViewClass),
1159 G_STRUCT_OFFSET(WebKitWebViewClass, load_changed),
1161 g_cclosure_marshal_VOID__ENUM,
1163 WEBKIT_TYPE_LOAD_EVENT);
1166 * WebKitWebView::load-failed:
1167 * @web_view: the #WebKitWebView on which the signal is emitted
1168 * @load_event: the #WebKitLoadEvent of the load operation
1169 * @failing_uri: the URI that failed to load
1170 * @error: the #GError that was triggered
1172 * Emitted when an error occurs during a load operation.
1173 * If the error happened when starting to load data for a page
1174 * @load_event will be %WEBKIT_LOAD_STARTED. If it happened while
1175 * loading a committed data source @load_event will be %WEBKIT_LOAD_COMMITTED.
1176 * Since a load error causes the load operation to finish, the signal
1177 * WebKitWebView::load-changed will always be emitted with
1178 * %WEBKIT_LOAD_FINISHED event right after this one.
1180 * By default, if the signal is not handled, a stock error page will be displayed.
1181 * You need to handle the signal if you want to provide your own error page.
1183 * Returns: %TRUE to stop other handlers from being invoked for the event.
1184 * %FALSE to propagate the event further.
1186 signals[LOAD_FAILED] =
1189 G_TYPE_FROM_CLASS(webViewClass),
1191 G_STRUCT_OFFSET(WebKitWebViewClass, load_failed),
1192 g_signal_accumulator_true_handled, 0,
1193 g_cclosure_marshal_generic,
1195 WEBKIT_TYPE_LOAD_EVENT,
1197 G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE);
1200 * WebKitWebView::load-failed-with-tls-errors:
1201 * @web_view: the #WebKitWebView on which the signal is emitted
1202 * @failing_uri: the URI that failed to load
1203 * @certificate: a #GTlsCertificate
1204 * @errors: a #GTlsCertificateFlags with the verification status of @certificate
1206 * Emitted when a TLS error occurs during a load operation.
1207 * To allow an exception for this @certificate
1208 * and the host of @failing_uri use webkit_web_context_allow_tls_certificate_for_host().
1210 * To handle this signal asynchronously you should call g_object_ref() on @certificate
1213 * If %FALSE is returned, #WebKitWebView::load-failed will be emitted. The load
1214 * will finish regardless of the returned value.
1216 * Returns: %TRUE to stop other handlers from being invoked for the event.
1217 * %FALSE to propagate the event further.
1221 signals[LOAD_FAILED_WITH_TLS_ERRORS] =
1222 g_signal_new("load-failed-with-tls-errors",
1223 G_TYPE_FROM_CLASS(webViewClass),
1225 G_STRUCT_OFFSET(WebKitWebViewClass, load_failed_with_tls_errors),
1226 g_signal_accumulator_true_handled, 0 /* accumulator data */,
1227 g_cclosure_marshal_generic,
1230 G_TYPE_TLS_CERTIFICATE,
1231 G_TYPE_TLS_CERTIFICATE_FLAGS);
1234 * WebKitWebView::create:
1235 * @web_view: the #WebKitWebView on which the signal is emitted
1236 * @navigation_action: a #WebKitNavigationAction
1238 * Emitted when the creation of a new #WebKitWebView is requested.
1239 * If this signal is handled the signal handler should return the
1240 * newly created #WebKitWebView.
1242 * The #WebKitNavigationAction parameter contains information about the
1243 * navigation action that triggered this signal.
1245 * When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES
1246 * process model, the new #WebKitWebView should be related to
1247 * @web_view to share the same web process, see webkit_web_view_new_with_related_view()
1250 * The new #WebKitWebView should not be displayed to the user
1251 * until the #WebKitWebView::ready-to-show signal is emitted.
1253 * Returns: (transfer full): a newly allocated #WebKitWebView widget
1254 * or %NULL to propagate the event further.
1256 signals[CREATE] = g_signal_new(
1258 G_TYPE_FROM_CLASS(webViewClass),
1260 G_STRUCT_OFFSET(WebKitWebViewClass, create),
1261 webkitWebViewAccumulatorObjectHandled, 0,
1262 g_cclosure_marshal_generic,
1266 WEBKIT_TYPE_WEB_VIEW,
1269 WEBKIT_TYPE_NAVIGATION_ACTION | G_SIGNAL_TYPE_STATIC_SCOPE);
1272 * WebKitWebView::ready-to-show:
1273 * @web_view: the #WebKitWebView on which the signal is emitted
1275 * Emitted after #WebKitWebView::create on the newly created #WebKitWebView
1276 * when it should be displayed to the user. When this signal is emitted
1277 * all the information about how the window should look, including
1278 * size, position, whether the location, status and scrollbars
1279 * should be displayed, is already set on the #WebKitWindowProperties
1280 * of @web_view. See also webkit_web_view_get_window_properties().
1282 signals[READY_TO_SHOW] =
1283 g_signal_new("ready-to-show",
1284 G_TYPE_FROM_CLASS(webViewClass),
1286 G_STRUCT_OFFSET(WebKitWebViewClass, ready_to_show),
1288 g_cclosure_marshal_VOID__VOID,
1292 * WebKitWebView::run-as-modal:
1293 * @web_view: the #WebKitWebView on which the signal is emitted
1295 * Emitted after #WebKitWebView::ready-to-show on the newly
1296 * created #WebKitWebView when JavaScript code calls
1297 * <function>window.showModalDialog</function>. The purpose of
1298 * this signal is to allow the client application to prepare the
1299 * new view to behave as modal. Once the signal is emitted a new
1300 * main loop will be run to block user interaction in the parent
1301 * #WebKitWebView until the new dialog is closed.
1303 signals[RUN_AS_MODAL] =
1304 g_signal_new("run-as-modal",
1305 G_TYPE_FROM_CLASS(webViewClass),
1307 G_STRUCT_OFFSET(WebKitWebViewClass, run_as_modal),
1309 g_cclosure_marshal_VOID__VOID,
1313 * WebKitWebView::close:
1314 * @web_view: the #WebKitWebView on which the signal is emitted
1316 * Emitted when closing a #WebKitWebView is requested. This occurs when a
1317 * call is made from JavaScript's <function>window.close</function> function or
1318 * after trying to close the @web_view with webkit_web_view_try_close().
1319 * It is the owner's responsibility to handle this signal to hide or
1320 * destroy the #WebKitWebView, if necessary.
1323 g_signal_new("close",
1324 G_TYPE_FROM_CLASS(webViewClass),
1326 G_STRUCT_OFFSET(WebKitWebViewClass, close),
1328 g_cclosure_marshal_VOID__VOID,
1332 * WebKitWebView::script-dialog:
1333 * @web_view: the #WebKitWebView on which the signal is emitted
1334 * @dialog: the #WebKitScriptDialog to show
1336 * Emitted when JavaScript code calls <function>window.alert</function>,
1337 * <function>window.confirm</function> or <function>window.prompt</function>,
1338 * or when <function>onbeforeunload</function> event is fired.
1339 * The @dialog parameter should be used to build the dialog.
1340 * If the signal is not handled a different dialog will be built and shown depending
1341 * on the dialog type:
1344 * %WEBKIT_SCRIPT_DIALOG_ALERT: message dialog with a single Close button.
1345 * </para></listitem>
1347 * %WEBKIT_SCRIPT_DIALOG_CONFIRM: message dialog with OK and Cancel buttons.
1348 * </para></listitem>
1350 * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and
1351 * a text entry with the default text.
1352 * </para></listitem>
1354 * %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: message dialog with Stay and Leave buttons.
1355 * </para></listitem>
1358 * Returns: %TRUE to stop other handlers from being invoked for the event.
1359 * %FALSE to propagate the event further.
1361 signals[SCRIPT_DIALOG] = g_signal_new(
1363 G_TYPE_FROM_CLASS(webViewClass),
1365 G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog),
1366 g_signal_accumulator_true_handled, nullptr,
1367 g_cclosure_marshal_generic,
1369 WEBKIT_TYPE_SCRIPT_DIALOG | G_SIGNAL_TYPE_STATIC_SCOPE);
1372 * WebKitWebView::decide-policy:
1373 * @web_view: the #WebKitWebView on which the signal is emitted
1374 * @decision: the #WebKitPolicyDecision
1375 * @decision_type: a #WebKitPolicyDecisionType denoting the type of @decision
1377 * This signal is emitted when WebKit is requesting the client to decide a policy
1378 * decision, such as whether to navigate to a page, open a new window or whether or
1379 * not to download a resource. The #WebKitNavigationPolicyDecision passed in the
1380 * @decision argument is a generic type, but should be casted to a more
1381 * specific type when making the decision. For example:
1383 * <informalexample><programlisting>
1385 * decide_policy_cb (WebKitWebView *web_view,
1386 * WebKitPolicyDecision *decision,
1387 * WebKitPolicyDecisionType type)
1390 * case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
1391 * WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1392 * /<!-- -->* Make a policy decision here. *<!-- -->/
1394 * case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
1395 * WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1396 * /<!-- -->* Make a policy decision here. *<!-- -->/
1398 * case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
1399 * WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
1400 * /<!-- -->* Make a policy decision here. *<!-- -->/
1403 * /<!-- -->* Making no decision results in webkit_policy_decision_use(). *<!-- -->/
1408 * </programlisting></informalexample>
1410 * It is possible to make policy decision asynchronously, by simply calling g_object_ref()
1411 * on the @decision argument and returning %TRUE to block the default signal handler.
1412 * If the last reference is removed on a #WebKitPolicyDecision and no decision has been
1413 * made explicitly, webkit_policy_decision_use() will be the default policy decision. The
1414 * default signal handler will simply call webkit_policy_decision_use(). Only the first
1415 * policy decision chosen for a given #WebKitPolicyDecision will have any affect.
1417 * Returns: %TRUE to stop other handlers from being invoked for the event.
1418 * %FALSE to propagate the event further.
1421 signals[DECIDE_POLICY] = g_signal_new(
1423 G_TYPE_FROM_CLASS(webViewClass),
1425 G_STRUCT_OFFSET(WebKitWebViewClass, decide_policy),
1426 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1427 g_cclosure_marshal_generic,
1428 G_TYPE_BOOLEAN, 2, /* number of parameters */
1429 WEBKIT_TYPE_POLICY_DECISION,
1430 WEBKIT_TYPE_POLICY_DECISION_TYPE);
1433 * WebKitWebView::permission-request:
1434 * @web_view: the #WebKitWebView on which the signal is emitted
1435 * @request: the #WebKitPermissionRequest
1437 * This signal is emitted when WebKit is requesting the client to
1438 * decide about a permission request, such as allowing the browser
1439 * to switch to fullscreen mode, sharing its location or similar
1442 * A possible way to use this signal could be through a dialog
1443 * allowing the user decide what to do with the request:
1445 * <informalexample><programlisting>
1446 * static gboolean permission_request_cb (WebKitWebView *web_view,
1447 * WebKitPermissionRequest *request,
1448 * GtkWindow *parent_window)
1450 * GtkWidget *dialog = gtk_message_dialog_new (parent_window,
1452 * GTK_MESSAGE_QUESTION,
1453 * GTK_BUTTONS_YES_NO,
1454 * "Allow Permission Request?");
1455 * gtk_widget_show (dialog);
1456 * gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1459 * case GTK_RESPONSE_YES:
1460 * webkit_permission_request_allow (request);
1463 * webkit_permission_request_deny (request);
1466 * gtk_widget_destroy (dialog);
1470 * </programlisting></informalexample>
1472 * It is possible to handle permission requests asynchronously, by
1473 * simply calling g_object_ref() on the @request argument and
1474 * returning %TRUE to block the default signal handler. If the
1475 * last reference is removed on a #WebKitPermissionRequest and the
1476 * request has not been handled, webkit_permission_request_deny()
1477 * will be the default action.
1479 * If the signal is not handled, the @request will be completed automatically
1480 * by the specific #WebKitPermissionRequest that could allow or deny it. Check the
1481 * documentation of classes implementing #WebKitPermissionRequest interface to know
1482 * their default action.
1484 * Returns: %TRUE to stop other handlers from being invoked for the event.
1485 * %FALSE to propagate the event further.
1488 signals[PERMISSION_REQUEST] = g_signal_new(
1489 "permission-request",
1490 G_TYPE_FROM_CLASS(webViewClass),
1492 G_STRUCT_OFFSET(WebKitWebViewClass, permission_request),
1493 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1494 g_cclosure_marshal_generic,
1495 G_TYPE_BOOLEAN, 1, /* number of parameters */
1496 WEBKIT_TYPE_PERMISSION_REQUEST);
1498 * WebKitWebView::mouse-target-changed:
1499 * @web_view: the #WebKitWebView on which the signal is emitted
1500 * @hit_test_result: a #WebKitHitTestResult
1501 * @modifiers: a bitmask of #GdkModifierType
1503 * This signal is emitted when the mouse cursor moves over an
1504 * element such as a link, image or a media element. To determine
1505 * what type of element the mouse cursor is over, a Hit Test is performed
1506 * on the current mouse coordinates and the result is passed in the
1507 * @hit_test_result argument. The @modifiers argument is a bitmask of
1508 * #GdkModifierType flags indicating the state of modifier keys.
1509 * The signal is emitted again when the mouse is moved out of the
1510 * current element with a new @hit_test_result.
1512 signals[MOUSE_TARGET_CHANGED] = g_signal_new(
1513 "mouse-target-changed",
1514 G_TYPE_FROM_CLASS(webViewClass),
1516 G_STRUCT_OFFSET(WebKitWebViewClass, mouse_target_changed),
1518 g_cclosure_marshal_generic,
1520 WEBKIT_TYPE_HIT_TEST_RESULT,
1525 * WebKitWebView::print:
1526 * @web_view: the #WebKitWebView on which the signal is emitted
1527 * @print_operation: the #WebKitPrintOperation that will handle the print request
1529 * Emitted when printing is requested on @web_view, usually by a JavaScript call,
1530 * before the print dialog is shown. This signal can be used to set the initial
1531 * print settings and page setup of @print_operation to be used as default values in
1532 * the print dialog. You can call webkit_print_operation_set_print_settings() and
1533 * webkit_print_operation_set_page_setup() and then return %FALSE to propagate the
1534 * event so that the print dialog is shown.
1536 * You can connect to this signal and return %TRUE to cancel the print operation
1537 * or implement your own print dialog.
1539 * Returns: %TRUE to stop other handlers from being invoked for the event.
1540 * %FALSE to propagate the event further.
1542 signals[PRINT] = g_signal_new(
1544 G_TYPE_FROM_CLASS(webViewClass),
1546 G_STRUCT_OFFSET(WebKitWebViewClass, print),
1547 g_signal_accumulator_true_handled, nullptr,
1548 g_cclosure_marshal_generic,
1550 WEBKIT_TYPE_PRINT_OPERATION);
1551 #endif // PLATFORM(GTK)
1554 * WebKitWebView::resource-load-started:
1555 * @web_view: the #WebKitWebView on which the signal is emitted
1556 * @resource: a #WebKitWebResource
1557 * @request: a #WebKitURIRequest
1559 * Emitted when a new resource is going to be loaded. The @request parameter
1560 * contains the #WebKitURIRequest that will be sent to the server.
1561 * You can monitor the load operation by connecting to the different signals
1564 signals[RESOURCE_LOAD_STARTED] = g_signal_new(
1565 "resource-load-started",
1566 G_TYPE_FROM_CLASS(webViewClass),
1568 G_STRUCT_OFFSET(WebKitWebViewClass, resource_load_started),
1570 g_cclosure_marshal_generic,
1572 WEBKIT_TYPE_WEB_RESOURCE,
1573 WEBKIT_TYPE_URI_REQUEST);
1576 * WebKitWebView::enter-fullscreen:
1577 * @web_view: the #WebKitWebView on which the signal is emitted.
1579 * Emitted when JavaScript code calls
1580 * <function>element.webkitRequestFullScreen</function>. If the
1581 * signal is not handled the #WebKitWebView will proceed to full screen
1582 * its top level window. This signal can be used by client code to
1583 * request permission to the user prior doing the full screen
1584 * transition and eventually prepare the top-level window
1585 * (e.g. hide some widgets that would otherwise be part of the
1586 * full screen window).
1588 * Returns: %TRUE to stop other handlers from being invoked for the event.
1589 * %FALSE to continue emission of the event.
1591 signals[ENTER_FULLSCREEN] = g_signal_new(
1593 G_TYPE_FROM_CLASS(webViewClass),
1595 G_STRUCT_OFFSET(WebKitWebViewClass, enter_fullscreen),
1596 g_signal_accumulator_true_handled, nullptr,
1597 g_cclosure_marshal_generic,
1601 * WebKitWebView::leave-fullscreen:
1602 * @web_view: the #WebKitWebView on which the signal is emitted.
1604 * Emitted when the #WebKitWebView is about to restore its top level
1605 * window out of its full screen state. This signal can be used by
1606 * client code to restore widgets hidden during the
1607 * #WebKitWebView::enter-fullscreen stage for instance.
1609 * Returns: %TRUE to stop other handlers from being invoked for the event.
1610 * %FALSE to continue emission of the event.
1612 signals[LEAVE_FULLSCREEN] = g_signal_new(
1614 G_TYPE_FROM_CLASS(webViewClass),
1616 G_STRUCT_OFFSET(WebKitWebViewClass, leave_fullscreen),
1617 g_signal_accumulator_true_handled, nullptr,
1618 g_cclosure_marshal_generic,
1622 * WebKitWebView::run-file-chooser:
1623 * @web_view: the #WebKitWebView on which the signal is emitted
1624 * @request: a #WebKitFileChooserRequest
1626 * This signal is emitted when the user interacts with a <input
1627 * type='file' /> HTML element, requesting from WebKit to show
1628 * a dialog to select one or more files to be uploaded. To let the
1629 * application know the details of the file chooser, as well as to
1630 * allow the client application to either cancel the request or
1631 * perform an actual selection of files, the signal will pass an
1632 * instance of the #WebKitFileChooserRequest in the @request
1635 * The default signal handler will asynchronously run a regular
1636 * #GtkFileChooserDialog for the user to interact with.
1638 * Returns: %TRUE to stop other handlers from being invoked for the event.
1639 * %FALSE to propagate the event further.
1642 signals[RUN_FILE_CHOOSER] = g_signal_new(
1644 G_TYPE_FROM_CLASS(webViewClass),
1646 G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
1647 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1648 g_cclosure_marshal_generic,
1649 G_TYPE_BOOLEAN, 1, /* number of parameters */
1650 WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
1653 * WebKitWebView::context-menu:
1654 * @web_view: the #WebKitWebView on which the signal is emitted
1655 * @context_menu: the proposed #WebKitContextMenu
1656 * @event: the #GdkEvent that triggered the context menu
1657 * @hit_test_result: a #WebKitHitTestResult
1659 * Emitted when a context menu is about to be displayed to give the application
1660 * a chance to customize the proposed menu, prevent the menu from being displayed,
1661 * or build its own context menu.
1664 * To customize the proposed menu you can use webkit_context_menu_prepend(),
1665 * webkit_context_menu_append() or webkit_context_menu_insert() to add new
1666 * #WebKitContextMenuItem<!-- -->s to @context_menu, webkit_context_menu_move_item()
1667 * to reorder existing items, or webkit_context_menu_remove() to remove an
1668 * existing item. The signal handler should return %FALSE, and the menu represented
1669 * by @context_menu will be shown.
1670 * </para></listitem>
1672 * To prevent the menu from being displayed you can just connect to this signal
1673 * and return %TRUE so that the proposed menu will not be shown.
1674 * </para></listitem>
1676 * To build your own menu, you can remove all items from the proposed menu with
1677 * webkit_context_menu_remove_all(), add your own items and return %FALSE so
1678 * that the menu will be shown. You can also ignore the proposed #WebKitContextMenu,
1679 * build your own #GtkMenu and return %TRUE to prevent the proposed menu from being shown.
1680 * </para></listitem>
1682 * If you just want the default menu to be shown always, simply don't connect to this
1683 * signal because showing the proposed context menu is the default behaviour.
1684 * </para></listitem>
1687 * The @event is expected to be one of the following types:
1690 * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu
1691 * was triggered with mouse.
1692 * </para></listitem>
1694 * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show
1696 * </para></listitem>
1698 * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget::popup-menu
1699 * signal was used to show the context menu.
1700 * </para></listitem>
1703 * If the signal handler returns %FALSE the context menu represented by @context_menu
1704 * will be shown, if it return %TRUE the context menu will not be shown.
1706 * The proposed #WebKitContextMenu passed in @context_menu argument is only valid
1707 * during the signal emission.
1709 * Returns: %TRUE to stop other handlers from being invoked for the event.
1710 * %FALSE to propagate the event further.
1712 signals[CONTEXT_MENU] = g_signal_new(
1714 G_TYPE_FROM_CLASS(webViewClass),
1716 G_STRUCT_OFFSET(WebKitWebViewClass, context_menu),
1717 g_signal_accumulator_true_handled, nullptr,
1718 g_cclosure_marshal_generic,
1720 WEBKIT_TYPE_CONTEXT_MENU,
1722 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1724 G_TYPE_POINTER, // FIXME: use a wpe thing here. I'm not sure we want to expose libwpe in the API.
1726 WEBKIT_TYPE_HIT_TEST_RESULT);
1729 * WebKitWebView::context-menu-dismissed:
1730 * @web_view: the #WebKitWebView on which the signal is emitted
1732 * Emitted after #WebKitWebView::context-menu signal, if the context menu is shown,
1733 * to notify that the context menu is dismissed.
1735 signals[CONTEXT_MENU_DISMISSED] =
1736 g_signal_new("context-menu-dismissed",
1737 G_TYPE_FROM_CLASS(webViewClass),
1739 G_STRUCT_OFFSET(WebKitWebViewClass, context_menu_dismissed),
1741 g_cclosure_marshal_VOID__VOID,
1745 * WebKitWebView::submit-form:
1746 * @web_view: the #WebKitWebView on which the signal is emitted
1747 * @request: a #WebKitFormSubmissionRequest
1749 * This signal is emitted when a form is about to be submitted. The @request
1750 * argument passed contains information about the text fields of the form. This
1751 * is typically used to store login information that can be used later to
1752 * pre-fill the form.
1753 * The form will not be submitted until webkit_form_submission_request_submit() is called.
1755 * It is possible to handle the form submission request asynchronously, by
1756 * simply calling g_object_ref() on the @request argument and calling
1757 * webkit_form_submission_request_submit() when done to continue with the form submission.
1758 * If the last reference is removed on a #WebKitFormSubmissionRequest and the
1759 * form has not been submitted, webkit_form_submission_request_submit() will be called.
1761 signals[SUBMIT_FORM] =
1762 g_signal_new("submit-form",
1763 G_TYPE_FROM_CLASS(webViewClass),
1765 G_STRUCT_OFFSET(WebKitWebViewClass, submit_form),
1767 g_cclosure_marshal_VOID__OBJECT,
1769 WEBKIT_TYPE_FORM_SUBMISSION_REQUEST);
1772 * WebKitWebView::insecure-content-detected:
1773 * @web_view: the #WebKitWebView on which the signal is emitted
1774 * @event: the #WebKitInsecureContentEvent
1776 * This signal is emitted when insecure content has been detected
1777 * in a page loaded through a secure connection. This typically
1778 * means that a external resource from an unstrusted source has
1779 * been run or displayed, resulting in a mix of HTTPS and
1780 * non-HTTPS content.
1782 * You can check the @event parameter to know exactly which kind
1783 * of event has been detected (see #WebKitInsecureContentEvent).
1785 signals[INSECURE_CONTENT_DETECTED] =
1786 g_signal_new("insecure-content-detected",
1787 G_TYPE_FROM_CLASS(webViewClass),
1789 G_STRUCT_OFFSET(WebKitWebViewClass, insecure_content_detected),
1791 g_cclosure_marshal_VOID__ENUM,
1793 WEBKIT_TYPE_INSECURE_CONTENT_EVENT);
1797 * WebKitWebView::web-process-crashed:
1798 * @web_view: the #WebKitWebView
1800 * This signal is emitted when the web process crashes.
1802 * Returns: %TRUE to stop other handlers from being invoked for the event.
1803 * %FALSE to propagate the event further.
1805 * Deprecated: 2.20: Use WebKitWebView::web-process-terminated instead.
1807 signals[WEB_PROCESS_CRASHED] = g_signal_new(
1808 "web-process-crashed",
1809 G_TYPE_FROM_CLASS(webViewClass),
1811 G_STRUCT_OFFSET(WebKitWebViewClass, web_process_crashed),
1812 g_signal_accumulator_true_handled, nullptr,
1813 g_cclosure_marshal_generic,
1818 * WebKitWebView::web-process-terminated:
1819 * @web_view: the #WebKitWebView
1820 * @reason: the a #WebKitWebProcessTerminationReason
1822 * This signal is emitted when the web process terminates abnormally due
1827 signals[WEB_PROCESS_TERMINATED] = g_signal_new(
1828 "web-process-terminated",
1829 G_TYPE_FROM_CLASS(webViewClass),
1831 G_STRUCT_OFFSET(WebKitWebViewClass, web_process_terminated),
1833 g_cclosure_marshal_VOID__ENUM,
1835 WEBKIT_TYPE_WEB_PROCESS_TERMINATION_REASON);
1838 * WebKitWebView::authenticate:
1839 * @web_view: the #WebKitWebView on which the signal is emitted
1840 * @request: a #WebKitAuthenticationRequest
1842 * This signal is emitted when the user is challenged with HTTP
1843 * authentication. To let the application access or supply
1844 * the credentials as well as to allow the client application
1845 * to either cancel the request or perform the authentication,
1846 * the signal will pass an instance of the
1847 * #WebKitAuthenticationRequest in the @request argument.
1848 * To handle this signal asynchronously you should keep a ref
1849 * of the request and return %TRUE. To disable HTTP authentication
1850 * entirely, connect to this signal and simply return %TRUE.
1852 * The default signal handler will run a default authentication
1853 * dialog asynchronously for the user to interact with.
1855 * Returns: %TRUE to stop other handlers from being invoked for the event.
1856 * %FALSE to propagate the event further.
1860 signals[AUTHENTICATE] = g_signal_new(
1862 G_TYPE_FROM_CLASS(webViewClass),
1864 G_STRUCT_OFFSET(WebKitWebViewClass, authenticate),
1865 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1866 g_cclosure_marshal_generic,
1867 G_TYPE_BOOLEAN, 1, /* number of parameters */
1868 WEBKIT_TYPE_AUTHENTICATION_REQUEST);
1871 * WebKitWebView::show-notification:
1872 * @web_view: the #WebKitWebView
1873 * @notification: a #WebKitNotification
1875 * This signal is emitted when a notification should be presented to the
1876 * user. The @notification is kept alive until either: 1) the web page cancels it
1877 * or 2) a navigation happens.
1879 * The default handler will emit a notification using libnotify, if built with
1882 * Returns: %TRUE to stop other handlers from being invoked. %FALSE otherwise.
1886 signals[SHOW_NOTIFICATION] = g_signal_new(
1887 "show-notification",
1888 G_TYPE_FROM_CLASS(gObjectClass),
1890 G_STRUCT_OFFSET(WebKitWebViewClass, show_notification),
1891 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1892 g_cclosure_marshal_generic,
1894 WEBKIT_TYPE_NOTIFICATION);
1898 * WebKitWebView::run-color-chooser:
1899 * @web_view: the #WebKitWebView on which the signal is emitted
1900 * @request: a #WebKitColorChooserRequest
1902 * This signal is emitted when the user interacts with a <input
1903 * type='color' /> HTML element, requesting from WebKit to show
1904 * a dialog to select a color. To let the application know the details of
1905 * the color chooser, as well as to allow the client application to either
1906 * cancel the request or perform an actual color selection, the signal will
1907 * pass an instance of the #WebKitColorChooserRequest in the @request
1910 * It is possible to handle this request asynchronously by increasing the
1911 * reference count of the request.
1913 * The default signal handler will asynchronously run a regular
1914 * #GtkColorChooser for the user to interact with.
1916 * Returns: %TRUE to stop other handlers from being invoked for the event.
1917 * %FALSE to propagate the event further.
1921 signals[RUN_COLOR_CHOOSER] = g_signal_new(
1922 "run-color-chooser",
1923 G_TYPE_FROM_CLASS(webViewClass),
1925 G_STRUCT_OFFSET(WebKitWebViewClass, run_color_chooser),
1926 g_signal_accumulator_true_handled, nullptr,
1927 g_cclosure_marshal_generic,
1929 WEBKIT_TYPE_COLOR_CHOOSER_REQUEST);
1932 * WebKitWebView::show-option-menu:
1933 * @web_view: the #WebKitWebView on which the signal is emitted
1934 * @menu: the #WebKitOptionMenu
1935 * @event: the #GdkEvent that triggered the menu, or %NULL
1936 * @rectangle: the option element area
1938 * This signal is emitted when a select element in @web_view needs to display a
1939 * dropdown menu. This signal can be used to show a custom menu, using @menu to get
1940 * the details of all items that should be displayed. The area of the element in the
1941 * #WebKitWebView is given as @rectangle parameter, it can be used to position the
1942 * menu. If this was triggered by a user interaction, like a mouse click,
1943 * @event parameter provides the #GdkEvent.
1944 * To handle this signal asynchronously you should keep a ref of the @menu.
1946 * The default signal handler will pop up a #GtkMenu.
1948 * Returns: %TRUE to stop other handlers from being invoked for the event.
1949 * %FALSE to propagate the event further.
1953 signals[SHOW_OPTION_MENU] = g_signal_new(
1955 G_TYPE_FROM_CLASS(webViewClass),
1957 G_STRUCT_OFFSET(WebKitWebViewClass, show_option_menu),
1958 g_signal_accumulator_true_handled, nullptr,
1959 g_cclosure_marshal_generic,
1961 WEBKIT_TYPE_OPTION_MENU,
1962 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1963 GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
1964 #endif // PLATFORM(GTK)
1967 static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)
1969 if (!webView->priv->authenticationRequest)
1972 webkit_authentication_request_cancel(webView->priv->authenticationRequest.get());
1973 webView->priv->authenticationRequest.clear();
1976 void webkitWebViewCreatePage(WebKitWebView* webView, Ref<API::PageConfiguration>&& configuration)
1979 webkitWebViewBaseCreateWebPage(WEBKIT_WEB_VIEW_BASE(webView), WTFMove(configuration));
1981 webView->priv->view.reset(WKWPE::View::create(webkit_web_view_backend_get_wpe_backend(webView->priv->backend.get()), configuration.get()));
1985 WebPageProxy& webkitWebViewGetPage(WebKitWebView* webView)
1987 return getPage(webView);
1990 void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
1992 WebKitWebViewPrivate* priv = webView->priv;
1993 switch (loadEvent) {
1994 case WEBKIT_LOAD_STARTED:
1996 webkitWebViewCancelFaviconRequest(webView);
1997 webkitWebViewWatchForChangesInFavicon(webView);
1999 webkitWebViewCancelAuthenticationRequest(webView);
2000 priv->loadingResourcesMap.clear();
2001 priv->mainResource = nullptr;
2004 case WEBKIT_LOAD_COMMITTED: {
2005 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
2006 GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data()));
2007 webkitWebViewUpdateFaviconURI(webView, faviconURI.get());
2011 case WEBKIT_LOAD_FINISHED:
2012 webkitWebViewCancelAuthenticationRequest(webView);
2018 g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent);
2021 void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error)
2023 webkitWebViewCancelAuthenticationRequest(webView);
2025 gboolean returnValue;
2026 g_signal_emit(webView, signals[LOAD_FAILED], 0, loadEvent, failingURI, error, &returnValue);
2027 g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
2030 void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError* error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate)
2032 webkitWebViewCancelAuthenticationRequest(webView);
2034 WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context.get());
2035 if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) {
2036 gboolean returnValue;
2037 g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, failingURI, certificate, tlsErrors, &returnValue);
2039 g_signal_emit(webView, signals[LOAD_FAILED], 0, WEBKIT_LOAD_STARTED, failingURI, error, &returnValue);
2042 g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
2046 void webkitWebViewGetLoadDecisionForIcon(WebKitWebView* webView, const LinkIcon& icon, Function<void(bool)>&& completionHandler)
2048 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
2049 webkitFaviconDatabaseGetLoadDecisionForIcon(database, icon, getPage(webView).pageLoadState().activeURL(), WTFMove(completionHandler));
2052 void webkitWebViewSetIcon(WebKitWebView* webView, const LinkIcon& icon, API::Data& iconData)
2054 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
2055 webkitFaviconDatabaseSetIconForPageURL(database, icon, iconData, getPage(webView).pageLoadState().activeURL());
2059 WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, const WindowFeatures& windowFeatures, WebKitNavigationAction* navigationAction)
2061 WebKitWebView* newWebView;
2062 g_signal_emit(webView, signals[CREATE], 0, navigationAction, &newWebView);
2066 webkitWindowPropertiesUpdateFromWebWindowFeatures(newWebView->priv->windowProperties.get(), windowFeatures);
2068 RefPtr<WebPageProxy> newPage = &getPage(newWebView);
2069 return newPage.leakRef();
2072 void webkitWebViewReadyToShowPage(WebKitWebView* webView)
2074 g_signal_emit(webView, signals[READY_TO_SHOW], 0, NULL);
2077 void webkitWebViewRunAsModal(WebKitWebView* webView)
2079 g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL);
2081 webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE));
2084 // This is to suppress warnings about gdk_threads_leave and gdk_threads_enter.
2085 #pragma GCC diagnostic push
2086 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2087 gdk_threads_leave();
2090 g_main_loop_run(webView->priv->modalLoop.get());
2093 gdk_threads_enter();
2094 #pragma GCC diagnostic pop
2098 void webkitWebViewClosePage(WebKitWebView* webView)
2100 g_signal_emit(webView, signals[CLOSE], 0, NULL);
2103 void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message)
2105 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_ALERT, message);
2106 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2107 gboolean returnValue;
2108 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2111 bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message)
2113 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_CONFIRM, message);
2114 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2115 gboolean returnValue;
2116 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2117 return dialog.confirmed;
2120 CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText)
2122 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText);
2123 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2124 gboolean returnValue;
2125 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2129 bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message)
2131 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message);
2132 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2133 gboolean returnValue;
2134 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2135 return dialog.confirmed;
2138 bool webkitWebViewIsShowingScriptDialog(WebKitWebView* webView)
2140 if (!webView->priv->currentScriptDialog)
2143 // FIXME: Add API to ask the user in case default implementation is not being used.
2144 return webkitScriptDialogIsRunning(webView->priv->currentScriptDialog);
2147 String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView* webView)
2149 if (!webView->priv->currentScriptDialog)
2152 return String::fromUTF8(webView->priv->currentScriptDialog->message);
2155 void webkitWebViewSetCurrentScriptDialogUserInput(WebKitWebView* webView, const String& userInput)
2157 if (!webView->priv->currentScriptDialog)
2160 // FIXME: Add API to ask the user in case default implementation is not being used.
2161 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2162 webkitScriptDialogSetUserInput(webView->priv->currentScriptDialog, userInput);
2165 void webkitWebViewAcceptCurrentScriptDialog(WebKitWebView* webView)
2167 if (!webView->priv->currentScriptDialog)
2170 // FIXME: Add API to ask the user in case default implementation is not being used.
2171 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2172 webkitScriptDialogAccept(webView->priv->currentScriptDialog);
2175 void webkitWebViewDismissCurrentScriptDialog(WebKitWebView* webView)
2177 if (!webView->priv->currentScriptDialog)
2180 // FIXME: Add API to ask the user in case default implementation is not being used.
2181 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2182 webkitScriptDialogDismiss(webView->priv->currentScriptDialog);
2185 std::optional<WebKitScriptDialogType> webkitWebViewGetCurrentScriptDialogType(WebKitWebView* webView)
2187 if (!webView->priv->currentScriptDialog)
2188 return std::nullopt;
2190 return static_cast<WebKitScriptDialogType>(webView->priv->currentScriptDialog->type);
2193 void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
2195 gboolean returnValue;
2196 g_signal_emit(webView, signals[DECIDE_POLICY], 0, decision, type, &returnValue);
2199 void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermissionRequest* request)
2201 gboolean returnValue;
2202 g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue);
2205 void webkitWebViewMouseTargetChanged(WebKitWebView* webView, const WebHitTestResultData& hitTestResult, WebEvent::Modifiers modifiers)
2208 webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult.elementBoundingBox);
2211 WebKitWebViewPrivate* priv = webView->priv;
2212 if (priv->mouseTargetHitTestResult
2213 && priv->mouseTargetModifiers == modifiers
2214 && webkitHitTestResultCompare(priv->mouseTargetHitTestResult.get(), hitTestResult))
2217 priv->mouseTargetModifiers = modifiers;
2218 priv->mouseTargetHitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResult));
2219 g_signal_emit(webView, signals[MOUSE_TARGET_CHANGED], 0, priv->mouseTargetHitTestResult.get(), toPlatformModifiers(modifiers));
2222 void webkitWebViewHandleDownloadRequest(WebKitWebView* webView, DownloadProxy* downloadProxy)
2224 ASSERT(downloadProxy);
2225 GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy);
2226 webkitDownloadSetWebView(download.get(), webView);
2230 void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame)
2232 auto printOperation = adoptGRef(webkit_print_operation_new(webView));
2233 webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync);
2234 gboolean returnValue;
2235 g_signal_emit(webView, signals[PRINT], 0, printOperation.get(), &returnValue);
2239 WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, frame);
2240 if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL)
2242 g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
2246 void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request)
2248 WebKitWebViewPrivate* priv = webView->priv;
2249 bool isMainResource = frame->isMainFrame() && !priv->mainResource;
2250 WebKitWebResource* resource = webkitWebResourceCreate(frame, request, isMainResource);
2252 priv->mainResource = resource;
2253 priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
2254 g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
2257 WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2259 GRefPtr<WebKitWebResource> resource = webView->priv->loadingResourcesMap.get(resourceIdentifier);
2260 return resource.get();
2263 void webkitWebViewRemoveLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2265 WebKitWebViewPrivate* priv = webView->priv;
2266 ASSERT(priv->loadingResourcesMap.contains(resourceIdentifier));
2267 priv->loadingResourcesMap.remove(resourceIdentifier);
2270 void webkitWebViewEnterFullScreen(WebKitWebView* webView)
2272 #if ENABLE(FULLSCREEN_API)
2273 gboolean returnValue;
2274 g_signal_emit(webView, signals[ENTER_FULLSCREEN], 0, &returnValue);
2277 webkitWebViewBaseEnterFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2282 void webkitWebViewExitFullScreen(WebKitWebView* webView)
2284 #if ENABLE(FULLSCREEN_API)
2285 gboolean returnValue;
2286 g_signal_emit(webView, signals[LEAVE_FULLSCREEN], 0, &returnValue);
2289 webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2294 void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChooserRequest* request)
2296 gboolean returnValue;
2297 g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
2301 static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView)
2303 g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL);
2306 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2308 WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
2309 WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase);
2310 ASSERT(contextMenuProxy);
2312 GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2314 webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2316 GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2317 GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase));
2318 gboolean returnValue;
2319 g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue);
2323 Vector<WebContextMenuItemGlib> contextMenuItems;
2324 webkitContextMenuPopulate(contextMenu.get(), contextMenuItems);
2325 contextMenuProxy->populate(contextMenuItems);
2327 g_signal_connect(contextMenuProxy->gtkMenu(), "deactivate", G_CALLBACK(contextMenuDismissed), webView);
2329 // Clear the menu to make sure it's useless after signal emission.
2330 webkit_context_menu_remove_all(contextMenu.get());
2333 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2335 GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2337 webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2338 GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2339 gboolean returnValue;
2340 g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), nullptr, hitTestResult.get(), &returnValue);
2344 void webkitWebViewSubmitFormRequest(WebKitWebView* webView, WebKitFormSubmissionRequest* request)
2346 g_signal_emit(webView, signals[SUBMIT_FORM], 0, request);
2349 void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge)
2352 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2353 gboolean privateBrowsingEnabled = webView->priv->isEphemeral || webkit_settings_get_enable_private_browsing(webView->priv->settings.get());
2354 G_GNUC_END_IGNORE_DEPRECATIONS;
2356 gboolean privateBrowsingEnabled = webView->priv->isEphemeral;
2358 webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled));
2359 gboolean returnValue;
2360 g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue);
2363 void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecureContentEvent type)
2365 g_signal_emit(webView, signals[INSECURE_CONTENT_DETECTED], 0, type);
2368 bool webkitWebViewEmitShowNotification(WebKitWebView* webView, WebKitNotification* webNotification)
2371 g_signal_emit(webView, signals[SHOW_NOTIFICATION], 0, webNotification, &handled);
2376 bool webkitWebViewEmitRunColorChooser(WebKitWebView* webView, WebKitColorChooserRequest* request)
2379 g_signal_emit(webView, signals[RUN_COLOR_CHOOSER], 0, request, &handled);
2384 void webkitWebViewSelectionDidChange(WebKitWebView* webView)
2386 if (!webView->priv->editorState)
2389 webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView).editorState());
2392 void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView* webView, InstallMissingMediaPluginsPermissionRequest& request)
2395 GRefPtr<WebKitInstallMissingMediaPluginsPermissionRequest> installMediaPluginsPermissionRequest = adoptGRef(webkitInstallMissingMediaPluginsPermissionRequestCreate(request));
2396 webkitWebViewMakePermissionRequest(webView, WEBKIT_PERMISSION_REQUEST(installMediaPluginsPermissionRequest.get()));
2398 ASSERT_NOT_REACHED();
2402 WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webView)
2404 return webView->priv->websiteDataManager.get();
2408 bool webkitWebViewShowOptionMenu(WebKitWebView* webView, const IntRect& rect, WebKitOptionMenu* menu, const GdkEvent* event)
2410 GdkRectangle menuRect = rect;
2412 g_signal_emit(webView, signals[SHOW_OPTION_MENU], 0, menu, event, &menuRect, &handled);
2419 * webkit_web_view_get_backend:
2420 * @web_view: a #WebKitWebView
2422 * Get the #WebKitWebViewBackend of @web_view
2424 * Returns: (transfer none): the #WebKitWebViewBackend of @web_view
2428 WebKitWebViewBackend* webkit_web_view_get_backend(WebKitWebView* webView)
2430 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2432 return webView->priv->backend.get();
2437 * webkit_web_view_get_context:
2438 * @web_view: a #WebKitWebView
2440 * Gets the web context of @web_view.
2442 * Returns: (transfer none): the #WebKitWebContext of the view
2444 WebKitWebContext* webkit_web_view_get_context(WebKitWebView *webView)
2446 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2448 return webView->priv->context.get();
2452 * webkit_web_view_get_user_content_manager:
2453 * @web_view: a #WebKitWebView
2455 * Gets the user content manager associated to @web_view.
2457 * Returns: (transfer none): the #WebKitUserContentManager associated with the view
2461 WebKitUserContentManager* webkit_web_view_get_user_content_manager(WebKitWebView* webView)
2463 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2465 return webView->priv->userContentManager.get();
2469 * webkit_web_view_is_ephemeral:
2470 * @web_view: a #WebKitWebView
2472 * Get whether a #WebKitWebView is ephemeral. To create an ephemeral #WebKitWebView you need to
2473 * use g_object_new() and pass is-ephemeral property with %TRUE value. See
2474 * #WebKitWebView:is-ephemeral for more details.
2475 * If @web_view was created with a ephemeral #WebKitWebView:related-view or an
2476 * ephemeral #WebKitWebView:web-context it will also be ephemeral.
2478 * Returns: %TRUE if @web_view is ephemeral or %FALSE otherwise.
2482 gboolean webkit_web_view_is_ephemeral(WebKitWebView* webView)
2484 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2486 return webView->priv->isEphemeral;
2490 * webkit_web_view_is_controlled_by_automation:
2491 * @web_view: a #WebKitWebView
2493 * Get whether a #WebKitWebView was created with #WebKitWebView:is-controlled-by-automation
2494 * property enabled. Only #WebKitWebView<!-- -->s controlled by automation can be used in an
2495 * automation session.
2497 * Returns: %TRUE if @web_view is controlled by automation, or %FALSE otherwise.
2501 gboolean webkit_web_view_is_controlled_by_automation(WebKitWebView* webView)
2503 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2505 return webView->priv->isControlledByAutomation;
2509 * webkit_web_view_get_website_data_manager:
2510 * @web_view: a #WebKitWebView
2512 * Get the #WebKitWebsiteDataManager associated to @web_view. If @web_view is not ephemeral,
2513 * the returned #WebKitWebsiteDataManager will be the same as the #WebKitWebsiteDataManager
2514 * of @web_view's #WebKitWebContext.
2516 * Returns: (transfer none): a #WebKitWebsiteDataManager
2520 WebKitWebsiteDataManager* webkit_web_view_get_website_data_manager(WebKitWebView* webView)
2522 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2524 if (webView->priv->websiteDataManager)
2525 return webView->priv->websiteDataManager.get();
2527 return webkit_web_context_get_website_data_manager(webView->priv->context.get());
2531 * webkit_web_view_try_close:
2532 * @web_view: a #WebKitWebView
2534 * Tries to close the @web_view. This will fire the onbeforeunload event
2535 * to ask the user for confirmation to close the page. If there isn't an
2536 * onbeforeunload event handler or the user confirms to close the page,
2537 * the #WebKitWebView::close signal is emitted, otherwise nothing happens.
2541 void webkit_web_view_try_close(WebKitWebView *webView)
2543 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2544 if (getPage(webView).tryClose())
2545 webkitWebViewClosePage(webView);
2549 * webkit_web_view_load_uri:
2550 * @web_view: a #WebKitWebView
2551 * @uri: an URI string
2553 * Requests loading of the specified URI string.
2554 * You can monitor the load operation by connecting to
2555 * #WebKitWebView::load-changed signal.
2557 void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri)
2559 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2560 g_return_if_fail(uri);
2562 GUniquePtr<SoupURI> soupURI(soup_uri_new(uri));
2563 getPage(webView).loadRequest(URL(soupURI.get()));
2567 * webkit_web_view_load_html:
2568 * @web_view: a #WebKitWebView
2569 * @content: The HTML string to load
2570 * @base_uri: (allow-none): The base URI for relative locations or %NULL
2572 * Load the given @content string with the specified @base_uri.
2573 * If @base_uri is not %NULL, relative URLs in the @content will be
2574 * resolved against @base_uri and absolute local paths must be children of the @base_uri.
2575 * For security reasons absolute local paths that are not children of @base_uri
2576 * will cause the web process to terminate.
2577 * If you need to include URLs in @content that are local paths in a different
2578 * directory than @base_uri you can build a data URI for them. When @base_uri is %NULL,
2579 * it defaults to "about:blank". The mime type of the document will be "text/html".
2580 * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2582 void webkit_web_view_load_html(WebKitWebView* webView, const gchar* content, const gchar* baseURI)
2584 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2585 g_return_if_fail(content);
2587 getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(content), content ? strlen(content) : 0 }, "text/html"_s, "UTF-8"_s, String::fromUTF8(baseURI));
2591 * webkit_web_view_load_alternate_html:
2592 * @web_view: a #WebKitWebView
2593 * @content: the new content to display as the main page of the @web_view
2594 * @content_uri: the URI for the alternate page content
2595 * @base_uri: (allow-none): the base URI for relative locations or %NULL
2597 * Load the given @content string for the URI @content_uri.
2598 * This allows clients to display page-loading errors in the #WebKitWebView itself.
2599 * When this method is called from #WebKitWebView::load-failed signal to show an
2600 * error page, then the back-forward list is maintained appropriately.
2601 * For everything else this method works the same way as webkit_web_view_load_html().
2603 void webkit_web_view_load_alternate_html(WebKitWebView* webView, const gchar* content, const gchar* contentURI, const gchar* baseURI)
2605 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2606 g_return_if_fail(content);
2607 g_return_if_fail(contentURI);
2609 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)));
2613 * webkit_web_view_load_plain_text:
2614 * @web_view: a #WebKitWebView
2615 * @plain_text: The plain text to load
2617 * Load the specified @plain_text string into @web_view. The mime type of
2618 * document will be "text/plain". You can monitor the load
2619 * operation by connecting to #WebKitWebView::load-changed signal.
2621 void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainText)
2623 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2624 g_return_if_fail(plainText);
2626 getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(plainText), plainText ? strlen(plainText) : 0 }, "text/plain"_s, "UTF-8"_s, blankURL().string());
2630 * webkit_web_view_load_bytes:
2631 * @web_view: a #WebKitWebView
2632 * @bytes: input data to load
2633 * @mime_type: (allow-none): the MIME type of @bytes, or %NULL
2634 * @encoding: (allow-none): the character encoding of @bytes, or %NULL
2635 * @base_uri: (allow-none): the base URI for relative locations or %NULL
2637 * Load the specified @bytes into @web_view using the given @mime_type and @encoding.
2638 * When @mime_type is %NULL, it defaults to "text/html".
2639 * When @encoding is %NULL, it defaults to "UTF-8".
2640 * When @base_uri is %NULL, it defaults to "about:blank".
2641 * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2645 void webkit_web_view_load_bytes(WebKitWebView* webView, GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI)
2647 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2648 g_return_if_fail(bytes);
2650 gsize bytesDataSize;
2651 gconstpointer bytesData = g_bytes_get_data(bytes, &bytesDataSize);
2652 g_return_if_fail(bytesDataSize);
2654 getPage(webView).loadData({ reinterpret_cast<const uint8_t*>(bytesData), bytesDataSize }, mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
2655 encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), String::fromUTF8(baseURI));
2659 * webkit_web_view_load_request:
2660 * @web_view: a #WebKitWebView
2661 * @request: a #WebKitURIRequest to load
2663 * Requests loading of the specified #WebKitURIRequest.
2664 * You can monitor the load operation by connecting to
2665 * #WebKitWebView::load-changed signal.
2667 void webkit_web_view_load_request(WebKitWebView* webView, WebKitURIRequest* request)
2669 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2670 g_return_if_fail(WEBKIT_IS_URI_REQUEST(request));
2672 ResourceRequest resourceRequest;
2673 webkitURIRequestGetResourceRequest(request, resourceRequest);
2674 getPage(webView).loadRequest(WTFMove(resourceRequest));
2678 * webkit_web_view_get_page_id:
2679 * @web_view: a #WebKitWebView
2681 * Get the identifier of the #WebKitWebPage corresponding to
2682 * the #WebKitWebView
2684 * Returns: the page ID of @web_view.
2686 guint64 webkit_web_view_get_page_id(WebKitWebView* webView)
2688 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2690 return getPage(webView).pageID();
2694 * webkit_web_view_get_title:
2695 * @web_view: a #WebKitWebView
2697 * Gets the value of the #WebKitWebView:title property.
2698 * You can connect to notify::title signal of @web_view to
2699 * be notified when the title has been received.
2701 * Returns: The main frame document title of @web_view.
2703 const gchar* webkit_web_view_get_title(WebKitWebView* webView)
2705 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2707 return webView->priv->title.data();
2711 * webkit_web_view_reload:
2712 * @web_view: a #WebKitWebView
2714 * Reloads the current contents of @web_view.
2715 * See also webkit_web_view_reload_bypass_cache().
2717 void webkit_web_view_reload(WebKitWebView* webView)
2719 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2721 getPage(webView).reload({ });
2725 * webkit_web_view_reload_bypass_cache:
2726 * @web_view: a #WebKitWebView
2728 * Reloads the current contents of @web_view without
2729 * using any cached data.
2731 void webkit_web_view_reload_bypass_cache(WebKitWebView* webView)
2733 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2735 getPage(webView).reload(ReloadOption::FromOrigin);
2739 * webkit_web_view_stop_loading:
2740 * @web_view: a #WebKitWebView
2742 * Stops any ongoing loading operation in @web_view.
2743 * This method does nothing if no content is being loaded.
2744 * If there is a loading operation in progress, it will be cancelled and
2745 * #WebKitWebView::load-failed signal will be emitted with
2746 * %WEBKIT_NETWORK_ERROR_CANCELLED error.
2748 void webkit_web_view_stop_loading(WebKitWebView* webView)
2750 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2752 getPage(webView).stopLoading();
2756 * webkit_web_view_is_loading:
2757 * @web_view: a #WebKitWebView
2759 * Gets the value of the #WebKitWebView:is-loading property.
2760 * You can monitor when a #WebKitWebView is loading a page by connecting to
2761 * notify::is-loading signal of @web_view. This is useful when you are
2762 * interesting in knowing when the view is loading something but not in the
2763 * details about the status of the load operation, for example to start a spinner
2764 * when the view is loading a page and stop it when it finishes.
2766 * Returns: %TRUE if @web_view is loading a page or %FALSE otherwise.
2768 gboolean webkit_web_view_is_loading(WebKitWebView* webView)
2770 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2772 return webView->priv->isLoading;
2776 * webkit_web_view_is_playing_audio:
2777 * @web_view: a #WebKitWebView
2779 * Gets the value of the #WebKitWebView:is-playing-audio property.
2780 * You can monitor when a page in a #WebKitWebView is playing audio by
2781 * connecting to the notify::is-playing-audio signal of @web_view. This
2782 * is useful when the application wants to provide visual feedback when a
2783 * page is producing sound.
2785 * Returns: %TRUE if a page in @web_view is playing audio or %FALSE otherwise.
2789 gboolean webkit_web_view_is_playing_audio(WebKitWebView* webView)
2791 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2793 return getPage(webView).isPlayingAudio();
2797 * webkit_web_view_go_back:
2798 * @web_view: a #WebKitWebView
2800 * Loads the previous history item.
2801 * You can monitor the load operation by connecting to
2802 * #WebKitWebView::load-changed signal.
2804 void webkit_web_view_go_back(WebKitWebView* webView)
2806 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2808 getPage(webView).goBack();
2812 * webkit_web_view_can_go_back:
2813 * @web_view: a #WebKitWebView
2815 * Determines whether @web_view has a previous history item.
2817 * Returns: %TRUE if able to move back or %FALSE otherwise.
2819 gboolean webkit_web_view_can_go_back(WebKitWebView* webView)
2821 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2823 return !!getPage(webView).backForwardList().backItem();
2827 * webkit_web_view_go_forward:
2828 * @web_view: a #WebKitWebView
2830 * Loads the next history item.
2831 * You can monitor the load operation by connecting to
2832 * #WebKitWebView::load-changed signal.
2834 void webkit_web_view_go_forward(WebKitWebView* webView)
2836 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2838 getPage(webView).goForward();
2842 * webkit_web_view_can_go_forward:
2843 * @web_view: a #WebKitWebView
2845 * Determines whether @web_view has a next history item.
2847 * Returns: %TRUE if able to move forward or %FALSE otherwise.
2849 gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
2851 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2853 return !!getPage(webView).backForwardList().forwardItem();
2857 * webkit_web_view_get_uri:
2858 * @web_view: a #WebKitWebView
2860 * Returns the current active URI of @web_view. The active URI might change during
2865 * When nothing has been loaded yet on @web_view the active URI is %NULL.
2866 * </para></listitem>
2868 * When a new load operation starts the active URI is the requested URI:
2871 * If the load operation was started by webkit_web_view_load_uri(),
2872 * the requested URI is the given one.
2873 * </para></listitem>
2875 * If the load operation was started by webkit_web_view_load_html(),
2876 * the requested URI is "about:blank".
2877 * </para></listitem>
2879 * If the load operation was started by webkit_web_view_load_alternate_html(),
2880 * the requested URI is content URI provided.
2881 * </para></listitem>
2883 * If the load operation was started by webkit_web_view_go_back() or
2884 * webkit_web_view_go_forward(), the requested URI is the original URI
2885 * of the previous/next item in the #WebKitBackForwardList of @web_view.
2886 * </para></listitem>
2888 * If the load operation was started by
2889 * webkit_web_view_go_to_back_forward_list_item(), the requested URI
2890 * is the opriginal URI of the given #WebKitBackForwardListItem.
2891 * </para></listitem>
2893 * </para></listitem>
2895 * If there is a server redirection during the load operation,
2896 * the active URI is the redirected URI. When the signal
2897 * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_REDIRECTED
2898 * event, the active URI is already updated to the redirected URI.
2899 * </para></listitem>
2901 * When the signal #WebKitWebView::load-changed is emitted
2902 * with %WEBKIT_LOAD_COMMITTED event, the active URI is the final
2903 * one and it will not change unless a new load operation is started
2904 * or a navigation action within the same page is performed.
2905 * </para></listitem>
2908 * You can monitor the active URI by connecting to the notify::uri
2909 * signal of @web_view.
2911 * Returns: the current active URI of @web_view or %NULL
2912 * if nothing has been loaded yet.
2914 const gchar* webkit_web_view_get_uri(WebKitWebView* webView)
2916 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2918 return webView->priv->activeURI.data();
2923 * webkit_web_view_get_favicon:
2924 * @web_view: a #WebKitWebView
2926 * Returns favicon currently associated to @web_view, if any. You can
2927 * connect to notify::favicon signal of @web_view to be notified when
2928 * the favicon is available.
2930 * Returns: (transfer none): a pointer to a #cairo_surface_t with the
2931 * favicon or %NULL if there's no icon associated with @web_view.
2933 cairo_surface_t* webkit_web_view_get_favicon(WebKitWebView* webView)
2935 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2936 if (webView->priv->activeURI.isNull())
2939 return webView->priv->favicon.get();
2944 * webkit_web_view_get_custom_charset:
2945 * @web_view: a #WebKitWebView
2947 * Returns the current custom character encoding name of @web_view.
2949 * Returns: the current custom character encoding name or %NULL if no
2950 * custom character encoding has been set.
2952 const gchar* webkit_web_view_get_custom_charset(WebKitWebView* webView)
2954 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2956 String customTextEncoding = getPage(webView).customTextEncodingName();
2957 if (customTextEncoding.isEmpty())
2960 webView->priv->customTextEncoding = customTextEncoding.utf8();
2961 return webView->priv->customTextEncoding.data();
2965 * webkit_web_view_set_custom_charset:
2966 * @web_view: a #WebKitWebView
2967 * @charset: (allow-none): a character encoding name or %NULL
2969 * Sets the current custom character encoding override of @web_view. The custom
2970 * character encoding will override any text encoding detected via HTTP headers or
2971 * META tags. Calling this method will stop any current load operation and reload the
2972 * current page. Setting the custom character encoding to %NULL removes the character
2973 * encoding override.
2975 void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* charset)
2977 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2979 getPage(webView).setCustomTextEncodingName(String::fromUTF8(charset));
2983 * webkit_web_view_get_estimated_load_progress:
2984 * @web_view: a #WebKitWebView
2986 * Gets the value of the #WebKitWebView:estimated-load-progress property.
2987 * You can monitor the estimated progress of a load operation by
2988 * connecting to the notify::estimated-load-progress signal of @web_view.
2990 * Returns: an estimate of the of the percent complete for a document
2991 * load as a range from 0.0 to 1.0.
2993 gdouble webkit_web_view_get_estimated_load_progress(WebKitWebView* webView)
2995 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2996 return getPage(webView).pageLoadState().estimatedProgress();
3000 * webkit_web_view_get_back_forward_list:
3001 * @web_view: a #WebKitWebView
3003 * Obtains the #WebKitBackForwardList associated with the given #WebKitWebView. The
3004 * #WebKitBackForwardList is owned by the #WebKitWebView.
3006 * Returns: (transfer none): the #WebKitBackForwardList
3008 WebKitBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView)
3010 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3012 return webView->priv->backForwardList.get();
3016 * webkit_web_view_go_to_back_forward_list_item:
3017 * @web_view: a #WebKitWebView
3018 * @list_item: a #WebKitBackForwardListItem
3020 * Loads the specific history item @list_item.
3021 * You can monitor the load operation by connecting to
3022 * #WebKitWebView::load-changed signal.
3024 void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKitBackForwardListItem* listItem)
3026 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3027 g_return_if_fail(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(listItem));
3029 getPage(webView).goToBackForwardItem(*webkitBackForwardListItemGetItem(listItem));
3033 * webkit_web_view_set_settings:
3034 * @web_view: a #WebKitWebView
3035 * @settings: a #WebKitSettings
3037 * Sets the #WebKitSettings to be applied to @web_view. The
3038 * existing #WebKitSettings of @web_view will be replaced by
3039 * @settings. New settings are applied immediately on @web_view.
3040 * The same #WebKitSettings object can be shared
3041 * by multiple #WebKitWebView<!-- -->s.
3043 void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings)
3045 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3046 g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
3048 if (webView->priv->settings == settings)
3051 // The "settings" property is set on construction, and in that
3052 // case webkit_web_view_set_settings() will be called *before*
3053 // any settings have been assigned. In that case there are no
3054 // signal handlers to disconnect.
3055 if (webView->priv->settings)
3056 webkitWebViewDisconnectSettingsSignalHandlers(webView);
3058 webView->priv->settings = settings;
3059 webkitWebViewUpdateSettings(webView);
3060 g_object_notify(G_OBJECT(webView), "settings");
3064 * webkit_web_view_get_settings:
3065 * @web_view: a #WebKitWebView
3067 * Gets the #WebKitSettings currently applied to @web_view.
3068 * If no other #WebKitSettings have been explicitly applied to
3069 * @web_view with webkit_web_view_set_settings(), the default
3070 * #WebKitSettings will be returned. This method always returns
3071 * a valid #WebKitSettings object.
3072 * To modify any of the @web_view settings, you can either create
3073 * a new #WebKitSettings object with webkit_settings_new(), setting
3074 * the desired preferences, and then replace the existing @web_view
3075 * settings with webkit_web_view_set_settings() or get the existing
3076 * @web_view settings and update it directly. #WebKitSettings objects
3077 * can be shared by multiple #WebKitWebView<!-- -->s, so modifying
3078 * the settings of a #WebKitWebView would affect other
3079 * #WebKitWebView<!-- -->s using the same #WebKitSettings.
3081 * Returns: (transfer none): the #WebKitSettings attached to @web_view
3083 WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView)
3085 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3086 return webView->priv->settings.get();
3090 * webkit_web_view_get_window_properties:
3091 * @web_view: a #WebKitWebView
3093 * Get the #WebKitWindowProperties object containing the properties
3094 * that the window containing @web_view should have.
3096 * Returns: (transfer none): the #WebKitWindowProperties of @web_view
3098 WebKitWindowProperties* webkit_web_view_get_window_properties(WebKitWebView* webView)
3100 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3102 return webView->priv->windowProperties.get();
3106 * webkit_web_view_set_zoom_level:
3107 * @web_view: a #WebKitWebView
3108 * @zoom_level: the zoom level
3110 * Set the zoom level of @web_view, i.e. the factor by which the
3111 * view contents are scaled with respect to their original size.
3113 void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel)
3115 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3117 if (webkit_web_view_get_zoom_level(webView) == zoomLevel)
3120 auto& page = getPage(webView);
3121 page.scalePage(1.0, IntPoint()); // Reset page scale when zoom level is changed
3122 if (webkit_settings_get_zoom_text_only(webView->priv->settings.get()))
3123 page.setTextZoomFactor(zoomLevel);
3125 page.setPageZoomFactor(zoomLevel);
3126 g_object_notify(G_OBJECT(webView), "zoom-level");
3130 * webkit_web_view_get_zoom_level:
3131 * @web_view: a #WebKitWebView
3133 * Get the zoom level of @web_view, i.e. the factor by which the
3134 * view contents are scaled with respect to their original size.
3136 * Returns: the current zoom level of @web_view
3138 gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView)
3140 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1);
3142 auto& page = getPage(webView);
3143 gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get());
3144 return zoomTextOnly ? page.textZoomFactor() : page.pageZoomFactor();
3148 * webkit_web_view_can_execute_editing_command:
3149 * @web_view: a #WebKitWebView
3150 * @command: the command to check
3151 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3152 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3153 * @user_data: (closure): the data to pass to callback function
3155 * Asynchronously check if it is possible to execute the given editing command.
3157 * When the operation is finished, @callback will be called. You can then call
3158 * webkit_web_view_can_execute_editing_command_finish() to get the result of the operation.
3160 void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const char* command, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3162 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3163 g_return_if_fail(command);
3165 GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
3166 getPage(webView).validateCommand(String::fromUTF8(command), [task = WTFMove(task)](const String&, bool isEnabled, int32_t, WebKit::CallbackBase::Error) {
3167 g_task_return_boolean(task.get(), isEnabled);
3172 * webkit_web_view_can_execute_editing_command_finish:
3173 * @web_view: a #WebKitWebView
3174 * @result: a #GAsyncResult
3175 * @error: return location for error or %NULL to ignore
3177 * Finish an asynchronous operation started with webkit_web_view_can_execute_editing_command().
3179 * Returns: %TRUE if the editing command can be executed or %FALSE otherwise
3181 gboolean webkit_web_view_can_execute_editing_command_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3183 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3184 g_return_val_if_fail(g_task_is_valid(result, webView), FALSE);
3186 return g_task_propagate_boolean(G_TASK(result), error);
3190 * webkit_web_view_execute_editing_command:
3191 * @web_view: a #WebKitWebView
3192 * @command: the command to execute
3194 * Request to execute the given @command for @web_view. You can use
3195 * webkit_web_view_can_execute_editing_command() to check whether
3196 * it's possible to execute the command.
3198 void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* command)
3200 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3201 g_return_if_fail(command);
3203 getPage(webView).executeEditCommand(String::fromUTF8(command));
3207 * webkit_web_view_execute_editing_command_with_argument:
3208 * @web_view: a #WebKitWebView
3209 * @command: the command to execute
3210 * @argument: the command argument
3212 * Request to execute the given @command with @argument for @web_view. You can use
3213 * webkit_web_view_can_execute_editing_command() to check whether
3214 * it's possible to execute the command.
3218 void webkit_web_view_execute_editing_command_with_argument(WebKitWebView* webView, const char* command, const char* argument)
3220 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3221 g_return_if_fail(command);
3222 g_return_if_fail(argument);
3224 getPage(webView).executeEditCommand(String::fromUTF8(command), String::fromUTF8(argument));
3228 * webkit_web_view_get_find_controller:
3229 * @web_view: the #WebKitWebView
3231 * Gets the #WebKitFindController that will allow the caller to query
3232 * the #WebKitWebView for the text to look for.
3234 * Returns: (transfer none): the #WebKitFindController associated to
3235 * this particular #WebKitWebView.
3237 WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView)
3239 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3241 if (!webView->priv->findController)
3242 webView->priv->findController = adoptGRef(WEBKIT_FIND_CONTROLLER(g_object_new(WEBKIT_TYPE_FIND_CONTROLLER, "web-view", webView, NULL)));
3244 return webView->priv->findController.get();
3249 * webkit_web_view_get_javascript_global_context: (skip)
3250 * @web_view: a #WebKitWebView
3252 * Get the global JavaScript context used by @web_view to deserialize the
3253 * result values of scripts executed with webkit_web_view_run_javascript().
3255 * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
3256 * the result values of scripts.
3258 * Deprecated: 2.22: Use jsc_value_get_context() instead.
3260 JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
3262 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3264 // We keep a reference to the js context in the view only when this method is called
3265 // for backwards compatibility.
3266 if (!webView->priv->jsContext)
3267 webView->priv->jsContext = SharedJavascriptContext::singleton().getOrCreateContext();
3268 return jscContextGetJSContext(webView->priv->jsContext.get());
3272 static void webkitWebViewRunJavaScriptCallback(API::SerializedScriptValue* wkSerializedScriptValue, const ExceptionDetails& exceptionDetails, GTask* task)
3274 if (g_task_return_error_if_cancelled(task))
3277 if (!wkSerializedScriptValue) {
3278 StringBuilder builder;
3279 if (!exceptionDetails.sourceURL.isEmpty()) {
3280 builder.append(exceptionDetails.sourceURL);
3281 if (exceptionDetails.lineNumber > 0) {
3282 builder.append(':');
3283 builder.appendNumber(exceptionDetails.lineNumber);
3285 if (exceptionDetails.columnNumber > 0) {
3286 builder.append(':');
3287 builder.appendNumber(exceptionDetails.columnNumber);
3289 builder.appendLiteral(": ");
3291 builder.append(exceptionDetails.message);
3292 g_task_return_new_error(task, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED,
3293 "%s", builder.toString().utf8().data());
3297 g_task_return_pointer(task, webkitJavascriptResultCreate(wkSerializedScriptValue->internalRepresentation()),
3298 reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
3302 * webkit_web_view_run_javascript:
3303 * @web_view: a #WebKitWebView
3304 * @script: the script to run
3305 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3306 * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
3307 * @user_data: (closure): the data to pass to callback function
3309 * Asynchronously run @script in the context of the current page in @web_view. If
3310 * WebKitSettings:enable-javascript is FALSE, this method will do nothing.
3312 * When the operation is finished, @callback will be called. You can then call
3313 * webkit_web_view_run_javascript_finish() to get the result of the operation.
3315 void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3317 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3318 g_return_if_fail(script);
3320 GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
3321 getPage(webView).runJavaScriptInMainFrame(String::fromUTF8(script), true, [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, bool, const ExceptionDetails& exceptionDetails, WebKit::CallbackBase::Error) {
3322 webkitWebViewRunJavaScriptCallback(serializedScriptValue, exceptionDetails, task.get());
3327 * webkit_web_view_run_javascript_finish:
3328 * @web_view: a #WebKitWebView
3329 * @result: a #GAsyncResult
3330 * @error: return location for error or %NULL to ignore
3332 * Finish an asynchronous operation started with webkit_web_view_run_javascript().
3334 * This is an example of using webkit_web_view_run_javascript() with a script returning
3337 * <informalexample><programlisting>
3339 * web_view_javascript_finished (GObject *object,
3340 * GAsyncResult *result,
3341 * gpointer user_data)
3343 * WebKitJavascriptResult *js_result;
3345 * GError *error = NULL;
3347 * js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
3349 * g_warning ("Error running javascript: %s", error->message);
3350 * g_error_free (error);
3354 * value = webkit_javascript_result_get_js_value (js_result);
3355 * if (jsc_value_is_string (value)) {
3356 * JSCException *exception;
3359 * str_value = jsc_value_to_string (value);
3360 * exception = jsc_context_get_exception (jsc_value_get_context (value));
3362 * g_warning ("Error running javascript: %s", jsc_exception_get_message (exception));
3364 * g_print ("Script result: %s\n", str_value);
3365 * g_free (str_value);
3367 * g_warning ("Error running javascript: unexpected return value");
3369 * webkit_javascript_result_unref (js_result);
3373 * web_view_get_link_url (WebKitWebView *web_view,
3374 * const gchar *link_id)
3378 * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id);
3379 * webkit_web_view_run_javascript (web_view, script, NULL, web_view_javascript_finished, NULL);
3382 * </programlisting></informalexample>
3384 * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
3385 * or %NULL in case of error
3387 WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3389 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3390 g_return_val_if_fail(g_task_is_valid(result, webView), nullptr);
3392 return static_cast<WebKitJavascriptResult*>(g_task_propagate_pointer(G_TASK(result), error));
3396 * webkit_web_view_run_javascript_in_world:
3397 * @web_view: a #WebKitWebView
3398 * @script: the script to run
3399 * @world_name: the name of a #WebKitScriptWorld
3400 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3401 * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
3402 * @user_data: (closure): the data to pass to callback function
3404 * Asynchronously run @script in the script world with name @world_name of the current page context in @web_view.
3405 * If WebKitSettings:enable-javascript is FALSE, this method will do nothing.
3407 * When the operation is finished, @callback will be called. You can then call
3408 * webkit_web_view_run_javascript_in_world_finish() to get the result of the operation.
3412 void webkit_web_view_run_javascript_in_world(WebKitWebView* webView, const gchar* script, const char* worldName, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3414 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3415 g_return_if_fail(script);
3416 g_return_if_fail(worldName);
3418 GRefPtr<GTask> task = adoptGRef(g_task_new(webView, cancellable, callback, userData));
3419 getPage(webView).runJavaScriptInMainFrameScriptWorld(String::fromUTF8(script), true, String::fromUTF8(worldName), [task = WTFMove(task)](API::SerializedScriptValue* serializedScriptValue, bool, const ExceptionDetails& exceptionDetails, WebKit::CallbackBase::Error) {
3420 webkitWebViewRunJavaScriptCallback(serializedScriptValue, exceptionDetails, task.get());
3425 * webkit_web_view_run_javascript_in_world_finish:
3426 * @web_view: a #WebKitWebView
3427 * @result: a #GAsyncResult
3428 * @error: return location for error or %NULL to ignore
3430 * Finish an asynchronous operation started with webkit_web_view_run_javascript_in_world().
3432 * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
3433 * or %NULL in case of error
3437 WebKitJavascriptResult* webkit_web_view_run_javascript_in_world_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3439 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3440 g_return_val_if_fail(g_task_is_valid(result, webView), nullptr);
3442 return static_cast<WebKitJavascriptResult*>(g_task_propagate_pointer(G_TASK(result), error));
3445 static void resourcesStreamReadCallback(GObject* object, GAsyncResult* result, gpointer userData)
3447 GRefPtr<GTask> task = adoptGRef(G_TASK(userData));
3450 g_output_stream_splice_finish(G_OUTPUT_STREAM(object), result, &error);
3452 g_task_return_error(task.get(), error);
3456 WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get()));
3457 gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object));
3458 getPage(webView).runJavaScriptInMainFrame(String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), true,
3459 [task](API::SerializedScriptValue* serializedScriptValue, bool, const ExceptionDetails& exceptionDetails, WebKit::CallbackBase::Error) {
3460 webkitWebViewRunJavaScriptCallback(serializedScriptValue, exceptionDetails, task.get());
3465 * webkit_web_view_run_javascript_from_gresource:
3466 * @web_view: a #WebKitWebView
3467 * @resource: the location of the resource to load
3468 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3469 * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
3470 * @user_data: (closure): the data to pass to callback function
3472 * Asynchronously run the script from @resource in the context of the
3473 * current page in @web_view.
3475 * When the operation is finished, @callback will be called. You can
3476 * then call webkit_web_view_run_javascript_from_gresource_finish() to get the result
3479 void webkit_web_view_run_javascript_from_gresource(WebKitWebView* webView, const gchar* resource, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3481 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3482 g_return_if_fail(resource);
3485 GRefPtr<GInputStream> inputStream = adoptGRef(g_resources_open_stream(resource, G_RESOURCE_LOOKUP_FLAGS_NONE, &error));
3487 g_task_report_error(webView, callback, userData, 0, error);
3491 GTask* task = g_task_new(webView, cancellable, callback, userData);
3492 GRefPtr<GOutputStream> outputStream = adoptGRef(g_memory_output_stream_new(0, 0, fastRealloc, fastFree));
3493 g_output_stream_splice_async(outputStream.get(), inputStream.get(),
3494 static_cast<GOutputStreamSpliceFlags>(G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET),
3495 G_PRIORITY_DEFAULT, cancellable, resourcesStreamReadCallback, task);
3499 * webkit_web_view_run_javascript_from_gresource_finish:
3500 * @web_view: a #WebKitWebView
3501 * @result: a #GAsyncResult
3502 * @error: return location for error or %NULL to ignore
3504 * Finish an asynchronous operation started with webkit_web_view_run_javascript_from_gresource().
3506 * Check webkit_web_view_run_javascript_finish() for a usage example.
3508 * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
3509 * or %NULL in case of error
3511 WebKitJavascriptResult* webkit_web_view_run_javascript_from_gresource_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3513 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3514 g_return_val_if_fail(g_task_is_valid(result, webView), 0);
3516 return static_cast<WebKitJavascriptResult*>(g_task_propagate_pointer(G_TASK(result), error));
3520 * webkit_web_view_get_main_resource:
3521 * @web_view: a #WebKitWebView
3523 * Return the main resource of @web_view.
3525 * Returns: (transfer none): the main #WebKitWebResource of the view
3526 * or %NULL if nothing has been loaded.
3528 WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView)
3530 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3532 return webView->priv->mainResource.get();
3537 * webkit_web_view_get_inspector:
3538 * @web_view: a #WebKitWebView
3540 * Get the #WebKitWebInspector associated to @web_view
3542 * Returns: (transfer none): the #WebKitWebInspector of @web_view
3544 WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView)
3546 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3548 if (!webView->priv->inspector)
3549 webView->priv->inspector = adoptGRef(webkitWebInspectorCreate(getPage(webView).inspector()));
3551 return webView->priv->inspector.get();
3556 * webkit_web_view_can_show_mime_type:
3557 * @web_view: a #WebKitWebView
3558 * @mime_type: a MIME type
3560 * Whether or not a MIME type can be displayed in @web_view.
3562 * Returns: %TRUE if the MIME type @mime_type can be displayed or %FALSE otherwise
3564 gboolean webkit_web_view_can_show_mime_type(WebKitWebView* webView, const char* mimeType)
3566 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3567 g_return_val_if_fail(mimeType, FALSE);
3569 return getPage(webView).canShowMIMEType(String::fromUTF8(mimeType));
3572 struct ViewSaveAsyncData {
3573 RefPtr<API::Data> webData;
3574 GRefPtr<GFile> file;
3576 WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ViewSaveAsyncData)
3578 static void fileReplaceContentsCallback(GObject* object, GAsyncResult* result, gpointer data)
3580 GRefPtr<GTask> task = adoptGRef(G_TASK(data));
3582 if (!g_file_replace_contents_finish(G_FILE(object), result, 0, &error)) {
3583 g_task_return_error(task.get(), error);
3587 g_task_return_boolean(task.get(), TRUE);
3590 static void getContentsAsMHTMLDataCallback(API::Data* wkData, GTask* taskPtr)
3592 auto task = adoptGRef(taskPtr);
3593 if (g_task_return_error_if_cancelled(task.get()))
3596 ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_task_get_task_data(task.get()));
3597 // We need to retain the data until the asyncronous process
3598 // initiated by the user has finished completely.
3599 data->webData = wkData;
3601 // If we are saving to a file we need to write the data on disk before finishing.
3602 if (g_task_get_source_tag(task.get()) == webkit_web_view_save_to_file) {
3603 ASSERT(G_IS_FILE(data->file.get()));
3604 GCancellable* cancellable = g_task_get_cancellable(task.get());
3605 g_file_replace_contents_async(data->file.get(), reinterpret_cast<const gchar*>(data->webData->bytes()), data->webData->size(),
3606 0, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, cancellable, fileReplaceContentsCallback, task.leakRef());
3610 g_task_return_boolean(task.get(), TRUE);
3614 * webkit_web_view_save:
3615 * @web_view: a #WebKitWebView
3616 * @save_mode: the #WebKitSaveMode specifying how the web page should be saved.
3617 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3618 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3619 * @user_data: (closure): the data to pass to callback function
3621 * Asynchronously save the current web page associated to the
3622 * #WebKitWebView into a self-contained format using the mode
3623 * specified in @save_mode.
3625 * When the operation is finished, @callback will be called. You can
3626 * then call webkit_web_view_save_finish() to get the result of the
3629 void webkit_web_view_save(WebKitWebView* webView, WebKitSaveMode saveMode, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3631 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3633 // We only support MHTML at the moment.
3634 g_return_if_fail(saveMode == WEBKIT_SAVE_MODE_MHTML);
3636 GTask* task = g_task_new(webView, cancellable, callback, userData);
3637 g_task_set_source_tag(task, reinterpret_cast<gpointer>(webkit_web_view_save));
3638 g_task_set_task_data(task, createViewSaveAsyncData(), reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
3639 getPage(webView).getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) {
3640 getContentsAsMHTMLDataCallback(data, task);
3645 * webkit_web_view_save_finish:
3646 * @web_view: a #WebKitWebView
3647 * @result: a #GAsyncResult
3648 * @error: return location for error or %NULL to ignore
3650 * Finish an asynchronous operation started with webkit_web_view_save().
3652 * Returns: (transfer full): a #GInputStream with the result of saving
3653 * the current web page or %NULL in case of error.
3655 GInputStream* webkit_web_view_save_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3657 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3658 g_return_val_if_fail(g_task_is_valid(result, webView), 0);
3660 GTask* task = G_TASK(result);
3661 if (!g_task_propagate_boolean(task, error))
3664 GInputStream* dataStream = g_memory_input_stream_new();
3665 ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_task_get_task_data(task));
3666 gsize length = data->webData->size();
3668 g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(dataStream), g_memdup(data->webData->bytes(), length), length, g_free);
3674 * webkit_web_view_save_to_file:
3675 * @web_view: a #WebKitWebView
3676 * @file: the #GFile where the current web page should be saved to.
3677 * @save_mode: the #WebKitSaveMode specifying how the web page should be saved.
3678 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3679 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3680 * @user_data: (closure): the data to pass to callback function
3682 * Asynchronously save the current web page associated to the
3683 * #WebKitWebView into a self-contained format using the mode
3684 * specified in @save_mode and writing it to @file.
3686 * When the operation is finished, @callback will be called. You can
3687 * then call webkit_web_view_save_to_file_finish() to get the result of the
3690 void webkit_web_view_save_to_file(WebKitWebView* webView, GFile* file, WebKitSaveMode saveMode, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3692 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3693 g_return_if_fail(G_IS_FILE(file));
3695 // We only support MHTML at the moment.
3696 g_return_if_fail(saveMode == WEBKIT_SAVE_MODE_MHTML);
3698 GTask* task = g_task_new(webView, cancellable, callback, userData);
3699 g_task_set_source_tag(task, reinterpret_cast<gpointer>(webkit_web_view_save_to_file));
3700 ViewSaveAsyncData* data = createViewSaveAsyncData();
3702 g_task_set_task_data(task, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData));
3704 getPage(webView).getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) {
3705 getContentsAsMHTMLDataCallback(data, task);
3710 * webkit_web_view_save_to_file_finish:
3711 * @web_view: a #WebKitWebView
3712 * @result: a #GAsyncResult
3713 * @error: return location for error or %NULL to ignore
3715 * Finish an asynchronous operation started with webkit_web_view_save_to_file().
3717 * Returns: %TRUE if the web page was successfully saved to a file or %FALSE otherwise.
3719 gboolean webkit_web_view_save_to_file_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3721 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3722 g_return_val_if_fail(g_task_is_valid(result, webView), FALSE);
3724 return g_task_propagate_boolean(G_TASK(result), error);
3728 * webkit_web_view_download_uri:
3729 * @web_view: a #WebKitWebView
3730 * @uri: the URI to download
3732 * Requests downloading of the specified URI string for @web_view.
3734 * Returns: (transfer full): a new #WebKitDownload representing
3735 * the download operation.
3737 WebKitDownload* webkit_web_view_download_uri(WebKitWebView* webView, const char* uri)
3739 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3740 g_return_val_if_fail(uri, nullptr);
3742 GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(webView->priv->context.get(), uri, &getPage(webView));
3743 return download.leakRef();
3747 * webkit_web_view_get_tls_info:
3748 * @web_view: a #WebKitWebView
3749 * @certificate: (out) (transfer none): return location for a #GTlsCertificate
3750 * @errors: (out): return location for a #GTlsCertificateFlags the verification status of @certificate
3752 * Retrieves the #GTlsCertificate associated with the main resource of @web_view,
3753 * and the #GTlsCertificateFlags showing what problems, if any, have been found
3754 * with that certificate.
3755 * If the connection is not HTTPS, this function returns %FALSE.
3756 * This function should be called after a response has been received from the
3757 * server, so you can connect to #WebKitWebView::load-changed and call this function
3758 * when it's emitted with %WEBKIT_LOAD_COMMITTED event.
3760 * Note that this function provides no information about the security of the web
3761 * page if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_IGNORE,
3762 * as subresources of the page may be controlled by an attacker. This function
3763 * may safely be used to determine the security status of the current page only
3764 * if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_FAIL, in
3765 * which case subresources that fail certificate verification will be blocked.
3767 * Returns: %TRUE if the @web_view connection uses HTTPS and a response has been received
3768 * from the server, or %FALSE otherwise.
3770 gboolean webkit_web_view_get_tls_info(WebKitWebView* webView, GTlsCertificate** certificate, GTlsCertificateFlags* errors)
3772 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3774 WebFrameProxy* mainFrame = getPage(webView).mainFrame();
3778 auto* wkCertificateInfo = mainFrame->certificateInfo();
3779 g_return_val_if_fail(wkCertificateInfo, FALSE);
3781 const auto& certificateInfo = wkCertificateInfo->certificateInfo();
3783 *certificate = certificateInfo.certificate();
3785 *errors = certificateInfo.tlsErrors();
3787 return !!certificateInfo.certificate();
3791 void webKitWebViewDidReceiveSnapshot(WebKitWebView* webView, uint64_t callbackID, WebImage* webImage)
3793 GRefPtr<GTask> task = webView->priv->snapshotResultsMap.take(callbackID);
3794 if (g_task_return_error_if_cancelled(task.get()))
3798 g_task_return_new_error(task.get(), WEBKIT_SNAPSHOT_ERROR, WEBKIT_SNAPSHOT_ERROR_FAILED_TO_CREATE,
3799 _("There was an error creating the snapshot"));
3803 g_task_return_pointer(task.get(), webImage->bitmap().createCairoSurface().leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy));
3806 static inline unsigned webKitSnapshotOptionsToSnapshotOptions(WebKitSnapshotOptions options)
3808 SnapshotOptions snapshotOptions = 0;
3810 if (!(options & WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING))
3811 snapshotOptions |= SnapshotOptionsExcludeSelectionHighlighting;
3813 return snapshotOptions;
3816 static inline SnapshotRegion toSnapshotRegion(WebKitSnapshotRegion region)
3819 case WEBKIT_SNAPSHOT_REGION_VISIBLE:
3820 return SnapshotRegionVisible;
3821 case WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT:
3822 return SnapshotRegionFullDocument;
3824 ASSERT_NOT_REACHED();
3825 return SnapshotRegionVisible;
3829 static inline uint64_t generateSnapshotCallbackID()
3831 static uint64_t uniqueCallbackID = 1;
3832 return uniqueCallbackID++;
3836 * webkit_web_view_get_snapshot:
3837 * @web_view: a #WebKitWebView
3838 * @region: the #WebKitSnapshotRegion for this snapshot
3839 * @options: #WebKitSnapshotOptions for the snapshot
3840 * @cancellable: (allow-none): a #GCancellable
3841 * @callback: (scope async): a #GAsyncReadyCallback
3842 * @user_data: (closure): user data
3844 * Asynchronously retrieves a snapshot of @web_view for @region.
3845 * @options specifies how the snapshot should be rendered.
3847 * When the operation is finished, @callback will be called. You must
3848 * call webkit_web_view_get_snapshot_finish() to get the result of the
3851 void webkit_web_view_get_snapshot(WebKitWebView* webView, WebKitSnapshotRegion region, WebKitSnapshotOptions options, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3853 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3855 API::Dictionary::MapType message;
3856 uint64_t callbackID = generateSnapshotCallbackID();
3857 message.set(String::fromUTF8("SnapshotOptions"), API::UInt64::create(static_cast<uint64_t>(webKitSnapshotOptionsToSnapshotOptions(options))));
3858 message.set(String::fromUTF8("SnapshotRegion"), API::UInt64::create(static_cast<uint64_t>(toSnapshotRegion(region))));
3859 message.set(String::fromUTF8("CallbackID"), API::UInt64::create(callbackID));
3860 message.set(String::fromUTF8("TransparentBackground"), API::Boolean::create(options & WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND));
3862 webView->priv->snapshotResultsMap.set(callbackID, adoptGRef(g_task_new(webView, cancellable, callback, userData)));
3863 getPage(webView).postMessageToInjectedBundle(String::fromUTF8("GetSnapshot"), API::Dictionary::create(WTFMove(message)).ptr());
3867 * webkit_web_view_get_snapshot_finish:
3868 * @web_view: a #WebKitWebView
3869 * @result: a #GAsyncResult
3870 * @error: return location for error or %NULL to ignore
3872 * Finishes an asynchronous operation started with webkit_web_view_get_snapshot().
3874 * Returns: (transfer full): a #cairo_surface_t with the retrieved snapshot or %NULL in error.
3876 cairo_surface_t* webkit_web_view_get_snapshot_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3878 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3879 g_return_val_if_fail(g_task_is_valid(result, webView), 0);
3881 return static_cast<cairo_surface_t*>(g_task_propagate_pointer(G_TASK(result), error));
3885 void webkitWebViewWebProcessTerminated(WebKitWebView* webView, WebKitWebProcessTerminationReason reason)
3888 if (reason == WEBKIT_WEB_PROCESS_CRASHED) {
3889 gboolean returnValue;
3890 g_signal_emit(webView, signals[WEB_PROCESS_CRASHED], 0, &returnValue);