2 * Copyright (C) 2011 Igalia S.L.
3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved.
4 * Copyright (C) 2014 Collabora Ltd.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #include "WebKitWebView.h"
26 #include "APISerializedScriptValue.h"
27 #include "ImageOptions.h"
28 #include "WebCertificateInfo.h"
29 #include "WebContextMenuItem.h"
30 #include "WebContextMenuItemData.h"
31 #include "WebKitAuthenticationRequestPrivate.h"
32 #include "WebKitBackForwardListPrivate.h"
33 #include "WebKitContextMenuClient.h"
34 #include "WebKitContextMenuItemPrivate.h"
35 #include "WebKitContextMenuPrivate.h"
36 #include "WebKitDownloadPrivate.h"
37 #include "WebKitEditorStatePrivate.h"
38 #include "WebKitEnumTypes.h"
39 #include "WebKitError.h"
40 #include "WebKitFaviconDatabasePrivate.h"
41 #include "WebKitFormClient.h"
42 #include "WebKitHitTestResultPrivate.h"
43 #include "WebKitIconLoadingClient.h"
44 #include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h"
45 #include "WebKitJavascriptResultPrivate.h"
46 #include "WebKitLoaderClient.h"
47 #include "WebKitNotificationPrivate.h"
48 #include "WebKitPolicyClient.h"
49 #include "WebKitPrivate.h"
50 #include "WebKitResponsePolicyDecision.h"
51 #include "WebKitScriptDialogPrivate.h"
52 #include "WebKitSettingsPrivate.h"
53 #include "WebKitUIClient.h"
54 #include "WebKitURIRequestPrivate.h"
55 #include "WebKitURIResponsePrivate.h"
56 #include "WebKitWebContextPrivate.h"
57 #include "WebKitWebResourcePrivate.h"
58 #include "WebKitWebViewPrivate.h"
59 #include "WebKitWebViewSessionStatePrivate.h"
60 #include "WebKitWebsiteDataManagerPrivate.h"
61 #include "WebKitWindowPropertiesPrivate.h"
62 #include <JavaScriptCore/APICast.h>
63 #include <JavaScriptCore/JSRetainPtr.h>
64 #include <WebCore/CertificateInfo.h>
65 #include <WebCore/GUniquePtrSoup.h>
66 #include <WebCore/JSDOMExceptionHandling.h>
67 #include <WebCore/RefPtrCairo.h>
68 #include <glib/gi18n-lib.h>
69 #include <wtf/SetForScope.h>
70 #include <wtf/glib/GRefPtr.h>
71 #include <wtf/glib/WTFGType.h>
72 #include <wtf/text/CString.h>
73 #include <wtf/text/StringBuilder.h>
76 #include "WebKitPrintOperationPrivate.h"
77 #include "WebKitWebInspectorPrivate.h"
78 #include "WebKitWebViewBasePrivate.h"
79 #include <WebCore/GUniquePtrGtk.h>
83 #include "APIViewClient.h"
88 #include <libnotify/notify.h>
91 using namespace WebKit;
92 using namespace WebCore;
95 * SECTION: WebKitWebView
96 * @Short_description: The central class of the WebKit2GTK+ API
97 * @Title: WebKitWebView
99 * #WebKitWebView is the central class of the WebKit2GTK+ API. It is
100 * responsible for managing the drawing of the content and forwarding
101 * of events. You can load any URI into the #WebKitWebView or a data
102 * string. With #WebKitSettings you can control various aspects of the
103 * rendering and loading of the content.
105 * Note that #WebKitWebView is scrollable by itself, so you don't need
106 * to embed it in a #GtkScrolledWindow.
112 LOAD_FAILED_WITH_TLS_ERRORS,
124 MOUSE_TARGET_CHANGED,
130 RESOURCE_LOAD_STARTED,
138 CONTEXT_MENU_DISMISSED,
142 INSECURE_CONTENT_DETECTED,
165 PROP_USER_CONTENT_MANAGER,
167 PROP_ESTIMATED_LOAD_PROGRESS,
172 PROP_IS_PLAYING_AUDIO,
174 PROP_IS_CONTROLLED_BY_AUTOMATION,
178 typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap;
179 typedef HashMap<uint64_t, GRefPtr<GTask> > SnapshotResultsMap;
181 class PageLoadStateObserver;
183 struct _WebKitWebViewPrivate {
184 ~_WebKitWebViewPrivate()
186 // For modal dialogs, make sure the main loop is stopped when finalizing the webView.
187 if (modalLoop && g_main_loop_is_running(modalLoop.get()))
188 g_main_loop_quit(modalLoop.get());
192 std::unique_ptr<WKWPE::View> view;
195 WebKitWebView* relatedView;
197 CString customTextEncoding;
201 bool isControlledByAutomation;
203 std::unique_ptr<PageLoadStateObserver> loadObserver;
205 GRefPtr<WebKitBackForwardList> backForwardList;
206 GRefPtr<WebKitSettings> settings;
207 GRefPtr<WebKitUserContentManager> userContentManager;
208 GRefPtr<WebKitWebContext> context;
209 GRefPtr<WebKitWindowProperties> windowProperties;
210 GRefPtr<WebKitEditorState> editorState;
212 GRefPtr<GMainLoop> modalLoop;
214 GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult;
215 WebEvent::Modifiers mouseTargetModifiers;
217 GRefPtr<WebKitFindController> findController;
218 JSRetainPtr<JSGlobalContextRef> javascriptGlobalContext;
220 GRefPtr<WebKitWebResource> mainResource;
221 LoadingResourcesMap loadingResourcesMap;
223 WebKitScriptDialog* currentScriptDialog;
226 GRefPtr<WebKitWebInspector> inspector;
229 RefPtr<cairo_surface_t> favicon;
230 GRefPtr<GCancellable> faviconCancellable;
232 unsigned long faviconChangedHandlerID;
234 SnapshotResultsMap snapshotResultsMap;
235 GRefPtr<WebKitAuthenticationRequest> authenticationRequest;
237 GRefPtr<WebKitWebsiteDataManager> websiteDataManager;
240 static guint signals[LAST_SIGNAL] = { 0, };
243 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, WEBKIT_TYPE_WEB_VIEW_BASE)
245 WEBKIT_DEFINE_TYPE(WebKitWebView, webkit_web_view, G_TYPE_OBJECT)
248 static inline WebPageProxy& getPage(WebKitWebView* webView)
251 auto* page = webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView));
255 ASSERT(webView->priv->view);
256 return webView->priv->view->page();
260 static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading)
262 if (webView->priv->isLoading == isLoading)
265 webView->priv->isLoading = isLoading;
266 g_object_notify(G_OBJECT(webView), "is-loading");
269 void webkitWebViewIsPlayingAudioChanged(WebKitWebView* webView)
271 g_object_notify(G_OBJECT(webView), "is-playing-audio");
274 class PageLoadStateObserver final : public PageLoadState::Observer {
276 PageLoadStateObserver(WebKitWebView* webView)
282 void willChangeIsLoading() override
284 g_object_freeze_notify(G_OBJECT(m_webView));
286 void didChangeIsLoading() override
288 webkitWebViewSetIsLoading(m_webView, getPage(m_webView).pageLoadState().isLoading());
289 g_object_thaw_notify(G_OBJECT(m_webView));
292 void willChangeTitle() override
294 g_object_freeze_notify(G_OBJECT(m_webView));
296 void didChangeTitle() override
298 m_webView->priv->title = getPage(m_webView).pageLoadState().title().utf8();
299 g_object_notify(G_OBJECT(m_webView), "title");
300 g_object_thaw_notify(G_OBJECT(m_webView));
303 void willChangeActiveURL() override
305 g_object_freeze_notify(G_OBJECT(m_webView));
307 void didChangeActiveURL() override
309 m_webView->priv->activeURI = getPage(m_webView).pageLoadState().activeURL().utf8();
310 g_object_notify(G_OBJECT(m_webView), "uri");
311 g_object_thaw_notify(G_OBJECT(m_webView));
314 void willChangeHasOnlySecureContent() override { }
315 void didChangeHasOnlySecureContent() override { }
317 void willChangeEstimatedProgress() override
319 g_object_freeze_notify(G_OBJECT(m_webView));
321 void didChangeEstimatedProgress() override
323 g_object_notify(G_OBJECT(m_webView), "estimated-load-progress");
324 g_object_thaw_notify(G_OBJECT(m_webView));
327 void willChangeCanGoBack() override { }
328 void didChangeCanGoBack() override { }
329 void willChangeCanGoForward() override { }
330 void didChangeCanGoForward() override { }
331 void willChangeNetworkRequestsInProgress() override { }
332 void didChangeNetworkRequestsInProgress() override { }
333 void willChangeCertificateInfo() override { }
334 void didChangeCertificateInfo() override { }
335 void willChangeWebProcessIsResponsive() override { }
336 void didChangeWebProcessIsResponsive() override { }
338 WebKitWebView* m_webView;
342 class WebViewClient final : public API::ViewClient {
344 explicit WebViewClient(WebKitWebView* webView)
350 void handleDownloadRequest(WKWPE::View&, DownloadProxy& downloadProxy) override
352 webkitWebViewHandleDownloadRequest(m_webView, &downloadProxy);
355 JSGlobalContextRef javascriptGlobalContext() override
357 return webkit_web_view_get_javascript_global_context(m_webView);
360 WebKitWebView* m_webView;
364 static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error)
366 if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)
367 || g_error_matches(error, WEBKIT_POLICY_ERROR, WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE)
368 || g_error_matches(error, WEBKIT_PLUGIN_ERROR, WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD))
371 GUniquePtr<char> htmlString(g_strdup_printf("<html><body>%s</body></html>", error->message));
372 webkit_web_view_load_alternate_html(webView, htmlString.get(), failingURI, 0);
378 static GtkWidget* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
383 static WebKitWebView* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*)
389 static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType)
391 if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) {
392 webkit_policy_decision_use(decision);
396 WebKitURIResponse* response = webkit_response_policy_decision_get_response(WEBKIT_RESPONSE_POLICY_DECISION(decision));
397 const ResourceResponse& resourceResponse = webkitURIResponseGetResourceResponse(response);
398 if (resourceResponse.isAttachment()) {
399 webkit_policy_decision_download(decision);
403 if (webkit_response_policy_decision_is_mime_type_supported(WEBKIT_RESPONSE_POLICY_DECISION(decision)))
404 webkit_policy_decision_use(decision);
406 webkit_policy_decision_ignore(decision);
411 static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request)
413 webkit_permission_request_deny(request);
417 static void allowModalDialogsChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
419 getPage(webView).setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
422 static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
424 auto& page = getPage(webView);
425 gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings);
426 gdouble pageZoomLevel = zoomTextOnly ? 1 : page.textZoomFactor();
427 gdouble textZoomLevel = zoomTextOnly ? page.pageZoomFactor() : 1;
428 page.setPageAndTextZoomFactors(pageZoomLevel, textZoomLevel);
431 static void userAgentChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView)
433 getPage(webView).setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
436 static void webkitWebViewUpdateFavicon(WebKitWebView* webView, cairo_surface_t* favicon)
438 WebKitWebViewPrivate* priv = webView->priv;
439 if (priv->favicon.get() == favicon)
442 priv->favicon = favicon;
443 g_object_notify(G_OBJECT(webView), "favicon");
446 static void webkitWebViewCancelFaviconRequest(WebKitWebView* webView)
448 if (!webView->priv->faviconCancellable)
451 g_cancellable_cancel(webView->priv->faviconCancellable.get());
452 webView->priv->faviconCancellable = 0;
455 static void gotFaviconCallback(GObject* object, GAsyncResult* result, gpointer userData)
457 GUniqueOutPtr<GError> error;
458 RefPtr<cairo_surface_t> favicon = adoptRef(webkit_favicon_database_get_favicon_finish(WEBKIT_FAVICON_DATABASE(object), result, &error.outPtr()));
459 if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
462 WebKitWebView* webView = WEBKIT_WEB_VIEW(userData);
463 webkitWebViewUpdateFavicon(webView, favicon.get());
464 webView->priv->faviconCancellable = 0;
467 static void webkitWebViewRequestFavicon(WebKitWebView* webView)
469 webkitWebViewCancelFaviconRequest(webView);
471 WebKitWebViewPrivate* priv = webView->priv;
472 priv->faviconCancellable = adoptGRef(g_cancellable_new());
473 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
474 webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), gotFaviconCallback, webView);
477 static void webkitWebViewUpdateFaviconURI(WebKitWebView* webView, const char* faviconURI)
479 if (webView->priv->faviconURI == faviconURI)
482 webView->priv->faviconURI = faviconURI;
483 webkitWebViewRequestFavicon(webView);
486 static void faviconChangedCallback(WebKitFaviconDatabase*, const char* pageURI, const char* faviconURI, WebKitWebView* webView)
488 if (webView->priv->activeURI != pageURI)
491 webkitWebViewUpdateFaviconURI(webView, faviconURI);
494 static bool webkitWebViewIsConstructed(WebKitWebView* webView)
496 // The loadObserver is set in webkitWebViewConstructed, right after the
497 // WebPageProxy is created, so we use it to check if the view has been
498 // constructed instead of adding a boolean member only for that.
499 return !!webView->priv->loadObserver;
502 static void webkitWebViewUpdateSettings(WebKitWebView* webView)
504 // The "settings" property is set on construction, and in that
505 // case webkit_web_view_set_settings() will be called *before* the
506 // WebPageProxy has been created so we should do an early return.
507 if (!webkitWebViewIsConstructed(webView))
510 auto& page = getPage(webView);
511 WebKitSettings* settings = webView->priv->settings.get();
512 page.setPreferences(*webkitSettingsGetPreferences(settings));
513 page.setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings));
514 page.setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings)));
516 g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView);
517 g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
518 g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView);
521 static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView)
523 if (!webkitWebViewIsConstructed(webView))
526 WebKitSettings* settings = webView->priv->settings.get();
527 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(allowModalDialogsChanged), webView);
528 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView);
529 g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(userAgentChanged), webView);
532 static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView)
534 WebKitWebViewPrivate* priv = webView->priv;
535 if (priv->faviconChangedHandlerID)
538 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
539 priv->faviconChangedHandlerID = g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), webView);
542 static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* webView)
544 WebKitWebViewPrivate* priv = webView->priv;
545 if (priv->faviconChangedHandlerID)
546 g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context.get()), priv->faviconChangedHandlerID);
547 priv->faviconChangedHandlerID = 0;
551 static const char* gNotifyNotificationID = "wk-notify-notification";
553 static void notifyNotificationClosed(NotifyNotification*, WebKitNotification* webNotification)
555 g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
556 webkit_notification_close(webNotification);
559 static void notifyNotificationClicked(NotifyNotification*, char*, WebKitNotification* webNotification)
561 webkit_notification_clicked(webNotification);
564 static void webNotificationClosed(WebKitNotification* webNotification)
566 NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
570 notify_notification_close(notification, nullptr);
571 g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr);
573 #endif // USE(LIBNOTIFY)
575 static gboolean webkitWebViewShowNotification(WebKitWebView*, WebKitNotification* webNotification)
578 if (!notify_is_initted())
579 notify_init(g_get_prgname());
581 NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID));
583 notification = notify_notification_new(webkit_notification_get_title(webNotification),
584 webkit_notification_get_body(webNotification), nullptr);
586 notify_notification_add_action(notification, "default", _("Acknowledge"), NOTIFY_ACTION_CALLBACK(notifyNotificationClicked), webNotification, nullptr);
588 g_signal_connect_object(notification, "closed", G_CALLBACK(notifyNotificationClosed), webNotification, static_cast<GConnectFlags>(0));
589 g_signal_connect(webNotification, "closed", G_CALLBACK(webNotificationClosed), nullptr);
590 g_object_set_data_full(G_OBJECT(webNotification), gNotifyNotificationID, notification, static_cast<GDestroyNotify>(g_object_unref));
592 notify_notification_update(notification, webkit_notification_get_title(webNotification),
593 webkit_notification_get_body(webNotification), nullptr);
596 notify_notification_show(notification, nullptr);
599 UNUSED_PARAM(webNotification);
604 static void webkitWebViewConstructed(GObject* object)
606 G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object);
608 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
609 WebKitWebViewPrivate* priv = webView->priv;
610 if (priv->relatedView) {
611 priv->context = webkit_web_view_get_context(priv->relatedView);
612 priv->isEphemeral = webkit_web_view_is_ephemeral(priv->relatedView);
613 priv->isControlledByAutomation = webkit_web_view_is_controlled_by_automation(priv->relatedView);
614 } else if (!priv->context)
615 priv->context = webkit_web_context_get_default();
616 else if (!priv->isEphemeral)
617 priv->isEphemeral = webkit_web_context_is_ephemeral(priv->context.get());
620 priv->settings = adoptGRef(webkit_settings_new());
622 if (!priv->userContentManager)
623 priv->userContentManager = adoptGRef(webkit_user_content_manager_new());
625 if (priv->isEphemeral && !webkit_web_context_is_ephemeral(priv->context.get())) {
626 priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new_ephemeral());
627 webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), webkitWebContextGetProcessPool(priv->context.get()));
630 webkitWebContextCreatePageForWebView(priv->context.get(), webView, priv->userContentManager.get(), priv->relatedView);
632 priv->loadObserver = std::make_unique<PageLoadStateObserver>(webView);
633 getPage(webView).pageLoadState().addObserver(*priv->loadObserver);
635 // The related view is only valid during the construction.
636 priv->relatedView = nullptr;
638 attachLoaderClientToView(webView);
639 attachUIClientToView(webView);
640 attachPolicyClientToView(webView);
641 attachContextMenuClientToView(webView);
642 attachFormClientToView(webView);
643 attachIconLoadingClientToView(webView);
646 priv->view->setClient(std::make_unique<WebViewClient>(webView));
649 // This needs to be after attachUIClientToView() because WebPageProxy::setUIClient() calls setCanRunModal() with true.
650 // See https://bugs.webkit.org/show_bug.cgi?id=135412.
651 webkitWebViewUpdateSettings(webView);
653 priv->backForwardList = adoptGRef(webkitBackForwardListCreate(&getPage(webView).backForwardList()));
654 priv->windowProperties = adoptGRef(webkitWindowPropertiesCreate());
657 static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
659 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
662 case PROP_WEB_CONTEXT: {
663 gpointer webContext = g_value_get_object(value);
664 webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : nullptr;
667 case PROP_RELATED_VIEW: {
668 gpointer relatedView = g_value_get_object(value);
669 webView->priv->relatedView = relatedView ? WEBKIT_WEB_VIEW(relatedView) : nullptr;
672 case PROP_SETTINGS: {
673 if (gpointer settings = g_value_get_object(value))
674 webkit_web_view_set_settings(webView, WEBKIT_SETTINGS(settings));
677 case PROP_USER_CONTENT_MANAGER: {
678 gpointer userContentManager = g_value_get_object(value);
679 webView->priv->userContentManager = userContentManager ? WEBKIT_USER_CONTENT_MANAGER(userContentManager) : nullptr;
682 case PROP_ZOOM_LEVEL:
683 webkit_web_view_set_zoom_level(webView, g_value_get_double(value));
685 case PROP_IS_EPHEMERAL:
686 webView->priv->isEphemeral = g_value_get_boolean(value);
688 case PROP_IS_CONTROLLED_BY_AUTOMATION:
689 webView->priv->isControlledByAutomation = g_value_get_boolean(value);
692 webkit_web_view_set_editable(webView, g_value_get_boolean(value));
695 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
699 static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
701 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
704 case PROP_WEB_CONTEXT:
705 g_value_set_object(value, webView->priv->context.get());
708 g_value_set_object(value, webkit_web_view_get_settings(webView));
710 case PROP_USER_CONTENT_MANAGER:
711 g_value_set_object(value, webkit_web_view_get_user_content_manager(webView));
714 g_value_set_string(value, webView->priv->title.data());
716 case PROP_ESTIMATED_LOAD_PROGRESS:
717 g_value_set_double(value, webkit_web_view_get_estimated_load_progress(webView));
720 g_value_set_pointer(value, webkit_web_view_get_favicon(webView));
723 g_value_set_string(value, webkit_web_view_get_uri(webView));
725 case PROP_ZOOM_LEVEL:
726 g_value_set_double(value, webkit_web_view_get_zoom_level(webView));
728 case PROP_IS_LOADING:
729 g_value_set_boolean(value, webkit_web_view_is_loading(webView));
731 case PROP_IS_PLAYING_AUDIO:
732 g_value_set_boolean(value, webkit_web_view_is_playing_audio(webView));
734 case PROP_IS_EPHEMERAL:
735 g_value_set_boolean(value, webkit_web_view_is_ephemeral(webView));
737 case PROP_IS_CONTROLLED_BY_AUTOMATION:
738 g_value_set_boolean(value, webkit_web_view_is_controlled_by_automation(webView));
741 g_value_set_boolean(value, webkit_web_view_is_editable(webView));
744 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
748 static void webkitWebViewDispose(GObject* object)
750 WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
751 webkitWebViewCancelFaviconRequest(webView);
752 webkitWebViewDisconnectSettingsSignalHandlers(webView);
753 webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView);
755 if (webView->priv->loadObserver) {
756 getPage(webView).pageLoadState().removeObserver(*webView->priv->loadObserver);
757 webView->priv->loadObserver.reset();
759 // We notify the context here to ensure it's called only once. Ideally we should
760 // call this in finalize, not dispose, but finalize is used internally and we don't
761 // have access to the instance pointer from the private struct destructor.
762 webkitWebContextWebViewDestroyed(webView->priv->context.get(), webView);
765 if (webView->priv->websiteDataManager) {
766 webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get()));
767 webView->priv->websiteDataManager = nullptr;
771 webView->priv->view->close();
774 G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
777 static gboolean webkitWebViewAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer)
779 void* object = g_value_get_object(handlerReturn);
781 g_value_set_object(returnValue, object);
786 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
788 GObjectClass* gObjectClass = G_OBJECT_CLASS(webViewClass);
790 gObjectClass->constructed = webkitWebViewConstructed;
791 gObjectClass->set_property = webkitWebViewSetProperty;
792 gObjectClass->get_property = webkitWebViewGetProperty;
793 gObjectClass->dispose = webkitWebViewDispose;
795 webViewClass->load_failed = webkitWebViewLoadFail;
796 webViewClass->create = webkitWebViewCreate;
797 webViewClass->script_dialog = webkitWebViewScriptDialog;
798 webViewClass->decide_policy = webkitWebViewDecidePolicy;
799 webViewClass->permission_request = webkitWebViewPermissionRequest;
800 webViewClass->run_file_chooser = webkitWebViewRunFileChooser;
801 webViewClass->authenticate = webkitWebViewAuthenticate;
802 webViewClass->show_notification = webkitWebViewShowNotification;
805 * WebKitWebView:web-context:
807 * The #WebKitWebContext of the view.
809 g_object_class_install_property(gObjectClass,
811 g_param_spec_object("web-context",
813 _("The web context for the view"),
814 WEBKIT_TYPE_WEB_CONTEXT,
815 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
817 * WebKitWebView:related-view:
819 * The related #WebKitWebView used when creating the view to share the
820 * same web process. This property is not readable because the related
821 * web view is only valid during the object construction.
825 g_object_class_install_property(
830 _("Related WebView"),
831 _("The related WebKitWebView used when creating the view to share the same web process"),
832 WEBKIT_TYPE_WEB_VIEW,
833 static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
836 * WebKitWebView:settings:
838 * The #WebKitSettings of the view.
842 g_object_class_install_property(
847 _("WebView settings"),
848 _("The WebKitSettings of the view"),
849 WEBKIT_TYPE_SETTINGS,
850 static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT)));
853 * WebKitWebView:user-content-manager:
855 * The #WebKitUserContentManager of the view.
859 g_object_class_install_property(
861 PROP_USER_CONTENT_MANAGER,
863 "user-content-manager",
864 _("WebView user content manager"),
865 _("The WebKitUserContentManager of the view"),
866 WEBKIT_TYPE_USER_CONTENT_MANAGER,
867 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
870 * WebKitWebView:title:
872 * The main frame document title of this #WebKitWebView. If
873 * the title has not been received yet, it will be %NULL.
875 g_object_class_install_property(gObjectClass,
877 g_param_spec_string("title",
879 _("Main frame document title"),
881 WEBKIT_PARAM_READABLE));
884 * WebKitWebView:estimated-load-progress:
886 * An estimate of the percent completion for the current loading operation.
887 * This value will range from 0.0 to 1.0 and, once a load completes,
888 * will remain at 1.0 until a new load starts, at which point it
889 * will be reset to 0.0.
890 * The value is an estimate based on the total number of bytes expected
891 * to be received for a document, including all its possible subresources
892 * and child documents.
894 g_object_class_install_property(gObjectClass,
895 PROP_ESTIMATED_LOAD_PROGRESS,
896 g_param_spec_double("estimated-load-progress",
897 _("Estimated Load Progress"),
898 _("An estimate of the percent completion for a document load"),
900 WEBKIT_PARAM_READABLE));
902 * WebKitWebView:favicon:
904 * The favicon currently associated to the #WebKitWebView.
905 * See webkit_web_view_get_favicon() for more details.
907 g_object_class_install_property(gObjectClass,
909 g_param_spec_pointer("favicon",
911 _("The favicon associated to the view, if any"),
912 WEBKIT_PARAM_READABLE));
916 * The current active URI of the #WebKitWebView.
917 * See webkit_web_view_get_uri() for more details.
919 g_object_class_install_property(gObjectClass,
921 g_param_spec_string("uri",
923 _("The current active URI of the view"),
925 WEBKIT_PARAM_READABLE));
928 * WebKitWebView:zoom-level:
930 * The zoom level of the #WebKitWebView content.
931 * See webkit_web_view_set_zoom_level() for more details.
933 g_object_class_install_property(
939 _("The zoom level of the view content"),
941 WEBKIT_PARAM_READWRITE));
944 * WebKitWebView:is-loading:
946 * Whether the #WebKitWebView is currently loading a page. This property becomes
947 * %TRUE as soon as a new load operation is requested and before the
948 * #WebKitWebView::load-changed signal is emitted with %WEBKIT_LOAD_STARTED and
949 * at that point the active URI is the requested one.
950 * When the load operation finishes the property is set to %FALSE before
951 * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_FINISHED.
953 g_object_class_install_property(
956 g_param_spec_boolean(
959 _("Whether the view is loading a page"),
961 WEBKIT_PARAM_READABLE));
964 * WebKitWebView:is-playing-audio:
966 * Whether the #WebKitWebView is currently playing audio from a page.
967 * This property becomes %TRUE as soon as web content starts playing any
968 * kind of audio. When a page is no longer playing any kind of sound,
969 * the property is set back to %FALSE.
973 g_object_class_install_property(
975 PROP_IS_PLAYING_AUDIO,
976 g_param_spec_boolean(
979 _("Whether the view is playing audio"),
981 WEBKIT_PARAM_READABLE));
984 * WebKitWebView:is-ephemeral:
986 * Whether the #WebKitWebView is ephemeral. An ephemeral web view never writes
987 * website data to the client storage, no matter what #WebKitWebsiteDataManager
988 * its context is using. This is normally used to implement private browsing mode.
989 * This is a %G_PARAM_CONSTRUCT_ONLY property, so you have to create a ephemeral
990 * #WebKitWebView and it can't be changed. Note that all #WebKitWebView<!-- -->s
991 * created with an ephemeral #WebKitWebContext will be ephemeral automatically.
992 * See also webkit_web_context_new_ephemeral().
996 g_object_class_install_property(
999 g_param_spec_boolean(
1002 _("Whether the web view is ephemeral"),
1004 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1007 * WebKitWebView:is-controlled-by-automation:
1009 * Whether the #WebKitWebView is controlled by automation. This should only be used when
1010 * creating a new #WebKitWebView as a response to #WebKitAutomationSession::create-web-view
1015 g_object_class_install_property(
1017 PROP_IS_CONTROLLED_BY_AUTOMATION,
1018 g_param_spec_boolean(
1019 "is-controlled-by-automation",
1020 "Is Controlled By Automation",
1021 _("Whether the web view is controlled by automation"),
1023 static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
1026 * WebKitWebView:editable:
1028 * Whether the pages loaded inside #WebKitWebView are editable. For more
1029 * information see webkit_web_view_set_editable().
1033 g_object_class_install_property(
1036 g_param_spec_boolean(
1039 _("Whether the content can be modified by the user."),
1041 WEBKIT_PARAM_READWRITE));
1044 * WebKitWebView::load-changed:
1045 * @web_view: the #WebKitWebView on which the signal is emitted
1046 * @load_event: the #WebKitLoadEvent
1048 * Emitted when a load operation in @web_view changes.
1049 * The signal is always emitted with %WEBKIT_LOAD_STARTED when a
1050 * new load request is made and %WEBKIT_LOAD_FINISHED when the load
1051 * finishes successfully or due to an error. When the ongoing load
1052 * operation fails #WebKitWebView::load-failed signal is emitted
1053 * before #WebKitWebView::load-changed is emitted with
1054 * %WEBKIT_LOAD_FINISHED.
1055 * If a redirection is received from the server, this signal is emitted
1056 * with %WEBKIT_LOAD_REDIRECTED after the initial emission with
1057 * %WEBKIT_LOAD_STARTED and before %WEBKIT_LOAD_COMMITTED.
1058 * When the page content starts arriving the signal is emitted with
1059 * %WEBKIT_LOAD_COMMITTED event.
1061 * You can handle this signal and use a switch to track any ongoing
1064 * <informalexample><programlisting>
1065 * static void web_view_load_changed (WebKitWebView *web_view,
1066 * WebKitLoadEvent load_event,
1067 * gpointer user_data)
1069 * switch (load_event) {
1070 * case WEBKIT_LOAD_STARTED:
1071 * /<!-- -->* New load, we have now a provisional URI *<!-- -->/
1072 * provisional_uri = webkit_web_view_get_uri (web_view);
1073 * /<!-- -->* Here we could start a spinner or update the
1074 * <!-- -->* location bar with the provisional URI *<!-- -->/
1076 * case WEBKIT_LOAD_REDIRECTED:
1077 * redirected_uri = webkit_web_view_get_uri (web_view);
1079 * case WEBKIT_LOAD_COMMITTED:
1080 * /<!-- -->* The load is being performed. Current URI is
1081 * <!-- -->* the final one and it won't change unless a new
1082 * <!-- -->* load is requested or a navigation within the
1083 * <!-- -->* same page is performed *<!-- -->/
1084 * uri = webkit_web_view_get_uri (web_view);
1086 * case WEBKIT_LOAD_FINISHED:
1087 * /<!-- -->* Load finished, we can now stop the spinner *<!-- -->/
1091 * </programlisting></informalexample>
1093 signals[LOAD_CHANGED] =
1094 g_signal_new("load-changed",
1095 G_TYPE_FROM_CLASS(webViewClass),
1097 G_STRUCT_OFFSET(WebKitWebViewClass, load_changed),
1099 g_cclosure_marshal_VOID__ENUM,
1101 WEBKIT_TYPE_LOAD_EVENT);
1104 * WebKitWebView::load-failed:
1105 * @web_view: the #WebKitWebView on which the signal is emitted
1106 * @load_event: the #WebKitLoadEvent of the load operation
1107 * @failing_uri: the URI that failed to load
1108 * @error: the #GError that was triggered
1110 * Emitted when an error occurs during a load operation.
1111 * If the error happened when starting to load data for a page
1112 * @load_event will be %WEBKIT_LOAD_STARTED. If it happened while
1113 * loading a committed data source @load_event will be %WEBKIT_LOAD_COMMITTED.
1114 * Since a load error causes the load operation to finish, the signal
1115 * WebKitWebView::load-changed will always be emitted with
1116 * %WEBKIT_LOAD_FINISHED event right after this one.
1118 * By default, if the signal is not handled, a stock error page will be displayed.
1119 * You need to handle the signal if you want to provide your own error page.
1121 * Returns: %TRUE to stop other handlers from being invoked for the event.
1122 * %FALSE to propagate the event further.
1124 signals[LOAD_FAILED] =
1127 G_TYPE_FROM_CLASS(webViewClass),
1129 G_STRUCT_OFFSET(WebKitWebViewClass, load_failed),
1130 g_signal_accumulator_true_handled, 0,
1131 g_cclosure_marshal_generic,
1133 WEBKIT_TYPE_LOAD_EVENT,
1135 G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE);
1138 * WebKitWebView::load-failed-with-tls-errors:
1139 * @web_view: the #WebKitWebView on which the signal is emitted
1140 * @failing_uri: the URI that failed to load
1141 * @certificate: a #GTlsCertificate
1142 * @errors: a #GTlsCertificateFlags with the verification status of @certificate
1144 * Emitted when a TLS error occurs during a load operation.
1145 * To allow an exception for this @certificate
1146 * and the host of @failing_uri use webkit_web_context_allow_tls_certificate_for_host().
1148 * To handle this signal asynchronously you should call g_object_ref() on @certificate
1151 * If %FALSE is returned, #WebKitWebView::load-failed will be emitted. The load
1152 * will finish regardless of the returned value.
1154 * Returns: %TRUE to stop other handlers from being invoked for the event.
1155 * %FALSE to propagate the event further.
1159 signals[LOAD_FAILED_WITH_TLS_ERRORS] =
1160 g_signal_new("load-failed-with-tls-errors",
1161 G_TYPE_FROM_CLASS(webViewClass),
1163 G_STRUCT_OFFSET(WebKitWebViewClass, load_failed_with_tls_errors),
1164 g_signal_accumulator_true_handled, 0 /* accumulator data */,
1165 g_cclosure_marshal_generic,
1168 G_TYPE_TLS_CERTIFICATE,
1169 G_TYPE_TLS_CERTIFICATE_FLAGS);
1172 * WebKitWebView::create:
1173 * @web_view: the #WebKitWebView on which the signal is emitted
1174 * @navigation_action: a #WebKitNavigationAction
1176 * Emitted when the creation of a new #WebKitWebView is requested.
1177 * If this signal is handled the signal handler should return the
1178 * newly created #WebKitWebView.
1180 * The #WebKitNavigationAction parameter contains information about the
1181 * navigation action that triggered this signal.
1183 * When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES
1184 * process model, the new #WebKitWebView should be related to
1185 * @web_view to share the same web process, see webkit_web_view_new_with_related_view()
1188 * The new #WebKitWebView should not be displayed to the user
1189 * until the #WebKitWebView::ready-to-show signal is emitted.
1191 * Returns: (transfer full): a newly allocated #WebKitWebView widget
1192 * or %NULL to propagate the event further.
1194 signals[CREATE] = g_signal_new(
1196 G_TYPE_FROM_CLASS(webViewClass),
1198 G_STRUCT_OFFSET(WebKitWebViewClass, create),
1199 webkitWebViewAccumulatorObjectHandled, 0,
1200 g_cclosure_marshal_generic,
1204 WEBKIT_TYPE_WEB_VIEW,
1207 WEBKIT_TYPE_NAVIGATION_ACTION | G_SIGNAL_TYPE_STATIC_SCOPE);
1210 * WebKitWebView::ready-to-show:
1211 * @web_view: the #WebKitWebView on which the signal is emitted
1213 * Emitted after #WebKitWebView::create on the newly created #WebKitWebView
1214 * when it should be displayed to the user. When this signal is emitted
1215 * all the information about how the window should look, including
1216 * size, position, whether the location, status and scrollbars
1217 * should be displayed, is already set on the #WebKitWindowProperties
1218 * of @web_view. See also webkit_web_view_get_window_properties().
1220 signals[READY_TO_SHOW] =
1221 g_signal_new("ready-to-show",
1222 G_TYPE_FROM_CLASS(webViewClass),
1224 G_STRUCT_OFFSET(WebKitWebViewClass, ready_to_show),
1226 g_cclosure_marshal_VOID__VOID,
1230 * WebKitWebView::run-as-modal:
1231 * @web_view: the #WebKitWebView on which the signal is emitted
1233 * Emitted after #WebKitWebView::ready-to-show on the newly
1234 * created #WebKitWebView when JavaScript code calls
1235 * <function>window.showModalDialog</function>. The purpose of
1236 * this signal is to allow the client application to prepare the
1237 * new view to behave as modal. Once the signal is emitted a new
1238 * main loop will be run to block user interaction in the parent
1239 * #WebKitWebView until the new dialog is closed.
1241 signals[RUN_AS_MODAL] =
1242 g_signal_new("run-as-modal",
1243 G_TYPE_FROM_CLASS(webViewClass),
1245 G_STRUCT_OFFSET(WebKitWebViewClass, run_as_modal),
1247 g_cclosure_marshal_VOID__VOID,
1251 * WebKitWebView::close:
1252 * @web_view: the #WebKitWebView on which the signal is emitted
1254 * Emitted when closing a #WebKitWebView is requested. This occurs when a
1255 * call is made from JavaScript's <function>window.close</function> function or
1256 * after trying to close the @web_view with webkit_web_view_try_close().
1257 * It is the owner's responsibility to handle this signal to hide or
1258 * destroy the #WebKitWebView, if necessary.
1261 g_signal_new("close",
1262 G_TYPE_FROM_CLASS(webViewClass),
1264 G_STRUCT_OFFSET(WebKitWebViewClass, close),
1266 g_cclosure_marshal_VOID__VOID,
1270 * WebKitWebView::script-dialog:
1271 * @web_view: the #WebKitWebView on which the signal is emitted
1272 * @dialog: the #WebKitScriptDialog to show
1274 * Emitted when JavaScript code calls <function>window.alert</function>,
1275 * <function>window.confirm</function> or <function>window.prompt</function>,
1276 * or when <function>onbeforeunload</function> event is fired.
1277 * The @dialog parameter should be used to build the dialog.
1278 * If the signal is not handled a different dialog will be built and shown depending
1279 * on the dialog type:
1282 * %WEBKIT_SCRIPT_DIALOG_ALERT: message dialog with a single Close button.
1283 * </para></listitem>
1285 * %WEBKIT_SCRIPT_DIALOG_CONFIRM: message dialog with OK and Cancel buttons.
1286 * </para></listitem>
1288 * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and
1289 * a text entry with the default text.
1290 * </para></listitem>
1292 * %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: message dialog with Stay and Leave buttons.
1293 * </para></listitem>
1296 * Returns: %TRUE to stop other handlers from being invoked for the event.
1297 * %FALSE to propagate the event further.
1299 signals[SCRIPT_DIALOG] = g_signal_new(
1301 G_TYPE_FROM_CLASS(webViewClass),
1303 G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog),
1304 g_signal_accumulator_true_handled, nullptr,
1305 g_cclosure_marshal_generic,
1307 WEBKIT_TYPE_SCRIPT_DIALOG | G_SIGNAL_TYPE_STATIC_SCOPE);
1310 * WebKitWebView::decide-policy:
1311 * @web_view: the #WebKitWebView on which the signal is emitted
1312 * @decision: the #WebKitPolicyDecision
1313 * @decision_type: a #WebKitPolicyDecisionType denoting the type of @decision
1315 * This signal is emitted when WebKit is requesting the client to decide a policy
1316 * decision, such as whether to navigate to a page, open a new window or whether or
1317 * not to download a resource. The #WebKitNavigationPolicyDecision passed in the
1318 * @decision argument is a generic type, but should be casted to a more
1319 * specific type when making the decision. For example:
1321 * <informalexample><programlisting>
1323 * decide_policy_cb (WebKitWebView *web_view,
1324 * WebKitPolicyDecision *decision,
1325 * WebKitPolicyDecisionType type)
1328 * case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
1329 * WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1330 * /<!-- -->* Make a policy decision here. *<!-- -->/
1332 * case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
1333 * WebKitNavigationPolicyDecision *navigation_decision = WEBKIT_NAVIGATION_POLICY_DECISION (decision);
1334 * /<!-- -->* Make a policy decision here. *<!-- -->/
1336 * case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
1337 * WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision);
1338 * /<!-- -->* Make a policy decision here. *<!-- -->/
1341 * /<!-- -->* Making no decision results in webkit_policy_decision_use(). *<!-- -->/
1346 * </programlisting></informalexample>
1348 * It is possible to make policy decision asynchronously, by simply calling g_object_ref()
1349 * on the @decision argument and returning %TRUE to block the default signal handler.
1350 * If the last reference is removed on a #WebKitPolicyDecision and no decision has been
1351 * made explicitly, webkit_policy_decision_use() will be the default policy decision. The
1352 * default signal handler will simply call webkit_policy_decision_use(). Only the first
1353 * policy decision chosen for a given #WebKitPolicyDecision will have any affect.
1355 * Returns: %TRUE to stop other handlers from being invoked for the event.
1356 * %FALSE to propagate the event further.
1359 signals[DECIDE_POLICY] = g_signal_new(
1361 G_TYPE_FROM_CLASS(webViewClass),
1363 G_STRUCT_OFFSET(WebKitWebViewClass, decide_policy),
1364 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1365 g_cclosure_marshal_generic,
1366 G_TYPE_BOOLEAN, 2, /* number of parameters */
1367 WEBKIT_TYPE_POLICY_DECISION,
1368 WEBKIT_TYPE_POLICY_DECISION_TYPE);
1371 * WebKitWebView::permission-request:
1372 * @web_view: the #WebKitWebView on which the signal is emitted
1373 * @request: the #WebKitPermissionRequest
1375 * This signal is emitted when WebKit is requesting the client to
1376 * decide about a permission request, such as allowing the browser
1377 * to switch to fullscreen mode, sharing its location or similar
1380 * A possible way to use this signal could be through a dialog
1381 * allowing the user decide what to do with the request:
1383 * <informalexample><programlisting>
1384 * static gboolean permission_request_cb (WebKitWebView *web_view,
1385 * WebKitPermissionRequest *request,
1386 * GtkWindow *parent_window)
1388 * GtkWidget *dialog = gtk_message_dialog_new (parent_window,
1390 * GTK_MESSAGE_QUESTION,
1391 * GTK_BUTTONS_YES_NO,
1392 * "Allow Permission Request?");
1393 * gtk_widget_show (dialog);
1394 * gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1397 * case GTK_RESPONSE_YES:
1398 * webkit_permission_request_allow (request);
1401 * webkit_permission_request_deny (request);
1404 * gtk_widget_destroy (dialog);
1408 * </programlisting></informalexample>
1410 * It is possible to handle permission requests asynchronously, by
1411 * simply calling g_object_ref() on the @request argument and
1412 * returning %TRUE to block the default signal handler. If the
1413 * last reference is removed on a #WebKitPermissionRequest and the
1414 * request has not been handled, webkit_permission_request_deny()
1415 * will be the default action.
1417 * If the signal is not handled, the @request will be completed automatically
1418 * by the specific #WebKitPermissionRequest that could allow or deny it. Check the
1419 * documentation of classes implementing #WebKitPermissionRequest interface to know
1420 * their default action.
1422 * Returns: %TRUE to stop other handlers from being invoked for the event.
1423 * %FALSE to propagate the event further.
1426 signals[PERMISSION_REQUEST] = g_signal_new(
1427 "permission-request",
1428 G_TYPE_FROM_CLASS(webViewClass),
1430 G_STRUCT_OFFSET(WebKitWebViewClass, permission_request),
1431 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1432 g_cclosure_marshal_generic,
1433 G_TYPE_BOOLEAN, 1, /* number of parameters */
1434 WEBKIT_TYPE_PERMISSION_REQUEST);
1436 * WebKitWebView::mouse-target-changed:
1437 * @web_view: the #WebKitWebView on which the signal is emitted
1438 * @hit_test_result: a #WebKitHitTestResult
1439 * @modifiers: a bitmask of #GdkModifierType
1441 * This signal is emitted when the mouse cursor moves over an
1442 * element such as a link, image or a media element. To determine
1443 * what type of element the mouse cursor is over, a Hit Test is performed
1444 * on the current mouse coordinates and the result is passed in the
1445 * @hit_test_result argument. The @modifiers argument is a bitmask of
1446 * #GdkModifierType flags indicating the state of modifier keys.
1447 * The signal is emitted again when the mouse is moved out of the
1448 * current element with a new @hit_test_result.
1450 signals[MOUSE_TARGET_CHANGED] = g_signal_new(
1451 "mouse-target-changed",
1452 G_TYPE_FROM_CLASS(webViewClass),
1454 G_STRUCT_OFFSET(WebKitWebViewClass, mouse_target_changed),
1456 g_cclosure_marshal_generic,
1458 WEBKIT_TYPE_HIT_TEST_RESULT,
1463 * WebKitWebView::print:
1464 * @web_view: the #WebKitWebView on which the signal is emitted
1465 * @print_operation: the #WebKitPrintOperation that will handle the print request
1467 * Emitted when printing is requested on @web_view, usually by a JavaScript call,
1468 * before the print dialog is shown. This signal can be used to set the initial
1469 * print settings and page setup of @print_operation to be used as default values in
1470 * the print dialog. You can call webkit_print_operation_set_print_settings() and
1471 * webkit_print_operation_set_page_setup() and then return %FALSE to propagate the
1472 * event so that the print dialog is shown.
1474 * You can connect to this signal and return %TRUE to cancel the print operation
1475 * or implement your own print dialog.
1477 * Returns: %TRUE to stop other handlers from being invoked for the event.
1478 * %FALSE to propagate the event further.
1480 signals[PRINT] = g_signal_new(
1482 G_TYPE_FROM_CLASS(webViewClass),
1484 G_STRUCT_OFFSET(WebKitWebViewClass, print),
1485 g_signal_accumulator_true_handled, nullptr,
1486 g_cclosure_marshal_generic,
1488 WEBKIT_TYPE_PRINT_OPERATION);
1489 #endif // PLATFORM(GTK)
1492 * WebKitWebView::resource-load-started:
1493 * @web_view: the #WebKitWebView on which the signal is emitted
1494 * @resource: a #WebKitWebResource
1495 * @request: a #WebKitURIRequest
1497 * Emitted when a new resource is going to be loaded. The @request parameter
1498 * contains the #WebKitURIRequest that will be sent to the server.
1499 * You can monitor the load operation by connecting to the different signals
1502 signals[RESOURCE_LOAD_STARTED] = g_signal_new(
1503 "resource-load-started",
1504 G_TYPE_FROM_CLASS(webViewClass),
1506 G_STRUCT_OFFSET(WebKitWebViewClass, resource_load_started),
1508 g_cclosure_marshal_generic,
1510 WEBKIT_TYPE_WEB_RESOURCE,
1511 WEBKIT_TYPE_URI_REQUEST);
1514 * WebKitWebView::enter-fullscreen:
1515 * @web_view: the #WebKitWebView on which the signal is emitted.
1517 * Emitted when JavaScript code calls
1518 * <function>element.webkitRequestFullScreen</function>. If the
1519 * signal is not handled the #WebKitWebView will proceed to full screen
1520 * its top level window. This signal can be used by client code to
1521 * request permission to the user prior doing the full screen
1522 * transition and eventually prepare the top-level window
1523 * (e.g. hide some widgets that would otherwise be part of the
1524 * full screen window).
1526 * Returns: %TRUE to stop other handlers from being invoked for the event.
1527 * %FALSE to continue emission of the event.
1529 signals[ENTER_FULLSCREEN] = g_signal_new(
1531 G_TYPE_FROM_CLASS(webViewClass),
1533 G_STRUCT_OFFSET(WebKitWebViewClass, enter_fullscreen),
1534 g_signal_accumulator_true_handled, nullptr,
1535 g_cclosure_marshal_generic,
1539 * WebKitWebView::leave-fullscreen:
1540 * @web_view: the #WebKitWebView on which the signal is emitted.
1542 * Emitted when the #WebKitWebView is about to restore its top level
1543 * window out of its full screen state. This signal can be used by
1544 * client code to restore widgets hidden during the
1545 * #WebKitWebView::enter-fullscreen stage for instance.
1547 * Returns: %TRUE to stop other handlers from being invoked for the event.
1548 * %FALSE to continue emission of the event.
1550 signals[LEAVE_FULLSCREEN] = g_signal_new(
1552 G_TYPE_FROM_CLASS(webViewClass),
1554 G_STRUCT_OFFSET(WebKitWebViewClass, leave_fullscreen),
1555 g_signal_accumulator_true_handled, nullptr,
1556 g_cclosure_marshal_generic,
1560 * WebKitWebView::run-file-chooser:
1561 * @web_view: the #WebKitWebView on which the signal is emitted
1562 * @request: a #WebKitFileChooserRequest
1564 * This signal is emitted when the user interacts with a <input
1565 * type='file' /> HTML element, requesting from WebKit to show
1566 * a dialog to select one or more files to be uploaded. To let the
1567 * application know the details of the file chooser, as well as to
1568 * allow the client application to either cancel the request or
1569 * perform an actual selection of files, the signal will pass an
1570 * instance of the #WebKitFileChooserRequest in the @request
1573 * The default signal handler will asynchronously run a regular
1574 * #GtkFileChooserDialog for the user to interact with.
1576 * Returns: %TRUE to stop other handlers from being invoked for the event.
1577 * %FALSE to propagate the event further.
1580 signals[RUN_FILE_CHOOSER] = g_signal_new(
1582 G_TYPE_FROM_CLASS(webViewClass),
1584 G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
1585 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1586 g_cclosure_marshal_generic,
1587 G_TYPE_BOOLEAN, 1, /* number of parameters */
1588 WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
1591 * WebKitWebView::context-menu:
1592 * @web_view: the #WebKitWebView on which the signal is emitted
1593 * @context_menu: the proposed #WebKitContextMenu
1594 * @event: the #GdkEvent that triggered the context menu
1595 * @hit_test_result: a #WebKitHitTestResult
1597 * Emitted when a context menu is about to be displayed to give the application
1598 * a chance to customize the proposed menu, prevent the menu from being displayed,
1599 * or build its own context menu.
1602 * To customize the proposed menu you can use webkit_context_menu_prepend(),
1603 * webkit_context_menu_append() or webkit_context_menu_insert() to add new
1604 * #WebKitContextMenuItem<!-- -->s to @context_menu, webkit_context_menu_move_item()
1605 * to reorder existing items, or webkit_context_menu_remove() to remove an
1606 * existing item. The signal handler should return %FALSE, and the menu represented
1607 * by @context_menu will be shown.
1608 * </para></listitem>
1610 * To prevent the menu from being displayed you can just connect to this signal
1611 * and return %TRUE so that the proposed menu will not be shown.
1612 * </para></listitem>
1614 * To build your own menu, you can remove all items from the proposed menu with
1615 * webkit_context_menu_remove_all(), add your own items and return %FALSE so
1616 * that the menu will be shown. You can also ignore the proposed #WebKitContextMenu,
1617 * build your own #GtkMenu and return %TRUE to prevent the proposed menu from being shown.
1618 * </para></listitem>
1620 * If you just want the default menu to be shown always, simply don't connect to this
1621 * signal because showing the proposed context menu is the default behaviour.
1622 * </para></listitem>
1625 * The @event is expected to be one of the following types:
1628 * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu
1629 * was triggered with mouse.
1630 * </para></listitem>
1632 * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show
1634 * </para></listitem>
1636 * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget::popup-menu
1637 * signal was used to show the context menu.
1638 * </para></listitem>
1641 * If the signal handler returns %FALSE the context menu represented by @context_menu
1642 * will be shown, if it return %TRUE the context menu will not be shown.
1644 * The proposed #WebKitContextMenu passed in @context_menu argument is only valid
1645 * during the signal emission.
1647 * Returns: %TRUE to stop other handlers from being invoked for the event.
1648 * %FALSE to propagate the event further.
1650 signals[CONTEXT_MENU] = g_signal_new(
1652 G_TYPE_FROM_CLASS(webViewClass),
1654 G_STRUCT_OFFSET(WebKitWebViewClass, context_menu),
1655 g_signal_accumulator_true_handled, nullptr,
1656 g_cclosure_marshal_generic,
1658 WEBKIT_TYPE_CONTEXT_MENU,
1660 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1662 G_TYPE_POINTER, // FIXME: use a wpe thing here. I'm not sure we want to expose libwpe in the API.
1664 WEBKIT_TYPE_HIT_TEST_RESULT);
1667 * WebKitWebView::context-menu-dismissed:
1668 * @web_view: the #WebKitWebView on which the signal is emitted
1670 * Emitted after #WebKitWebView::context-menu signal, if the context menu is shown,
1671 * to notify that the context menu is dismissed.
1673 signals[CONTEXT_MENU_DISMISSED] =
1674 g_signal_new("context-menu-dismissed",
1675 G_TYPE_FROM_CLASS(webViewClass),
1677 G_STRUCT_OFFSET(WebKitWebViewClass, context_menu_dismissed),
1679 g_cclosure_marshal_VOID__VOID,
1683 * WebKitWebView::submit-form:
1684 * @web_view: the #WebKitWebView on which the signal is emitted
1685 * @request: a #WebKitFormSubmissionRequest
1687 * This signal is emitted when a form is about to be submitted. The @request
1688 * argument passed contains information about the text fields of the form. This
1689 * is typically used to store login information that can be used later to
1690 * pre-fill the form.
1691 * The form will not be submitted until webkit_form_submission_request_submit() is called.
1693 * It is possible to handle the form submission request asynchronously, by
1694 * simply calling g_object_ref() on the @request argument and calling
1695 * webkit_form_submission_request_submit() when done to continue with the form submission.
1696 * If the last reference is removed on a #WebKitFormSubmissionRequest and the
1697 * form has not been submitted, webkit_form_submission_request_submit() will be called.
1699 signals[SUBMIT_FORM] =
1700 g_signal_new("submit-form",
1701 G_TYPE_FROM_CLASS(webViewClass),
1703 G_STRUCT_OFFSET(WebKitWebViewClass, submit_form),
1705 g_cclosure_marshal_VOID__OBJECT,
1707 WEBKIT_TYPE_FORM_SUBMISSION_REQUEST);
1710 * WebKitWebView::insecure-content-detected:
1711 * @web_view: the #WebKitWebView on which the signal is emitted
1712 * @event: the #WebKitInsecureContentEvent
1714 * This signal is emitted when insecure content has been detected
1715 * in a page loaded through a secure connection. This typically
1716 * means that a external resource from an unstrusted source has
1717 * been run or displayed, resulting in a mix of HTTPS and
1718 * non-HTTPS content.
1720 * You can check the @event parameter to know exactly which kind
1721 * of event has been detected (see #WebKitInsecureContentEvent).
1723 signals[INSECURE_CONTENT_DETECTED] =
1724 g_signal_new("insecure-content-detected",
1725 G_TYPE_FROM_CLASS(webViewClass),
1727 G_STRUCT_OFFSET(WebKitWebViewClass, insecure_content_detected),
1729 g_cclosure_marshal_VOID__ENUM,
1731 WEBKIT_TYPE_INSECURE_CONTENT_EVENT);
1734 * WebKitWebView::web-process-crashed:
1735 * @web_view: the #WebKitWebView
1737 * This signal is emitted when the web process crashes.
1739 * Returns: %TRUE to stop other handlers from being invoked for the event.
1740 * %FALSE to propagate the event further.
1742 signals[WEB_PROCESS_CRASHED] = g_signal_new(
1743 "web-process-crashed",
1744 G_TYPE_FROM_CLASS(webViewClass),
1746 G_STRUCT_OFFSET(WebKitWebViewClass, web_process_crashed),
1747 g_signal_accumulator_true_handled, nullptr,
1748 g_cclosure_marshal_generic,
1752 * WebKitWebView::authenticate:
1753 * @web_view: the #WebKitWebView on which the signal is emitted
1754 * @request: a #WebKitAuthenticationRequest
1756 * This signal is emitted when the user is challenged with HTTP
1757 * authentication. To let the application access or supply
1758 * the credentials as well as to allow the client application
1759 * to either cancel the request or perform the authentication,
1760 * the signal will pass an instance of the
1761 * #WebKitAuthenticationRequest in the @request argument.
1762 * To handle this signal asynchronously you should keep a ref
1763 * of the request and return %TRUE. To disable HTTP authentication
1764 * entirely, connect to this signal and simply return %TRUE.
1766 * The default signal handler will run a default authentication
1767 * dialog asynchronously for the user to interact with.
1769 * Returns: %TRUE to stop other handlers from being invoked for the event.
1770 * %FALSE to propagate the event further.
1774 signals[AUTHENTICATE] = g_signal_new(
1776 G_TYPE_FROM_CLASS(webViewClass),
1778 G_STRUCT_OFFSET(WebKitWebViewClass, authenticate),
1779 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1780 g_cclosure_marshal_generic,
1781 G_TYPE_BOOLEAN, 1, /* number of parameters */
1782 WEBKIT_TYPE_AUTHENTICATION_REQUEST);
1785 * WebKitWebView::show-notification:
1786 * @web_view: the #WebKitWebView
1787 * @notification: a #WebKitNotification
1789 * This signal is emitted when a notification should be presented to the
1790 * user. The @notification is kept alive until either: 1) the web page cancels it
1791 * or 2) a navigation happens.
1793 * The default handler will emit a notification using libnotify, if built with
1796 * Returns: %TRUE to stop other handlers from being invoked. %FALSE otherwise.
1800 signals[SHOW_NOTIFICATION] = g_signal_new(
1801 "show-notification",
1802 G_TYPE_FROM_CLASS(gObjectClass),
1804 G_STRUCT_OFFSET(WebKitWebViewClass, show_notification),
1805 g_signal_accumulator_true_handled, nullptr /* accumulator data */,
1806 g_cclosure_marshal_generic,
1808 WEBKIT_TYPE_NOTIFICATION);
1812 * WebKitWebView::run-color-chooser:
1813 * @web_view: the #WebKitWebView on which the signal is emitted
1814 * @request: a #WebKitColorChooserRequest
1816 * This signal is emitted when the user interacts with a <input
1817 * type='color' /> HTML element, requesting from WebKit to show
1818 * a dialog to select a color. To let the application know the details of
1819 * the color chooser, as well as to allow the client application to either
1820 * cancel the request or perform an actual color selection, the signal will
1821 * pass an instance of the #WebKitColorChooserRequest in the @request
1824 * It is possible to handle this request asynchronously by increasing the
1825 * reference count of the request.
1827 * The default signal handler will asynchronously run a regular
1828 * #GtkColorChooser for the user to interact with.
1830 * Returns: %TRUE to stop other handlers from being invoked for the event.
1831 * %FALSE to propagate the event further.
1835 signals[RUN_COLOR_CHOOSER] = g_signal_new(
1836 "run-color-chooser",
1837 G_TYPE_FROM_CLASS(webViewClass),
1839 G_STRUCT_OFFSET(WebKitWebViewClass, run_color_chooser),
1840 g_signal_accumulator_true_handled, nullptr,
1841 g_cclosure_marshal_generic,
1843 WEBKIT_TYPE_COLOR_CHOOSER_REQUEST);
1846 * WebKitWebView::show-option-menu:
1847 * @web_view: the #WebKitWebView on which the signal is emitted
1848 * @menu: the #WebKitOptionMenu
1849 * @event: the #GdkEvent that triggered the menu, or %NULL
1850 * @rectangle: the option element area
1852 * This signal is emitted when a select element in @web_view needs to display a
1853 * dropdown menu. This signal can be used to show a custom menu, using @menu to get
1854 * the details of all items that should be displayed. The area of the element in the
1855 * #WebKitWebView is given as @rectangle parameter, it can be used to position the
1856 * menu. If this was triggered by a user interaction, like a mouse click,
1857 * @event parameter provides the #GdkEvent.
1858 * To handle this signal asynchronously you should keep a ref of the @menu.
1860 * The default signal handler will pop up a #GtkMenu.
1862 * Returns: %TRUE to stop other handlers from being invoked for the event.
1863 * %FALSE to propagate the event further.
1867 signals[SHOW_OPTION_MENU] = g_signal_new(
1869 G_TYPE_FROM_CLASS(webViewClass),
1871 G_STRUCT_OFFSET(WebKitWebViewClass, show_option_menu),
1872 g_signal_accumulator_true_handled, nullptr,
1873 g_cclosure_marshal_generic,
1875 WEBKIT_TYPE_OPTION_MENU,
1876 GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
1877 GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
1878 #endif // PLATFORM(GTK)
1881 static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView)
1883 if (!webView->priv->authenticationRequest)
1886 webkit_authentication_request_cancel(webView->priv->authenticationRequest.get());
1887 webView->priv->authenticationRequest.clear();
1890 void webkitWebViewCreatePage(WebKitWebView* webView, Ref<API::PageConfiguration>&& configuration)
1893 webkitWebViewBaseCreateWebPage(WEBKIT_WEB_VIEW_BASE(webView), WTFMove(configuration));
1895 webView->priv->view.reset(WKWPE::View::create(nullptr, configuration.get()));
1899 WebPageProxy& webkitWebViewGetPage(WebKitWebView* webView)
1901 return getPage(webView);
1904 void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
1906 WebKitWebViewPrivate* priv = webView->priv;
1907 switch (loadEvent) {
1908 case WEBKIT_LOAD_STARTED:
1909 webkitWebViewCancelFaviconRequest(webView);
1910 webkitWebViewWatchForChangesInFavicon(webView);
1911 webkitWebViewCancelAuthenticationRequest(webView);
1912 priv->loadingResourcesMap.clear();
1913 priv->mainResource = nullptr;
1915 case WEBKIT_LOAD_COMMITTED: {
1916 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get());
1917 GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data()));
1918 webkitWebViewUpdateFaviconURI(webView, faviconURI.get());
1921 case WEBKIT_LOAD_FINISHED:
1922 webkitWebViewCancelAuthenticationRequest(webView);
1928 g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent);
1931 void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error)
1933 webkitWebViewCancelAuthenticationRequest(webView);
1935 gboolean returnValue;
1936 g_signal_emit(webView, signals[LOAD_FAILED], 0, loadEvent, failingURI, error, &returnValue);
1937 g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
1940 void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError* error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate)
1942 webkitWebViewCancelAuthenticationRequest(webView);
1944 WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context.get());
1945 if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) {
1946 gboolean returnValue;
1947 g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, failingURI, certificate, tlsErrors, &returnValue);
1949 g_signal_emit(webView, signals[LOAD_FAILED], 0, WEBKIT_LOAD_STARTED, failingURI, error, &returnValue);
1952 g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED);
1955 void webkitWebViewGetLoadDecisionForIcon(WebKitWebView* webView, const LinkIcon& icon, Function<void(bool)>&& completionHandler)
1957 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
1958 webkitFaviconDatabaseGetLoadDecisionForIcon(database, icon, getPage(webView).pageLoadState().activeURL(), WTFMove(completionHandler));
1961 void webkitWebViewSetIcon(WebKitWebView* webView, const LinkIcon& icon, API::Data& iconData)
1963 WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(webView->priv->context.get());
1964 webkitFaviconDatabaseSetIconForPageURL(database, icon, iconData, getPage(webView).pageLoadState().activeURL());
1967 WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, const WindowFeatures& windowFeatures, WebKitNavigationAction* navigationAction)
1969 WebKitWebView* newWebView;
1970 g_signal_emit(webView, signals[CREATE], 0, navigationAction, &newWebView);
1974 webkitWindowPropertiesUpdateFromWebWindowFeatures(newWebView->priv->windowProperties.get(), windowFeatures);
1976 RefPtr<WebPageProxy> newPage = &getPage(newWebView);
1977 return newPage.leakRef();
1980 void webkitWebViewReadyToShowPage(WebKitWebView* webView)
1982 g_signal_emit(webView, signals[READY_TO_SHOW], 0, NULL);
1985 void webkitWebViewRunAsModal(WebKitWebView* webView)
1987 g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL);
1989 webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE));
1992 // This is to suppress warnings about gdk_threads_leave and gdk_threads_enter.
1993 #pragma GCC diagnostic push
1994 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1995 gdk_threads_leave();
1998 g_main_loop_run(webView->priv->modalLoop.get());
2001 gdk_threads_enter();
2002 #pragma GCC diagnostic pop
2006 void webkitWebViewClosePage(WebKitWebView* webView)
2008 g_signal_emit(webView, signals[CLOSE], 0, NULL);
2011 void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message)
2013 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_ALERT, message);
2014 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2015 gboolean returnValue;
2016 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2019 bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message)
2021 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_CONFIRM, message);
2022 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2023 gboolean returnValue;
2024 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2025 return dialog.confirmed;
2028 CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText)
2030 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText);
2031 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2032 gboolean returnValue;
2033 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2037 bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message)
2039 WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message);
2040 SetForScope<WebKitScriptDialog*> change(webView->priv->currentScriptDialog, &dialog);
2041 gboolean returnValue;
2042 g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue);
2043 return dialog.confirmed;
2046 bool webkitWebViewIsShowingScriptDialog(WebKitWebView* webView)
2048 if (!webView->priv->currentScriptDialog)
2051 // FIXME: Add API to ask the user in case default implementation is not being used.
2052 return webkitScriptDialogIsRunning(webView->priv->currentScriptDialog);
2055 String webkitWebViewGetCurrentScriptDialogMessage(WebKitWebView* webView)
2057 if (!webView->priv->currentScriptDialog)
2060 return String::fromUTF8(webView->priv->currentScriptDialog->message);
2063 void webkitWebViewSetCurrentScriptDialogUserInput(WebKitWebView* webView, const String& userInput)
2065 if (!webView->priv->currentScriptDialog)
2068 // FIXME: Add API to ask the user in case default implementation is not being used.
2069 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2070 webkitScriptDialogSetUserInput(webView->priv->currentScriptDialog, userInput);
2073 void webkitWebViewAcceptCurrentScriptDialog(WebKitWebView* webView)
2075 if (!webView->priv->currentScriptDialog)
2078 // FIXME: Add API to ask the user in case default implementation is not being used.
2079 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2080 webkitScriptDialogAccept(webView->priv->currentScriptDialog);
2083 void webkitWebViewDismissCurrentScriptDialog(WebKitWebView* webView)
2085 if (!webView->priv->currentScriptDialog)
2088 // FIXME: Add API to ask the user in case default implementation is not being used.
2089 if (webkitScriptDialogIsRunning(webView->priv->currentScriptDialog))
2090 webkitScriptDialogDismiss(webView->priv->currentScriptDialog);
2093 std::optional<WebKitScriptDialogType> webkitWebViewGetCurrentScriptDialogType(WebKitWebView* webView)
2095 if (!webView->priv->currentScriptDialog)
2096 return std::nullopt;
2098 return static_cast<WebKitScriptDialogType>(webView->priv->currentScriptDialog->type);
2101 void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision)
2103 gboolean returnValue;
2104 g_signal_emit(webView, signals[DECIDE_POLICY], 0, decision, type, &returnValue);
2107 void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermissionRequest* request)
2109 gboolean returnValue;
2110 g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue);
2113 void webkitWebViewMouseTargetChanged(WebKitWebView* webView, const WebHitTestResultData& hitTestResult, WebEvent::Modifiers modifiers)
2116 webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult.elementBoundingBox);
2119 WebKitWebViewPrivate* priv = webView->priv;
2120 if (priv->mouseTargetHitTestResult
2121 && priv->mouseTargetModifiers == modifiers
2122 && webkitHitTestResultCompare(priv->mouseTargetHitTestResult.get(), hitTestResult))
2125 priv->mouseTargetModifiers = modifiers;
2126 priv->mouseTargetHitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResult));
2127 g_signal_emit(webView, signals[MOUSE_TARGET_CHANGED], 0, priv->mouseTargetHitTestResult.get(), toPlatformModifiers(modifiers));
2130 void webkitWebViewHandleDownloadRequest(WebKitWebView* webView, DownloadProxy* downloadProxy)
2132 ASSERT(downloadProxy);
2133 GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy);
2134 webkitDownloadSetWebView(download.get(), webView);
2138 void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame)
2140 auto printOperation = adoptGRef(webkit_print_operation_new(webView));
2141 webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync);
2142 gboolean returnValue;
2143 g_signal_emit(webView, signals[PRINT], 0, printOperation.get(), &returnValue);
2147 WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, frame);
2148 if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL)
2150 g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
2154 void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request)
2156 WebKitWebViewPrivate* priv = webView->priv;
2157 bool isMainResource = frame->isMainFrame() && !priv->mainResource;
2158 WebKitWebResource* resource = webkitWebResourceCreate(frame, request, isMainResource);
2160 priv->mainResource = resource;
2161 priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
2162 g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
2165 WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2167 GRefPtr<WebKitWebResource> resource = webView->priv->loadingResourcesMap.get(resourceIdentifier);
2168 return resource.get();
2171 void webkitWebViewRemoveLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
2173 WebKitWebViewPrivate* priv = webView->priv;
2174 ASSERT(priv->loadingResourcesMap.contains(resourceIdentifier));
2175 priv->loadingResourcesMap.remove(resourceIdentifier);
2178 void webkitWebViewEnterFullScreen(WebKitWebView* webView)
2180 #if ENABLE(FULLSCREEN_API)
2181 gboolean returnValue;
2182 g_signal_emit(webView, signals[ENTER_FULLSCREEN], 0, &returnValue);
2185 webkitWebViewBaseEnterFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2190 void webkitWebViewExitFullScreen(WebKitWebView* webView)
2192 #if ENABLE(FULLSCREEN_API)
2193 gboolean returnValue;
2194 g_signal_emit(webView, signals[LEAVE_FULLSCREEN], 0, &returnValue);
2197 webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(webView));
2202 void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChooserRequest* request)
2204 gboolean returnValue;
2205 g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
2209 static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView)
2211 g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL);
2214 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2216 WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView);
2217 WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase);
2218 ASSERT(contextMenuProxy);
2220 GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2222 webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2224 GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2225 GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase));
2226 gboolean returnValue;
2227 g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue);
2231 Vector<WebContextMenuItemGlib> contextMenuItems;
2232 webkitContextMenuPopulate(contextMenu.get(), contextMenuItems);
2233 contextMenuProxy->populate(contextMenuItems);
2235 g_signal_connect(contextMenuProxy->gtkMenu(), "deactivate", G_CALLBACK(contextMenuDismissed), webView);
2237 // Clear the menu to make sure it's useless after signal emission.
2238 webkit_context_menu_remove_all(contextMenu.get());
2241 void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData)
2243 GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu));
2245 webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData);
2246 GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData));
2247 gboolean returnValue;
2248 g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), nullptr, hitTestResult.get(), &returnValue);
2252 void webkitWebViewSubmitFormRequest(WebKitWebView* webView, WebKitFormSubmissionRequest* request)
2254 g_signal_emit(webView, signals[SUBMIT_FORM], 0, request);
2257 void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge)
2259 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2260 gboolean privateBrowsingEnabled = webView->priv->isEphemeral || webkit_settings_get_enable_private_browsing(webView->priv->settings.get());
2261 G_GNUC_END_IGNORE_DEPRECATIONS;
2262 webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled));
2263 gboolean returnValue;
2264 g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue);
2267 void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecureContentEvent type)
2269 g_signal_emit(webView, signals[INSECURE_CONTENT_DETECTED], 0, type);
2272 bool webkitWebViewEmitShowNotification(WebKitWebView* webView, WebKitNotification* webNotification)
2275 g_signal_emit(webView, signals[SHOW_NOTIFICATION], 0, webNotification, &handled);
2280 bool webkitWebViewEmitRunColorChooser(WebKitWebView* webView, WebKitColorChooserRequest* request)
2283 g_signal_emit(webView, signals[RUN_COLOR_CHOOSER], 0, request, &handled);
2288 void webkitWebViewSelectionDidChange(WebKitWebView* webView)
2290 if (!webView->priv->editorState)
2293 webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView).editorState());
2296 void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView* webView, InstallMissingMediaPluginsPermissionRequest& request)
2299 GRefPtr<WebKitInstallMissingMediaPluginsPermissionRequest> installMediaPluginsPermissionRequest = adoptGRef(webkitInstallMissingMediaPluginsPermissionRequestCreate(request));
2300 webkitWebViewMakePermissionRequest(webView, WEBKIT_PERMISSION_REQUEST(installMediaPluginsPermissionRequest.get()));
2302 ASSERT_NOT_REACHED();
2306 WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webView)
2308 return webView->priv->websiteDataManager.get();
2312 bool webkitWebViewShowOptionMenu(WebKitWebView* webView, const IntRect& rect, WebKitOptionMenu* menu, const GdkEvent* event)
2314 GdkRectangle menuRect = rect;
2316 g_signal_emit(webView, signals[SHOW_OPTION_MENU], 0, menu, event, &menuRect, &handled);
2322 * webkit_web_view_get_context:
2323 * @web_view: a #WebKitWebView
2325 * Gets the web context of @web_view.
2327 * Returns: (transfer none): the #WebKitWebContext of the view
2329 WebKitWebContext* webkit_web_view_get_context(WebKitWebView *webView)
2331 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2333 return webView->priv->context.get();
2337 * webkit_web_view_get_user_content_manager:
2338 * @web_view: a #WebKitWebView
2340 * Gets the user content manager associated to @web_view.
2342 * Returns: (transfer none): the #WebKitUserContentManager associated with the view
2346 WebKitUserContentManager* webkit_web_view_get_user_content_manager(WebKitWebView* webView)
2348 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2350 return webView->priv->userContentManager.get();
2354 * webkit_web_view_is_ephemeral:
2355 * @web_view: a #WebKitWebView
2357 * Get whether a #WebKitWebView is ephemeral. To create an ephemeral #WebKitWebView you need to
2358 * use g_object_new() and pass is-ephemeral property with %TRUE value. See
2359 * #WebKitWebView:is-ephemeral for more details.
2360 * If @web_view was created with a ephemeral #WebKitWebView:related-view or an
2361 * ephemeral #WebKitWebView:web-context it will also be ephemeral.
2363 * Returns: %TRUE if @web_view is ephemeral or %FALSE otherwise.
2367 gboolean webkit_web_view_is_ephemeral(WebKitWebView* webView)
2369 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2371 return webView->priv->isEphemeral;
2375 * webkit_web_view_is_controlled_by_automation:
2376 * @web_view: a #WebKitWebView
2378 * Get whether a #WebKitWebView was created with #WebKitWebView:is-controlled-by-automation
2379 * property enabled. Only #WebKitWebView<!-- -->s controlled by automation can be used in an
2380 * automation session.
2382 * Returns: %TRUE if @web_view is controlled by automation, or %FALSE otherwise.
2386 gboolean webkit_web_view_is_controlled_by_automation(WebKitWebView* webView)
2388 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2390 return webView->priv->isControlledByAutomation;
2394 * webkit_web_view_get_website_data_manager:
2395 * @web_view: a #WebKitWebView
2397 * Get the #WebKitWebsiteDataManager associated to @web_view. If @web_view is not ephemeral,
2398 * the returned #WebKitWebsiteDataManager will be the same as the #WebKitWebsiteDataManager
2399 * of @web_view's #WebKitWebContext.
2401 * Returns: (transfer none): a #WebKitWebsiteDataManager
2405 WebKitWebsiteDataManager* webkit_web_view_get_website_data_manager(WebKitWebView* webView)
2407 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2409 if (webView->priv->websiteDataManager)
2410 return webView->priv->websiteDataManager.get();
2412 return webkit_web_context_get_website_data_manager(webView->priv->context.get());
2416 * webkit_web_view_try_close:
2417 * @web_view: a #WebKitWebView
2419 * Tries to close the @web_view. This will fire the onbeforeunload event
2420 * to ask the user for confirmation to close the page. If there isn't an
2421 * onbeforeunload event handler or the user confirms to close the page,
2422 * the #WebKitWebView::close signal is emitted, otherwise nothing happens.
2426 void webkit_web_view_try_close(WebKitWebView *webView)
2428 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2429 if (getPage(webView).tryClose())
2430 webkitWebViewClosePage(webView);
2434 * webkit_web_view_load_uri:
2435 * @web_view: a #WebKitWebView
2436 * @uri: an URI string
2438 * Requests loading of the specified URI string.
2439 * You can monitor the load operation by connecting to
2440 * #WebKitWebView::load-changed signal.
2442 void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri)
2444 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2445 g_return_if_fail(uri);
2447 GUniquePtr<SoupURI> soupURI(soup_uri_new(uri));
2448 getPage(webView).loadRequest(URL(soupURI.get()));
2452 * webkit_web_view_load_html:
2453 * @web_view: a #WebKitWebView
2454 * @content: The HTML string to load
2455 * @base_uri: (allow-none): The base URI for relative locations or %NULL
2457 * Load the given @content string with the specified @base_uri.
2458 * If @base_uri is not %NULL, relative URLs in the @content will be
2459 * resolved against @base_uri and absolute local paths must be children of the @base_uri.
2460 * For security reasons absolute local paths that are not children of @base_uri
2461 * will cause the web process to terminate.
2462 * If you need to include URLs in @content that are local paths in a different
2463 * directory than @base_uri you can build a data URI for them. When @base_uri is %NULL,
2464 * it defaults to "about:blank". The mime type of the document will be "text/html".
2465 * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2467 void webkit_web_view_load_html(WebKitWebView* webView, const gchar* content, const gchar* baseURI)
2469 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2470 g_return_if_fail(content);
2472 getPage(webView).loadHTMLString(String::fromUTF8(content), String::fromUTF8(baseURI));
2476 * webkit_web_view_load_alternate_html:
2477 * @web_view: a #WebKitWebView
2478 * @content: the new content to display as the main page of the @web_view
2479 * @content_uri: the URI for the alternate page content
2480 * @base_uri: (allow-none): the base URI for relative locations or %NULL
2482 * Load the given @content string for the URI @content_uri.
2483 * This allows clients to display page-loading errors in the #WebKitWebView itself.
2484 * When this method is called from #WebKitWebView::load-failed signal to show an
2485 * error page, then the back-forward list is maintained appropriately.
2486 * For everything else this method works the same way as webkit_web_view_load_html().
2488 void webkit_web_view_load_alternate_html(WebKitWebView* webView, const gchar* content, const gchar* contentURI, const gchar* baseURI)
2490 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2491 g_return_if_fail(content);
2492 g_return_if_fail(contentURI);
2494 getPage(webView).loadAlternateHTMLString(String::fromUTF8(content), String::fromUTF8(baseURI), String::fromUTF8(contentURI));
2498 * webkit_web_view_load_plain_text:
2499 * @web_view: a #WebKitWebView
2500 * @plain_text: The plain text to load
2502 * Load the specified @plain_text string into @web_view. The mime type of
2503 * document will be "text/plain". You can monitor the load
2504 * operation by connecting to #WebKitWebView::load-changed signal.
2506 void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainText)
2508 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2509 g_return_if_fail(plainText);
2511 getPage(webView).loadPlainTextString(String::fromUTF8(plainText));
2514 static void releaseGBytes(unsigned char*, const void* bytes)
2516 // Balanced by g_bytes_ref in webkit_web_view_load_bytes().
2517 g_bytes_unref(static_cast<GBytes*>(const_cast<void*>(bytes)));
2521 * webkit_web_view_load_bytes:
2522 * @web_view: a #WebKitWebView
2523 * @bytes: input data to load
2524 * @mime_type: (allow-none): the MIME type of @bytes, or %NULL
2525 * @encoding: (allow-none): the character encoding of @bytes, or %NULL
2526 * @base_uri: (allow-none): the base URI for relative locations or %NULL
2528 * Load the specified @bytes into @web_view using the given @mime_type and @encoding.
2529 * When @mime_type is %NULL, it defaults to "text/html".
2530 * When @encoding is %NULL, it defaults to "UTF-8".
2531 * When @base_uri is %NULL, it defaults to "about:blank".
2532 * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal.
2536 void webkit_web_view_load_bytes(WebKitWebView* webView, GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI)
2538 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2539 g_return_if_fail(bytes);
2541 gsize bytesDataSize;
2542 gconstpointer bytesData = g_bytes_get_data(bytes, &bytesDataSize);
2543 g_return_if_fail(bytesDataSize);
2545 // Balanced by g_bytes_unref in releaseGBytes.
2548 Ref<API::Data> data = API::Data::createWithoutCopying(static_cast<const unsigned char*>(bytesData), bytesDataSize, releaseGBytes, bytes);
2549 getPage(webView).loadData(data.ptr(), mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"),
2550 encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), String::fromUTF8(baseURI));
2554 * webkit_web_view_load_request:
2555 * @web_view: a #WebKitWebView
2556 * @request: a #WebKitURIRequest to load
2558 * Requests loading of the specified #WebKitURIRequest.
2559 * You can monitor the load operation by connecting to
2560 * #WebKitWebView::load-changed signal.
2562 void webkit_web_view_load_request(WebKitWebView* webView, WebKitURIRequest* request)
2564 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2565 g_return_if_fail(WEBKIT_IS_URI_REQUEST(request));
2567 ResourceRequest resourceRequest;
2568 webkitURIRequestGetResourceRequest(request, resourceRequest);
2569 getPage(webView).loadRequest(WTFMove(resourceRequest));
2573 * webkit_web_view_get_page_id:
2574 * @web_view: a #WebKitWebView
2576 * Get the identifier of the #WebKitWebPage corresponding to
2577 * the #WebKitWebView
2579 * Returns: the page ID of @web_view.
2581 guint64 webkit_web_view_get_page_id(WebKitWebView* webView)
2583 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2585 return getPage(webView).pageID();
2589 * webkit_web_view_get_title:
2590 * @web_view: a #WebKitWebView
2592 * Gets the value of the #WebKitWebView:title property.
2593 * You can connect to notify::title signal of @web_view to
2594 * be notified when the title has been received.
2596 * Returns: The main frame document title of @web_view.
2598 const gchar* webkit_web_view_get_title(WebKitWebView* webView)
2600 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2602 return webView->priv->title.data();
2606 * webkit_web_view_reload:
2607 * @web_view: a #WebKitWebView
2609 * Reloads the current contents of @web_view.
2610 * See also webkit_web_view_reload_bypass_cache().
2612 void webkit_web_view_reload(WebKitWebView* webView)
2614 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2616 getPage(webView).reload({ });
2620 * webkit_web_view_reload_bypass_cache:
2621 * @web_view: a #WebKitWebView
2623 * Reloads the current contents of @web_view without
2624 * using any cached data.
2626 void webkit_web_view_reload_bypass_cache(WebKitWebView* webView)
2628 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2630 getPage(webView).reload(WebCore::ReloadOption::FromOrigin);
2634 * webkit_web_view_stop_loading:
2635 * @web_view: a #WebKitWebView
2637 * Stops any ongoing loading operation in @web_view.
2638 * This method does nothing if no content is being loaded.
2639 * If there is a loading operation in progress, it will be cancelled and
2640 * #WebKitWebView::load-failed signal will be emitted with
2641 * %WEBKIT_NETWORK_ERROR_CANCELLED error.
2643 void webkit_web_view_stop_loading(WebKitWebView* webView)
2645 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2647 getPage(webView).stopLoading();
2651 * webkit_web_view_is_loading:
2652 * @web_view: a #WebKitWebView
2654 * Gets the value of the #WebKitWebView:is-loading property.
2655 * You can monitor when a #WebKitWebView is loading a page by connecting to
2656 * notify::is-loading signal of @web_view. This is useful when you are
2657 * interesting in knowing when the view is loading something but not in the
2658 * details about the status of the load operation, for example to start a spinner
2659 * when the view is loading a page and stop it when it finishes.
2661 * Returns: %TRUE if @web_view is loading a page or %FALSE otherwise.
2663 gboolean webkit_web_view_is_loading(WebKitWebView* webView)
2665 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2667 return webView->priv->isLoading;
2671 * webkit_web_view_is_playing_audio:
2672 * @web_view: a #WebKitWebView
2674 * Gets the value of the #WebKitWebView:is-playing-audio property.
2675 * You can monitor when a page in a #WebKitWebView is playing audio by
2676 * connecting to the notify::is-playing-audio signal of @web_view. This
2677 * is useful when the application wants to provide visual feedback when a
2678 * page is producing sound.
2680 * Returns: %TRUE if a page in @web_view is playing audio or %FALSE otherwise.
2684 gboolean webkit_web_view_is_playing_audio(WebKitWebView* webView)
2686 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2688 return getPage(webView).isPlayingAudio();
2692 * webkit_web_view_go_back:
2693 * @web_view: a #WebKitWebView
2695 * Loads the previous history item.
2696 * You can monitor the load operation by connecting to
2697 * #WebKitWebView::load-changed signal.
2699 void webkit_web_view_go_back(WebKitWebView* webView)
2701 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2703 getPage(webView).goBack();
2707 * webkit_web_view_can_go_back:
2708 * @web_view: a #WebKitWebView
2710 * Determines whether @web_view has a previous history item.
2712 * Returns: %TRUE if able to move back or %FALSE otherwise.
2714 gboolean webkit_web_view_can_go_back(WebKitWebView* webView)
2716 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2718 return !!getPage(webView).backForwardList().backItem();
2722 * webkit_web_view_go_forward:
2723 * @web_view: a #WebKitWebView
2725 * Loads the next history item.
2726 * You can monitor the load operation by connecting to
2727 * #WebKitWebView::load-changed signal.
2729 void webkit_web_view_go_forward(WebKitWebView* webView)
2731 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2733 getPage(webView).goForward();
2737 * webkit_web_view_can_go_forward:
2738 * @web_view: a #WebKitWebView
2740 * Determines whether @web_view has a next history item.
2742 * Returns: %TRUE if able to move forward or %FALSE otherwise.
2744 gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
2746 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
2748 return !!getPage(webView).backForwardList().forwardItem();
2752 * webkit_web_view_get_uri:
2753 * @web_view: a #WebKitWebView
2755 * Returns the current active URI of @web_view. The active URI might change during
2760 * When nothing has been loaded yet on @web_view the active URI is %NULL.
2761 * </para></listitem>
2763 * When a new load operation starts the active URI is the requested URI:
2766 * If the load operation was started by webkit_web_view_load_uri(),
2767 * the requested URI is the given one.
2768 * </para></listitem>
2770 * If the load operation was started by webkit_web_view_load_html(),
2771 * the requested URI is "about:blank".
2772 * </para></listitem>
2774 * If the load operation was started by webkit_web_view_load_alternate_html(),
2775 * the requested URI is content URI provided.
2776 * </para></listitem>
2778 * If the load operation was started by webkit_web_view_go_back() or
2779 * webkit_web_view_go_forward(), the requested URI is the original URI
2780 * of the previous/next item in the #WebKitBackForwardList of @web_view.
2781 * </para></listitem>
2783 * If the load operation was started by
2784 * webkit_web_view_go_to_back_forward_list_item(), the requested URI
2785 * is the opriginal URI of the given #WebKitBackForwardListItem.
2786 * </para></listitem>
2788 * </para></listitem>
2790 * If there is a server redirection during the load operation,
2791 * the active URI is the redirected URI. When the signal
2792 * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_REDIRECTED
2793 * event, the active URI is already updated to the redirected URI.
2794 * </para></listitem>
2796 * When the signal #WebKitWebView::load-changed is emitted
2797 * with %WEBKIT_LOAD_COMMITTED event, the active URI is the final
2798 * one and it will not change unless a new load operation is started
2799 * or a navigation action within the same page is performed.
2800 * </para></listitem>
2803 * You can monitor the active URI by connecting to the notify::uri
2804 * signal of @web_view.
2806 * Returns: the current active URI of @web_view or %NULL
2807 * if nothing has been loaded yet.
2809 const gchar* webkit_web_view_get_uri(WebKitWebView* webView)
2811 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2813 return webView->priv->activeURI.data();
2817 * webkit_web_view_get_favicon:
2818 * @web_view: a #WebKitWebView
2820 * Returns favicon currently associated to @web_view, if any. You can
2821 * connect to notify::favicon signal of @web_view to be notified when
2822 * the favicon is available.
2824 * Returns: (transfer none): a pointer to a #cairo_surface_t with the
2825 * favicon or %NULL if there's no icon associated with @web_view.
2827 cairo_surface_t* webkit_web_view_get_favicon(WebKitWebView* webView)
2829 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2830 if (webView->priv->activeURI.isNull())
2833 return webView->priv->favicon.get();
2837 * webkit_web_view_get_custom_charset:
2838 * @web_view: a #WebKitWebView
2840 * Returns the current custom character encoding name of @web_view.
2842 * Returns: the current custom character encoding name or %NULL if no
2843 * custom character encoding has been set.
2845 const gchar* webkit_web_view_get_custom_charset(WebKitWebView* webView)
2847 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2849 String customTextEncoding = getPage(webView).customTextEncodingName();
2850 if (customTextEncoding.isEmpty())
2853 webView->priv->customTextEncoding = customTextEncoding.utf8();
2854 return webView->priv->customTextEncoding.data();
2858 * webkit_web_view_set_custom_charset:
2859 * @web_view: a #WebKitWebView
2860 * @charset: (allow-none): a character encoding name or %NULL
2862 * Sets the current custom character encoding override of @web_view. The custom
2863 * character encoding will override any text encoding detected via HTTP headers or
2864 * META tags. Calling this method will stop any current load operation and reload the
2865 * current page. Setting the custom character encoding to %NULL removes the character
2866 * encoding override.
2868 void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* charset)
2870 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2872 getPage(webView).setCustomTextEncodingName(String::fromUTF8(charset));
2876 * webkit_web_view_get_estimated_load_progress:
2877 * @web_view: a #WebKitWebView
2879 * Gets the value of the #WebKitWebView:estimated-load-progress property.
2880 * You can monitor the estimated progress of a load operation by
2881 * connecting to the notify::estimated-load-progress signal of @web_view.
2883 * Returns: an estimate of the of the percent complete for a document
2884 * load as a range from 0.0 to 1.0.
2886 gdouble webkit_web_view_get_estimated_load_progress(WebKitWebView* webView)
2888 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2889 return getPage(webView).pageLoadState().estimatedProgress();
2893 * webkit_web_view_get_back_forward_list:
2894 * @web_view: a #WebKitWebView
2896 * Obtains the #WebKitBackForwardList associated with the given #WebKitWebView. The
2897 * #WebKitBackForwardList is owned by the #WebKitWebView.
2899 * Returns: (transfer none): the #WebKitBackForwardList
2901 WebKitBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView)
2903 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2905 return webView->priv->backForwardList.get();
2909 * webkit_web_view_go_to_back_forward_list_item:
2910 * @web_view: a #WebKitWebView
2911 * @list_item: a #WebKitBackForwardListItem
2913 * Loads the specific history item @list_item.
2914 * You can monitor the load operation by connecting to
2915 * #WebKitWebView::load-changed signal.
2917 void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKitBackForwardListItem* listItem)
2919 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2920 g_return_if_fail(WEBKIT_IS_BACK_FORWARD_LIST_ITEM(listItem));
2922 getPage(webView).goToBackForwardItem(webkitBackForwardListItemGetItem(listItem));
2926 * webkit_web_view_set_settings:
2927 * @web_view: a #WebKitWebView
2928 * @settings: a #WebKitSettings
2930 * Sets the #WebKitSettings to be applied to @web_view. The
2931 * existing #WebKitSettings of @web_view will be replaced by
2932 * @settings. New settings are applied immediately on @web_view.
2933 * The same #WebKitSettings object can be shared
2934 * by multiple #WebKitWebView<!-- -->s.
2936 void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings)
2938 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
2939 g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
2941 if (webView->priv->settings == settings)
2944 // The "settings" property is set on construction, and in that
2945 // case webkit_web_view_set_settings() will be called *before*
2946 // any settings have been assigned. In that case there are no
2947 // signal handlers to disconnect.
2948 if (webView->priv->settings)
2949 webkitWebViewDisconnectSettingsSignalHandlers(webView);
2951 webView->priv->settings = settings;
2952 webkitWebViewUpdateSettings(webView);
2953 g_object_notify(G_OBJECT(webView), "settings");
2957 * webkit_web_view_get_settings:
2958 * @web_view: a #WebKitWebView
2960 * Gets the #WebKitSettings currently applied to @web_view.
2961 * If no other #WebKitSettings have been explicitly applied to
2962 * @web_view with webkit_web_view_set_settings(), the default
2963 * #WebKitSettings will be returned. This method always returns
2964 * a valid #WebKitSettings object.
2965 * To modify any of the @web_view settings, you can either create
2966 * a new #WebKitSettings object with webkit_settings_new(), setting
2967 * the desired preferences, and then replace the existing @web_view
2968 * settings with webkit_web_view_set_settings() or get the existing
2969 * @web_view settings and update it directly. #WebKitSettings objects
2970 * can be shared by multiple #WebKitWebView<!-- -->s, so modifying
2971 * the settings of a #WebKitWebView would affect other
2972 * #WebKitWebView<!-- -->s using the same #WebKitSettings.
2974 * Returns: (transfer none): the #WebKitSettings attached to @web_view
2976 WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView)
2978 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
2979 return webView->priv->settings.get();
2983 * webkit_web_view_get_window_properties:
2984 * @web_view: a #WebKitWebView
2986 * Get the #WebKitWindowProperties object containing the properties
2987 * that the window containing @web_view should have.
2989 * Returns: (transfer none): the #WebKitWindowProperties of @web_view
2991 WebKitWindowProperties* webkit_web_view_get_window_properties(WebKitWebView* webView)
2993 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
2995 return webView->priv->windowProperties.get();
2999 * webkit_web_view_set_zoom_level:
3000 * @web_view: a #WebKitWebView
3001 * @zoom_level: the zoom level
3003 * Set the zoom level of @web_view, i.e. the factor by which the
3004 * view contents are scaled with respect to their original size.
3006 void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel)
3008 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3010 if (webkit_web_view_get_zoom_level(webView) == zoomLevel)
3013 auto& page = getPage(webView);
3014 if (webkit_settings_get_zoom_text_only(webView->priv->settings.get()))
3015 page.setTextZoomFactor(zoomLevel);
3017 page.setPageZoomFactor(zoomLevel);
3018 g_object_notify(G_OBJECT(webView), "zoom-level");
3022 * webkit_web_view_get_zoom_level:
3023 * @web_view: a #WebKitWebView
3025 * Get the zoom level of @web_view, i.e. the factor by which the
3026 * view contents are scaled with respect to their original size.
3028 * Returns: the current zoom level of @web_view
3030 gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView)
3032 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1);
3034 auto& page = getPage(webView);
3035 gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get());
3036 return zoomTextOnly ? page.textZoomFactor() : page.pageZoomFactor();
3040 * webkit_web_view_can_execute_editing_command:
3041 * @web_view: a #WebKitWebView
3042 * @command: the command to check
3043 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3044 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
3045 * @user_data: (closure): the data to pass to callback function
3047 * Asynchronously check if it is possible to execute the given editing command.
3049 * When the operation is finished, @callback will be called. You can then call
3050 * webkit_web_view_can_execute_editing_command_finish() to get the result of the operation.
3052 void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const char* command, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3054 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3055 g_return_if_fail(command);
3057 GTask* task = g_task_new(webView, cancellable, callback, userData);
3058 getPage(webView).validateCommand(String::fromUTF8(command), [task](const String&, bool isEnabled, int32_t, WebKit::CallbackBase::Error) {
3059 g_task_return_boolean(adoptGRef(task).get(), isEnabled);
3064 * webkit_web_view_can_execute_editing_command_finish:
3065 * @web_view: a #WebKitWebView
3066 * @result: a #GAsyncResult
3067 * @error: return location for error or %NULL to ignore
3069 * Finish an asynchronous operation started with webkit_web_view_can_execute_editing_command().
3071 * Returns: %TRUE if the editing command can be executed or %FALSE otherwise
3073 gboolean webkit_web_view_can_execute_editing_command_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3075 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3076 g_return_val_if_fail(g_task_is_valid(result, webView), FALSE);
3078 return g_task_propagate_boolean(G_TASK(result), error);
3082 * webkit_web_view_execute_editing_command:
3083 * @web_view: a #WebKitWebView
3084 * @command: the command to execute
3086 * Request to execute the given @command for @web_view. You can use
3087 * webkit_web_view_can_execute_editing_command() to check whether
3088 * it's possible to execute the command.
3090 void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* command)
3092 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3093 g_return_if_fail(command);
3095 getPage(webView).executeEditCommand(String::fromUTF8(command));
3099 * webkit_web_view_execute_editing_command_with_argument:
3100 * @web_view: a #WebKitWebView
3101 * @command: the command to execute
3102 * @argument: the command argument
3104 * Request to execute the given @command with @argument for @web_view. You can use
3105 * webkit_web_view_can_execute_editing_command() to check whether
3106 * it's possible to execute the command.
3110 void webkit_web_view_execute_editing_command_with_argument(WebKitWebView* webView, const char* command, const char* argument)
3112 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3113 g_return_if_fail(command);
3114 g_return_if_fail(argument);
3116 getPage(webView).executeEditCommand(String::fromUTF8(command), String::fromUTF8(argument));
3120 * webkit_web_view_get_find_controller:
3121 * @web_view: the #WebKitWebView
3123 * Gets the #WebKitFindController that will allow the caller to query
3124 * the #WebKitWebView for the text to look for.
3126 * Returns: (transfer none): the #WebKitFindController associated to
3127 * this particular #WebKitWebView.
3129 WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView)
3131 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3133 if (!webView->priv->findController)
3134 webView->priv->findController = adoptGRef(WEBKIT_FIND_CONTROLLER(g_object_new(WEBKIT_TYPE_FIND_CONTROLLER, "web-view", webView, NULL)));
3136 return webView->priv->findController.get();
3140 * webkit_web_view_get_javascript_global_context:
3141 * @web_view: a #WebKitWebView
3143 * Get the global JavaScript context used by @web_view to deserialize the
3144 * result values of scripts executed with webkit_web_view_run_javascript().
3146 * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
3147 * the result values of scripts.
3149 JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
3151 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
3153 if (!webView->priv->javascriptGlobalContext)
3154 webView->priv->javascriptGlobalContext = adopt(JSGlobalContextCreate(nullptr));
3155 return webView->priv->javascriptGlobalContext.get();
3158 static void webkitWebViewRunJavaScriptCallback(API::SerializedScriptValue* wkSerializedScriptValue, const WebCore::ExceptionDetails& exceptionDetails, GTask* task)
3160 if (g_task_return_error_if_cancelled(task))
3163 if (!wkSerializedScriptValue) {
3164 StringBuilder builder;
3165 if (!exceptionDetails.sourceURL.isEmpty()) {
3166 builder.append(exceptionDetails.sourceURL);
3167 if (exceptionDetails.lineNumber > 0) {
3168 builder.append(':');
3169 builder.appendNumber(exceptionDetails.lineNumber);
3171 if (exceptionDetails.columnNumber > 0) {
3172 builder.append(':');
3173 builder.appendNumber(exceptionDetails.columnNumber);
3175 builder.appendLiteral(": ");
3177 builder.append(exceptionDetails.message);
3178 g_task_return_new_error(task, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED,
3179 "%s", builder.toString().utf8().data());
3183 auto* jsContext = webkit_web_view_get_javascript_global_context(WEBKIT_WEB_VIEW(g_task_get_source_object(task)));
3184 g_task_return_pointer(task, webkitJavascriptResultCreate(jsContext,
3185 *wkSerializedScriptValue->internalRepresentation()),
3186 reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
3190 * webkit_web_view_run_javascript:
3191 * @web_view: a #WebKitWebView
3192 * @script: the script to run
3193 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3194 * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
3195 * @user_data: (closure): the data to pass to callback function
3197 * Asynchronously run @script in the context of the current page in @web_view. If
3198 * WebKitSettings:enable-javascript is FALSE, this method will do nothing.
3200 * When the operation is finished, @callback will be called. You can then call
3201 * webkit_web_view_run_javascript_finish() to get the result of the operation.
3203 void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
3205 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3206 g_return_if_fail(script);
3208 GTask* task = g_task_new(webView, cancellable, callback, userData);
3209 getPage(webView).runJavaScriptInMainFrame(String::fromUTF8(script), true, [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails& exceptionDetails, WebKit::CallbackBase::Error) {
3210 webkitWebViewRunJavaScriptCallback(serializedScriptValue, exceptionDetails, adoptGRef(task).get());
3215 * webkit_web_view_run_javascript_finish:
3216 * @web_view: a #WebKitWebView
3217 * @result: a #GAsyncResult
3218 * @error: return location for error or %NULL to ignore
3220 * Finish an asynchronous operation started with webkit_web_view_run_javascript().
3222 * This is an example of using webkit_web_view_run_javascript() with a script returning
3225 * <informalexample><programlisting>
3227 * web_view_javascript_finished (GObject *object,
3228 * GAsyncResult *result,
3229 * gpointer user_data)
3231 * WebKitJavascriptResult *js_result;
3233 * JSGlobalContextRef context;
3234 * GError *error = NULL;
3236 * js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
3238 * g_warning ("Error running javascript: %s", error->message);
3239 * g_error_free (error);
3243 * context = webkit_javascript_result_get_global_context (js_result);
3244 * value = webkit_javascript_result_get_value (js_result);
3245 * if (JSValueIsString (context, value)) {
3246 * JSStringRef js_str_value;
3250 * js_str_value = JSValueToStringCopy (context, value, NULL);
3251 * str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
3252 * str_value = (gchar *)g_malloc (str_length);
3253 * JSStringGetUTF8CString (js_str_value, str_value, str_length);
3254 * JSStringRelease (js_str_value);
3255 * g_print ("Script result: %s\n", str_value);
3256 * g_free (str_value);
3258 * g_warning ("Error running javascript: unexpected return value");
3260 * webkit_javascript_result_unref (js_result);
3264 * web_view_get_link_url (WebKitWebView *web_view,
3265 * const gchar *link_id)
3269 * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id);
3270 * webkit_web_view_run_javascript (web_view, script, NULL, web_view_javascript_finished, NULL);
3273 * </programlisting></informalexample>
3275 * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
3276 * or %NULL in case of error
3278 WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
3280 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3281 g_return_val_if_fail(g_task_is_valid(result, webView), 0);
3283 return static_cast<WebKitJavascriptResult*>(g_task_propagate_pointer(G_TASK(result), error));
3286 static void resourcesStreamReadCallback(GObject* object, GAsyncResult* result, gpointer userData)
3288 GRefPtr<GTask> task = adoptGRef(G_TASK(userData));
3291 g_output_stream_splice_finish(G_OUTPUT_STREAM(object), result, &error);
3293 g_task_return_error(task.get(), error);
3297 WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get()));
3298 gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object));
3299 getPage(webView).runJavaScriptInMainFrame(String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), true,
3300 [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails& exceptionDetails, WebKit::CallbackBase::Error) {
3301 webkitWebViewRunJavaScriptCallback(serializedScriptValue, exceptionDetails, task.get());
3306 * webkit_web_view_run_javascript_from_gresource:
3307 * @web_view: a #WebKitWebView
3308 * @resource: the location of the resource to load
3309 * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
3310 * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
3311 * @user_data: (closure): the data to pass to callback function
3313 * Asynchronously run the script from @resource in the context of the
3314 * current page in @web_view.
3316 * When the operation is finished, @callback will be called. You can
3317 * then call webkit_web_view_run_javascript_from_gresource_finish() to get the result
3320 void webkit_web_view_run_javascript_from_gresource(WebKitWebView* webView, const gchar* resource, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)