/* * Copyright (C) 2011 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "config.h" #include "WebKitWebContext.h" #include "APICustomProtocolManagerClient.h" #include "APIDownloadClient.h" #include "APIPageConfiguration.h" #include "APIProcessPoolConfiguration.h" #include "APIString.h" #include "TextChecker.h" #include "TextCheckerState.h" #include "WebCertificateInfo.h" #include "WebGeolocationManagerProxy.h" #include "WebKitCustomProtocolManagerClient.h" #include "WebKitDownloadClient.h" #include "WebKitDownloadPrivate.h" #include "WebKitFaviconDatabasePrivate.h" #include "WebKitGeolocationProvider.h" #include "WebKitInjectedBundleClient.h" #include "WebKitNetworkProxySettingsPrivate.h" #include "WebKitNotificationProvider.h" #include "WebKitPluginPrivate.h" #include "WebKitPrivate.h" #include "WebKitSecurityManagerPrivate.h" #include "WebKitSecurityOriginPrivate.h" #include "WebKitSettingsPrivate.h" #include "WebKitURISchemeRequestPrivate.h" #include "WebKitUserContentManagerPrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" #include "WebKitWebsiteDataManagerPrivate.h" #include "WebNotificationManagerProxy.h" #include "WebsiteDataType.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace WebKit; /** * SECTION: WebKitWebContext * @Short_description: Manages aspects common to all #WebKitWebViews * @Title: WebKitWebContext * * The #WebKitWebContext manages all aspects common to all * #WebKitWebViews. * * You can define the #WebKitCacheModel and #WebKitProcessModel with * webkit_web_context_set_cache_model() and * webkit_web_context_set_process_model(), depending on the needs of * your application. You can access the #WebKitSecurityManager to specify * the behaviour of your application regarding security using * webkit_web_context_get_security_manager(). * * It is also possible to change your preferred language or enable * spell checking, using webkit_web_context_set_preferred_languages(), * webkit_web_context_set_spell_checking_languages() and * webkit_web_context_set_spell_checking_enabled(). * * You can use webkit_web_context_register_uri_scheme() to register * custom URI schemes, and manage several other settings. * * TLS certificate validation failure is now treated as a transport * error by default. To handle TLS failures differently, you can * connect to #WebKitWebView::load-failed-with-tls-errors. * Alternatively, you can use webkit_web_context_set_tls_errors_policy() * to set the policy %WEBKIT_TLS_ERRORS_POLICY_IGNORE; however, this is * not appropriate for Internet applications. * */ enum { PROP_0, PROP_LOCAL_STORAGE_DIRECTORY, PROP_WEBSITE_DATA_MANAGER }; enum { DOWNLOAD_STARTED, INITIALIZE_WEB_EXTENSIONS, INITIALIZE_NOTIFICATION_PERMISSIONS, LAST_SIGNAL }; class WebKitURISchemeHandler: public RefCounted { public: WebKitURISchemeHandler(WebKitURISchemeRequestCallback callback, void* userData, GDestroyNotify destroyNotify) : m_callback(callback) , m_userData(userData) , m_destroyNotify(destroyNotify) { } ~WebKitURISchemeHandler() { if (m_destroyNotify) m_destroyNotify(m_userData); } bool hasCallback() { return m_callback; } void performCallback(WebKitURISchemeRequest* request) { ASSERT(m_callback); m_callback(request, m_userData); } private: WebKitURISchemeRequestCallback m_callback { nullptr }; void* m_userData { nullptr }; GDestroyNotify m_destroyNotify { nullptr }; }; typedef HashMap > URISchemeHandlerMap; typedef HashMap > URISchemeRequestMap; struct _WebKitWebContextPrivate { RefPtr processPool; bool clientsDetached; GRefPtr faviconDatabase; GRefPtr securityManager; URISchemeHandlerMap uriSchemeHandlers; URISchemeRequestMap uriSchemeRequests; #if ENABLE(GEOLOCATION) RefPtr geolocationProvider; #endif #if ENABLE(NOTIFICATIONS) RefPtr notificationProvider; #endif GRefPtr websiteDataManager; CString faviconDatabaseDirectory; WebKitTLSErrorsPolicy tlsErrorsPolicy; WebKitProcessModel processModel; unsigned processCountLimit; HashMap webViews; unsigned ephemeralPageCount; CString webExtensionsDirectory; GRefPtr webExtensionsInitializationUserData; CString localStorageDirectory; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitWebContext, webkit_web_context, G_TYPE_OBJECT) static const char* injectedBundleDirectory() { #if ENABLE(DEVELOPER_MODE) const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH"); if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR)) return bundleDirectory; #endif static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING G_DIR_SEPARATOR_S "injected-bundle" G_DIR_SEPARATOR_S; return injectedBundlePath; } static void webkitWebContextGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec) { WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); switch (propID) { case PROP_LOCAL_STORAGE_DIRECTORY: g_value_set_string(value, context->priv->localStorageDirectory.data()); break; case PROP_WEBSITE_DATA_MANAGER: g_value_set_object(value, webkit_web_context_get_website_data_manager(context)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); } } static void webkitWebContextSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec) { WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); switch (propID) { case PROP_LOCAL_STORAGE_DIRECTORY: context->priv->localStorageDirectory = g_value_get_string(value); break; case PROP_WEBSITE_DATA_MANAGER: { gpointer manager = g_value_get_object(value); context->priv->websiteDataManager = manager ? WEBKIT_WEBSITE_DATA_MANAGER(manager) : nullptr; break; } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); } } static inline WebsiteDataStore::Configuration websiteDataStoreConfigurationForWebProcessPoolConfiguration(const API::ProcessPoolConfiguration& processPoolconfigurarion) { WebsiteDataStore::Configuration configuration; configuration.applicationCacheDirectory = processPoolconfigurarion.applicationCacheDirectory(); configuration.networkCacheDirectory = processPoolconfigurarion.diskCacheDirectory(); configuration.webSQLDatabaseDirectory = processPoolconfigurarion.webSQLDatabaseDirectory(); configuration.localStorageDirectory = processPoolconfigurarion.localStorageDirectory(); configuration.mediaKeysStorageDirectory = processPoolconfigurarion.mediaKeysStorageDirectory(); return configuration; } static void webkitWebContextConstructed(GObject* object) { G_OBJECT_CLASS(webkit_web_context_parent_class)->constructed(object); GUniquePtr bundleFilename(g_build_filename(injectedBundleDirectory(), "libwebkit2gtkinjectedbundle.so", nullptr)); API::ProcessPoolConfiguration configuration; configuration.setInjectedBundlePath(WebCore::stringFromFileSystemRepresentation(bundleFilename.get())); configuration.setMaximumProcessCount(1); configuration.setDiskCacheSpeculativeValidationEnabled(true); WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(object); WebKitWebContextPrivate* priv = webContext->priv; if (priv->websiteDataManager && !webkit_website_data_manager_is_ephemeral(priv->websiteDataManager.get())) { configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_local_storage_directory(priv->websiteDataManager.get()))); configuration.setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_disk_cache_directory(priv->websiteDataManager.get())), networkCacheSubdirectory)); configuration.setApplicationCacheDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_offline_application_cache_directory(priv->websiteDataManager.get()))); configuration.setIndexedDBDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_indexeddb_directory(priv->websiteDataManager.get()))); configuration.setWebSQLDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_websql_directory(priv->websiteDataManager.get()))); } else if (!priv->localStorageDirectory.isNull()) configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(priv->localStorageDirectory.data())); priv->processPool = WebProcessPool::create(configuration); if (!priv->websiteDataManager) priv->websiteDataManager = adoptGRef(webkitWebsiteDataManagerCreate(websiteDataStoreConfigurationForWebProcessPoolConfiguration(configuration))); webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), *priv->processPool); priv->tlsErrorsPolicy = WEBKIT_TLS_ERRORS_POLICY_FAIL; priv->processPool->setIgnoreTLSErrors(false); #if ENABLE(MEMORY_SAMPLER) if (getenv("WEBKIT_SAMPLE_MEMORY")) priv->processPool->startMemorySampler(0); #endif attachInjectedBundleClientToContext(webContext); attachDownloadClientToContext(webContext); attachCustomProtocolManagerClientToContext(webContext); #if ENABLE(GEOLOCATION) priv->geolocationProvider = WebKitGeolocationProvider::create(priv->processPool->supplement()); #endif #if ENABLE(NOTIFICATIONS) priv->notificationProvider = WebKitNotificationProvider::create(priv->processPool->supplement(), webContext); #endif } static void webkitWebContextDispose(GObject* object) { WebKitWebContextPrivate* priv = WEBKIT_WEB_CONTEXT(object)->priv; if (!priv->clientsDetached) { priv->clientsDetached = true; priv->processPool->initializeInjectedBundleClient(nullptr); priv->processPool->setDownloadClient(nullptr); priv->processPool->setCustomProtocolManagerClient(nullptr); } if (priv->websiteDataManager) { webkitWebsiteDataManagerRemoveProcessPool(priv->websiteDataManager.get(), *priv->processPool); priv->websiteDataManager = nullptr; } G_OBJECT_CLASS(webkit_web_context_parent_class)->dispose(object); } static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass) { GObjectClass* gObjectClass = G_OBJECT_CLASS(webContextClass); bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); gObjectClass->get_property = webkitWebContextGetProperty; gObjectClass->set_property = webkitWebContextSetProperty; gObjectClass->constructed = webkitWebContextConstructed; gObjectClass->dispose = webkitWebContextDispose; /** * WebKitWebContext:local-storage-directory: * * The directory where local storage data will be saved. * * Since: 2.8 * * Deprecated: 2.10. Use #WebKitWebsiteDataManager:local-storage-directory instead. */ g_object_class_install_property( gObjectClass, PROP_LOCAL_STORAGE_DIRECTORY, g_param_spec_string( "local-storage-directory", _("Local Storage Directory"), _("The directory where local storage data will be saved"), nullptr, static_cast(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); /** * WebKitWebContext:website-data-manager: * * The #WebKitWebsiteDataManager associated with this context. * * Since: 2.10 */ g_object_class_install_property( gObjectClass, PROP_WEBSITE_DATA_MANAGER, g_param_spec_object( "website-data-manager", _("Website Data Manager"), _("The WebKitWebsiteDataManager associated with this context"), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, static_cast(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); /** * WebKitWebContext::download-started: * @context: the #WebKitWebContext * @download: the #WebKitDownload associated with this event * * This signal is emitted when a new download request is made. */ signals[DOWNLOAD_STARTED] = g_signal_new("download-started", G_TYPE_FROM_CLASS(gObjectClass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(WebKitWebContextClass, download_started), nullptr, nullptr, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, WEBKIT_TYPE_DOWNLOAD); /** * WebKitWebContext::initialize-web-extensions: * @context: the #WebKitWebContext * * This signal is emitted when a new web process is about to be * launched. It signals the most appropriate moment to use * webkit_web_context_set_web_extensions_initialization_user_data() * and webkit_web_context_set_web_extensions_directory(). * * Since: 2.4 */ signals[INITIALIZE_WEB_EXTENSIONS] = g_signal_new("initialize-web-extensions", G_TYPE_FROM_CLASS(gObjectClass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(WebKitWebContextClass, initialize_web_extensions), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * WebKitWebContext::initialize-notification-permissions: * @context: the #WebKitWebContext * * This signal is emitted when a #WebKitWebContext needs to set * initial notification permissions for a web process. It is emitted * when a new web process is about to be launched, and signals the * most appropriate moment to use * webkit_web_context_initialize_notification_permissions(). If no * notification permissions have changed since the last time this * signal was emitted, then there is no need to call * webkit_web_context_initialize_notification_permissions() again. * * Since: 2.16 */ signals[INITIALIZE_NOTIFICATION_PERMISSIONS] = g_signal_new("initialize-notification-permissions", G_TYPE_FROM_CLASS(gObjectClass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(WebKitWebContextClass, initialize_notification_permissions), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static gpointer createDefaultWebContext(gpointer) { static GRefPtr webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr))); return webContext.get(); } /** * webkit_web_context_get_default: * * Gets the default web context * * Returns: (transfer none): a #WebKitWebContext */ WebKitWebContext* webkit_web_context_get_default(void) { static GOnce onceInit = G_ONCE_INIT; return WEBKIT_WEB_CONTEXT(g_once(&onceInit, createDefaultWebContext, 0)); } /** * webkit_web_context_new: * * Create a new #WebKitWebContext * * Returns: (transfer full): a newly created #WebKitWebContext * * Since: 2.8 */ WebKitWebContext* webkit_web_context_new(void) { return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr)); } /** * webkit_web_context_new_ephemeral: * * Create a new ephemeral #WebKitWebContext. An ephemeral #WebKitWebContext is a context * created with an ephemeral #WebKitWebsiteDataManager. This is just a convenient method * to create ephemeral contexts without having to create your own #WebKitWebsiteDataManager. * All #WebKitWebViews associated with this context will also be ephemeral. Websites will * not store any data in the client storage. * This is normally used to implement private instances. * * Returns: (transfer full): a new ephemeral #WebKitWebContext. * * Since: 2.16 */ WebKitWebContext* webkit_web_context_new_ephemeral() { GRefPtr manager = adoptGRef(webkit_website_data_manager_new_ephemeral()); return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager.get(), nullptr)); } /** * webkit_web_context_new_with_website_data_manager: * @manager: a #WebKitWebsiteDataManager * * Create a new #WebKitWebContext with a #WebKitWebsiteDataManager. * * Returns: (transfer full): a newly created #WebKitWebContext * * Since: 2.10 */ WebKitWebContext* webkit_web_context_new_with_website_data_manager(WebKitWebsiteDataManager* manager) { g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, nullptr)); } /** * webkit_web_context_get_website_data_manager: * @context: the #WebKitWebContext * * Get the #WebKitWebsiteDataManager of @context. * * Returns: (transfer none): a #WebKitWebsiteDataManager * * Since: 2.10 */ WebKitWebsiteDataManager* webkit_web_context_get_website_data_manager(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); return context->priv->websiteDataManager.get(); } /** * webkit_web_context_is_ephemeral: * @context: the #WebKitWebContext * * Get whether a #WebKitWebContext is ephemeral. * * Returns: %TRUE if @context is ephemeral or %FALSE otherwise. * * Since: 2.16 */ gboolean webkit_web_context_is_ephemeral(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); return webkit_website_data_manager_is_ephemeral(context->priv->websiteDataManager.get()); } /** * webkit_web_context_set_cache_model: * @context: the #WebKitWebContext * @cache_model: a #WebKitCacheModel * * Specifies a usage model for WebViews, which WebKit will use to * determine its caching behavior. All web views follow the cache * model. This cache model determines the RAM and disk space to use * for caching previously viewed content . * * Research indicates that users tend to browse within clusters of * documents that hold resources in common, and to revisit previously * visited documents. WebKit and the frameworks below it include * built-in caches that take advantage of these patterns, * substantially improving document load speed in browsing * situations. The WebKit cache model controls the behaviors of all of * these caches, including various WebCore caches. * * Browsers can improve document load speed substantially by * specifying %WEBKIT_CACHE_MODEL_WEB_BROWSER. Applications without a * browsing interface can reduce memory usage substantially by * specifying %WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER. The default value is * %WEBKIT_CACHE_MODEL_WEB_BROWSER. */ void webkit_web_context_set_cache_model(WebKitWebContext* context, WebKitCacheModel model) { CacheModel cacheModel; g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); switch (model) { case WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER: cacheModel = CacheModelDocumentViewer; break; case WEBKIT_CACHE_MODEL_WEB_BROWSER: cacheModel = CacheModelPrimaryWebBrowser; break; case WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER: cacheModel = CacheModelDocumentBrowser; break; default: g_assert_not_reached(); } if (cacheModel != context->priv->processPool->cacheModel()) context->priv->processPool->setCacheModel(cacheModel); } /** * webkit_web_context_get_cache_model: * @context: the #WebKitWebContext * * Returns the current cache model. For more information about this * value check the documentation of the function * webkit_web_context_set_cache_model(). * * Returns: the current #WebKitCacheModel */ WebKitCacheModel webkit_web_context_get_cache_model(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_CACHE_MODEL_WEB_BROWSER); switch (context->priv->processPool->cacheModel()) { case CacheModelDocumentViewer: return WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER; case CacheModelPrimaryWebBrowser: return WEBKIT_CACHE_MODEL_WEB_BROWSER; case CacheModelDocumentBrowser: return WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER; default: g_assert_not_reached(); } return WEBKIT_CACHE_MODEL_WEB_BROWSER; } /** * webkit_web_context_clear_cache: * @context: a #WebKitWebContext * * Clears all resources currently cached. * See also webkit_web_context_set_cache_model(). */ void webkit_web_context_clear_cache(WebKitWebContext* context) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); OptionSet websiteDataTypes; websiteDataTypes |= WebsiteDataType::MemoryCache; websiteDataTypes |= WebsiteDataType::DiskCache; auto& websiteDataStore = webkitWebsiteDataManagerGetDataStore(context->priv->websiteDataManager.get()).websiteDataStore(); websiteDataStore.removeData(websiteDataTypes, std::chrono::system_clock::time_point::min(), [] { }); } /** * webkit_web_context_set_network_proxy_settings: * @context: a #WebKitWebContext * @proxy_mode: a #WebKitNetworkProxyMode * @proxy_settings: (allow-none): a #WebKitNetworkProxySettings, or %NULL * * Set the network proxy settings to be used by connections started in @context. * By default %WEBKIT_NETWORK_PROXY_MODE_DEFAULT is used, which means that the * system settings will be used (g_proxy_resolver_get_default()). * If you want to override the system default settings, you can either use * %WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to make sure no proxies are used at all, * or %WEBKIT_NETWORK_PROXY_MODE_CUSTOM to provide your own proxy settings. * When @proxy_mode is %WEBKIT_NETWORK_PROXY_MODE_CUSTOM @proxy_settings must be * a valid #WebKitNetworkProxySettings; otherwise, @proxy_settings must be %NULL. * * Since: 2.16 */ void webkit_web_context_set_network_proxy_settings(WebKitWebContext* context, WebKitNetworkProxyMode proxyMode, WebKitNetworkProxySettings* proxySettings) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail((proxyMode != WEBKIT_NETWORK_PROXY_MODE_CUSTOM && !proxySettings) || (proxyMode == WEBKIT_NETWORK_PROXY_MODE_CUSTOM && proxySettings)); WebKitWebContextPrivate* priv = context->priv; switch (proxyMode) { case WEBKIT_NETWORK_PROXY_MODE_DEFAULT: priv->processPool->setNetworkProxySettings({ }); break; case WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: priv->processPool->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(WebCore::SoupNetworkProxySettings::Mode::NoProxy)); break; case WEBKIT_NETWORK_PROXY_MODE_CUSTOM: const auto& settings = webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings); if (settings.isEmpty()) { g_warning("Invalid attempt to set custom network proxy settings with an empty WebKitNetworkProxySettings. Use " "WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to not use any proxy or WEBKIT_NETWORK_PROXY_MODE_DEFAULT to use the default system settings"); } else priv->processPool->setNetworkProxySettings(settings); break; } } typedef HashMap > DownloadsMap; static DownloadsMap& downloadsMap() { static NeverDestroyed downloads; return downloads; } /** * webkit_web_context_download_uri: * @context: a #WebKitWebContext * @uri: the URI to download * * Requests downloading of the specified URI string. The download operation * will not be associated to any #WebKitWebView, if you are interested in * starting a download from a particular #WebKitWebView use * webkit_web_view_download_uri() instead. * * Returns: (transfer full): a new #WebKitDownload representing the * the download operation. */ WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const gchar* uri) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); g_return_val_if_fail(uri, nullptr); GRefPtr download = webkitWebContextStartDownload(context, uri, nullptr); return download.leakRef(); } /** * webkit_web_context_get_cookie_manager: * @context: a #WebKitWebContext * * Get the #WebKitCookieManager of the @context's #WebKitWebsiteDataManager. * * Returns: (transfer none): the #WebKitCookieManager of @context. */ WebKitCookieManager* webkit_web_context_get_cookie_manager(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); return webkit_website_data_manager_get_cookie_manager(context->priv->websiteDataManager.get()); } static void ensureFaviconDatabase(WebKitWebContext* context) { WebKitWebContextPrivate* priv = context->priv; if (priv->faviconDatabase) return; priv->faviconDatabase = adoptGRef(webkitFaviconDatabaseCreate(priv->processPool->iconDatabase())); } static void webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) { if (webkit_web_context_is_ephemeral(context)) return; if (!webkit_web_view_is_ephemeral(webView)) return; if (!context->priv->ephemeralPageCount) context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); context->priv->ephemeralPageCount++; } static void webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) { if (webkit_web_context_is_ephemeral(context)) return; if (!webkit_web_view_is_ephemeral(webView)) return; ASSERT(context->priv->ephemeralPageCount); context->priv->ephemeralPageCount--; if (!context->priv->ephemeralPageCount) context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(false); } /** * webkit_web_context_set_favicon_database_directory: * @context: a #WebKitWebContext * @path: (allow-none): an absolute path to the icon database * directory or %NULL to use the defaults * * Set the directory path to be used to store the favicons database * for @context on disk. Passing %NULL as @path means using the * default directory for the platform (see g_get_user_data_dir()). * * Calling this method also means enabling the favicons database for * its use from the applications, so that's why it's expected to be * called only once. Further calls for the same instance of * #WebKitWebContext won't cause any effect. */ void webkit_web_context_set_favicon_database_directory(WebKitWebContext* context, const gchar* path) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); WebKitWebContextPrivate* priv = context->priv; WebIconDatabase* iconDatabase = priv->processPool->iconDatabase(); if (iconDatabase->isOpen()) return; ensureFaviconDatabase(context); // Use default if 0 is passed as parameter. String directoryPath = WebCore::stringFromFileSystemRepresentation(path); priv->faviconDatabaseDirectory = directoryPath.isEmpty() ? priv->processPool->iconDatabasePath().utf8() : directoryPath.utf8(); // Build the full path to the icon database file on disk. GUniquePtr faviconDatabasePath(g_build_filename(priv->faviconDatabaseDirectory.data(), WebCore::IconDatabase::defaultDatabaseFilename().utf8().data(), nullptr)); // Setting the path will cause the icon database to be opened. priv->processPool->setIconDatabasePath(WebCore::stringFromFileSystemRepresentation(faviconDatabasePath.get())); if (webkit_web_context_is_ephemeral(context)) priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); } /** * webkit_web_context_get_favicon_database_directory: * @context: a #WebKitWebContext * * Get the directory path being used to store the favicons database * for @context, or %NULL if * webkit_web_context_set_favicon_database_directory() hasn't been * called yet. * * This function will always return the same path after having called * webkit_web_context_set_favicon_database_directory() for the first * time. * * Returns: (transfer none): the path of the directory of the favicons * database associated with @context, or %NULL. */ const gchar* webkit_web_context_get_favicon_database_directory(WebKitWebContext *context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); WebKitWebContextPrivate* priv = context->priv; if (priv->faviconDatabaseDirectory.isNull()) return 0; return priv->faviconDatabaseDirectory.data(); } /** * webkit_web_context_get_favicon_database: * @context: a #WebKitWebContext * * Get the #WebKitFaviconDatabase associated with @context. * * To initialize the database you need to call * webkit_web_context_set_favicon_database_directory(). * * Returns: (transfer none): the #WebKitFaviconDatabase of @context. */ WebKitFaviconDatabase* webkit_web_context_get_favicon_database(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); ensureFaviconDatabase(context); return context->priv->faviconDatabase.get(); } /** * webkit_web_context_get_security_manager: * @context: a #WebKitWebContext * * Get the #WebKitSecurityManager of @context. * * Returns: (transfer none): the #WebKitSecurityManager of @context. */ WebKitSecurityManager* webkit_web_context_get_security_manager(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); WebKitWebContextPrivate* priv = context->priv; if (!priv->securityManager) priv->securityManager = adoptGRef(webkitSecurityManagerCreate(context)); return priv->securityManager.get(); } /** * webkit_web_context_set_additional_plugins_directory: * @context: a #WebKitWebContext * @directory: the directory to add * * Set an additional directory where WebKit will look for plugins. */ void webkit_web_context_set_additional_plugins_directory(WebKitWebContext* context, const char* directory) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); #if ENABLE(NETSCAPE_PLUGIN_API) context->priv->processPool->setAdditionalPluginsDirectory(WebCore::stringFromFileSystemRepresentation(directory)); #endif } static void destroyPluginList(GList* plugins) { g_list_free_full(plugins, g_object_unref); } static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer /* taskData */, GCancellable*) { GList* returnValue = 0; #if ENABLE(NETSCAPE_PLUGIN_API) Vector plugins = WEBKIT_WEB_CONTEXT(object)->priv->processPool->pluginInfoStore().plugins(); for (size_t i = 0; i < plugins.size(); ++i) returnValue = g_list_prepend(returnValue, webkitPluginCreate(plugins[i])); #endif g_task_return_pointer(task, returnValue, reinterpret_cast(destroyPluginList)); } /** * webkit_web_context_get_plugins: * @context: a #WebKitWebContext * @cancellable: (allow-none): a #GCancellable or %NULL to ignore * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied * @user_data: (closure): the data to pass to callback function * * Asynchronously get the list of installed plugins. * * When the operation is finished, @callback will be called. You can then call * webkit_web_context_get_plugins_finish() to get the result of the operation. */ void webkit_web_context_get_plugins(WebKitWebContext* context, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); GRefPtr task = adoptGRef(g_task_new(context, cancellable, callback, userData)); g_task_run_in_thread(task.get(), webkitWebContextGetPluginThread); } /** * webkit_web_context_get_plugins_finish: * @context: a #WebKitWebContext * @result: a #GAsyncResult * @error: return location for error or %NULL to ignore * * Finish an asynchronous operation started with webkit_web_context_get_plugins. * * Returns: (element-type WebKitPlugin) (transfer full): a #GList of #WebKitPlugin. You must free the #GList with * g_list_free() and unref the #WebKitPlugins with g_object_unref() when you're done with them. */ GList* webkit_web_context_get_plugins_finish(WebKitWebContext* context, GAsyncResult* result, GError** error) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); g_return_val_if_fail(g_task_is_valid(result, context), 0); return static_cast(g_task_propagate_pointer(G_TASK(result), error)); } /** * webkit_web_context_register_uri_scheme: * @context: a #WebKitWebContext * @scheme: the network scheme to register * @callback: (scope async): a #WebKitURISchemeRequestCallback * @user_data: data to pass to callback function * @user_data_destroy_func: destroy notify for @user_data * * Register @scheme in @context, so that when an URI request with @scheme is made in the * #WebKitWebContext, the #WebKitURISchemeRequestCallback registered will be called with a * #WebKitURISchemeRequest. * It is possible to handle URI scheme requests asynchronously, by calling g_object_ref() on the * #WebKitURISchemeRequest and calling webkit_uri_scheme_request_finish() later * when the data of the request is available or * webkit_uri_scheme_request_finish_error() in case of error. * * * static void * about_uri_scheme_request_cb (WebKitURISchemeRequest *request, * gpointer user_data) * { * GInputStream *stream; * gsize stream_length; * const gchar *path; * * path = webkit_uri_scheme_request_get_path (request); * if (!g_strcmp0 (path, "plugins")) { * /* Create a GInputStream with the contents of plugins about page, and set its length to stream_length */ * } else if (!g_strcmp0 (path, "memory")) { * /* Create a GInputStream with the contents of memory about page, and set its length to stream_length */ * } else if (!g_strcmp0 (path, "applications")) { * /* Create a GInputStream with the contents of applications about page, and set its length to stream_length */ * } else if (!g_strcmp0 (path, "example")) { * gchar *contents; * * contents = g_strdup_printf ("<html><body><p>Example about page</p></body></html>"); * stream_length = strlen (contents); * stream = g_memory_input_stream_new_from_data (contents, stream_length, g_free); * } else { * GError *error; * * error = g_error_new (ABOUT_HANDLER_ERROR, ABOUT_HANDLER_ERROR_INVALID, "Invalid about:%s page.", path); * webkit_uri_scheme_request_finish_error (request, error); * g_error_free (error); * return; * } * webkit_uri_scheme_request_finish (request, stream, stream_length, "text/html"); * g_object_unref (stream); * } * */ void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const char* scheme, WebKitURISchemeRequestCallback callback, gpointer userData, GDestroyNotify destroyNotify) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(scheme); g_return_if_fail(callback); RefPtr handler = adoptRef(new WebKitURISchemeHandler(callback, userData, destroyNotify)); auto addResult = context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), handler.get()); if (addResult.isNewEntry) context->priv->processPool->registerSchemeForCustomProtocol(String::fromUTF8(scheme)); } /** * webkit_web_context_get_spell_checking_enabled: * @context: a #WebKitWebContext * * Get whether spell checking feature is currently enabled. * * Returns: %TRUE If spell checking is enabled, or %FALSE otherwise. */ gboolean webkit_web_context_get_spell_checking_enabled(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); #if ENABLE(SPELLCHECK) return TextChecker::state().isContinuousSpellCheckingEnabled; #else return false; #endif } /** * webkit_web_context_set_spell_checking_enabled: * @context: a #WebKitWebContext * @enabled: Value to be set * * Enable or disable the spell checking feature. */ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gboolean enabled) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); #if ENABLE(SPELLCHECK) TextChecker::setContinuousSpellCheckingEnabled(enabled); #endif } /** * webkit_web_context_get_spell_checking_languages: * @context: a #WebKitWebContext * * Get the the list of spell checking languages associated with * @context, or %NULL if no languages have been previously set. * * See webkit_web_context_set_spell_checking_languages() for more * details on the format of the languages in the list. * * Returns: (array zero-terminated=1) (element-type utf8) (transfer none): A %NULL-terminated * array of languages if available, or %NULL otherwise. */ const gchar* const* webkit_web_context_get_spell_checking_languages(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); #if ENABLE(SPELLCHECK) Vector spellCheckingLanguages = TextChecker::loadedSpellCheckingLanguages(); if (spellCheckingLanguages.isEmpty()) return nullptr; static GRefPtr languagesToReturn; languagesToReturn = adoptGRef(g_ptr_array_new_with_free_func(g_free)); for (const auto& language : spellCheckingLanguages) g_ptr_array_add(languagesToReturn.get(), g_strdup(language.utf8().data())); g_ptr_array_add(languagesToReturn.get(), nullptr); return reinterpret_cast(languagesToReturn->pdata); #else return 0; #endif } /** * webkit_web_context_set_spell_checking_languages: * @context: a #WebKitWebContext * @languages: (array zero-terminated=1) (transfer none): a %NULL-terminated list of spell checking languages * * Set the list of spell checking languages to be used for spell * checking. * * The locale string typically is in the form lang_COUNTRY, where lang * is an ISO-639 language code, and COUNTRY is an ISO-3166 country code. * For instance, sv_FI for Swedish as written in Finland or pt_BR * for Portuguese as written in Brazil. * * You need to call this function with a valid list of languages at * least once in order to properly enable the spell checking feature * in WebKit. */ void webkit_web_context_set_spell_checking_languages(WebKitWebContext* context, const gchar* const* languages) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(languages); #if ENABLE(SPELLCHECK) Vector spellCheckingLanguages; for (size_t i = 0; languages[i]; ++i) spellCheckingLanguages.append(String::fromUTF8(languages[i])); TextChecker::setSpellCheckingLanguages(spellCheckingLanguages); #endif } /** * webkit_web_context_set_preferred_languages: * @context: a #WebKitWebContext * @languages: (allow-none) (array zero-terminated=1) (element-type utf8) (transfer none): a %NULL-terminated list of language identifiers * * Set the list of preferred languages, sorted from most desirable * to least desirable. The list will be used to build the "Accept-Language" * header that will be included in the network requests started by * the #WebKitWebContext. */ void webkit_web_context_set_preferred_languages(WebKitWebContext* context, const gchar* const* languageList) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); if (!languageList || !g_strv_length(const_cast(languageList))) return; Vector languages; for (size_t i = 0; languageList[i]; ++i) { // Do not propagate the C locale to WebCore. if (!g_ascii_strcasecmp(languageList[i], "C") || !g_ascii_strcasecmp(languageList[i], "POSIX")) languages.append(ASCIILiteral("en-us")); else languages.append(String::fromUTF8(languageList[i]).convertToASCIILowercase().replace("_", "-")); } WebCore::overrideUserPreferredLanguages(languages); } /** * webkit_web_context_set_tls_errors_policy: * @context: a #WebKitWebContext * @policy: a #WebKitTLSErrorsPolicy * * Set the TLS errors policy of @context as @policy */ void webkit_web_context_set_tls_errors_policy(WebKitWebContext* context, WebKitTLSErrorsPolicy policy) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); if (context->priv->tlsErrorsPolicy == policy) return; context->priv->tlsErrorsPolicy = policy; bool ignoreTLSErrors = policy == WEBKIT_TLS_ERRORS_POLICY_IGNORE; if (context->priv->processPool->ignoreTLSErrors() != ignoreTLSErrors) context->priv->processPool->setIgnoreTLSErrors(ignoreTLSErrors); } /** * webkit_web_context_get_tls_errors_policy: * @context: a #WebKitWebContext * * Get the TLS errors policy of @context * * Returns: a #WebKitTLSErrorsPolicy */ WebKitTLSErrorsPolicy webkit_web_context_get_tls_errors_policy(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_TLS_ERRORS_POLICY_IGNORE); return context->priv->tlsErrorsPolicy; } /** * webkit_web_context_set_web_extensions_directory: * @context: a #WebKitWebContext * @directory: the directory to add * * Set the directory where WebKit will look for Web Extensions. * This method must be called before loading anything in this context, * otherwise it will not have any effect. You can connect to * #WebKitWebContext::initialize-web-extensions to call this method * before anything is loaded. */ void webkit_web_context_set_web_extensions_directory(WebKitWebContext* context, const char* directory) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); context->priv->webExtensionsDirectory = directory; } /** * webkit_web_context_set_web_extensions_initialization_user_data: * @context: a #WebKitWebContext * @user_data: a #GVariant * * Set user data to be passed to Web Extensions on initialization. * The data will be passed to the * #WebKitWebExtensionInitializeWithUserDataFunction. * This method must be called before loading anything in this context, * otherwise it will not have any effect. You can connect to * #WebKitWebContext::initialize-web-extensions to call this method * before anything is loaded. * * Since: 2.4 */ void webkit_web_context_set_web_extensions_initialization_user_data(WebKitWebContext* context, GVariant* userData) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(userData); context->priv->webExtensionsInitializationUserData = userData; } /** * webkit_web_context_set_disk_cache_directory: * @context: a #WebKitWebContext * @directory: the directory to set * * Set the directory where disk cache files will be stored * This method must be called before loading anything in this context, otherwise * it will not have any effect. * * Note that this method overrides the directory set in the #WebKitWebsiteDataManager, * but it doesn't change the value returned by webkit_website_data_manager_get_disk_cache_directory() * since the #WebKitWebsiteDataManager is immutable. * * Deprecated: 2.10. Use webkit_web_context_new_with_website_data_manager() instead. */ void webkit_web_context_set_disk_cache_directory(WebKitWebContext* context, const char* directory) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); context->priv->processPool->configuration().setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(directory), networkCacheSubdirectory)); } /** * webkit_web_context_prefetch_dns: * @context: a #WebKitWebContext * @hostname: a hostname to be resolved * * Resolve the domain name of the given @hostname in advance, so that if a URI * of @hostname is requested the load will be performed more quickly. */ void webkit_web_context_prefetch_dns(WebKitWebContext* context, const char* hostname) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(hostname); API::Dictionary::MapType message; message.set(String::fromUTF8("Hostname"), API::String::create(String::fromUTF8(hostname))); context->priv->processPool->postMessageToInjectedBundle(String::fromUTF8("PrefetchDNS"), API::Dictionary::create(WTFMove(message)).ptr()); } /** * webkit_web_context_allow_tls_certificate_for_host: * @context: a #WebKitWebContext * @certificate: a #GTlsCertificate * @host: the host for which a certificate is to be allowed * * Ignore further TLS errors on the @host for the certificate present in @info. * * Since: 2.6 */ void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context, GTlsCertificate* certificate, const gchar* host) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(G_IS_TLS_CERTIFICATE(certificate)); g_return_if_fail(host); RefPtr webCertificateInfo = WebCertificateInfo::create(WebCore::CertificateInfo(certificate, static_cast(0))); context->priv->processPool->allowSpecificHTTPSCertificateForHost(webCertificateInfo.get(), String::fromUTF8(host)); } /** * webkit_web_context_set_process_model: * @context: the #WebKitWebContext * @process_model: a #WebKitProcessModel * * Specifies a process model for WebViews, which WebKit will use to * determine how auxiliary processes are handled. The default setting * (%WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS) is suitable for most * applications which embed a small amount of WebViews, or are used to * display documents which are considered safe — like local files. * * Applications which may potentially use a large amount of WebViews * —for example a multi-tabbed web browser— may want to use * %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES, which will use * one process per view most of the time, while still allowing for web * views to share a process when needed (for example when different * views interact with each other). Using this model, when a process * hangs or crashes, only the WebViews using it stop working, while * the rest of the WebViews in the application will still function * normally. * * This method **must be called before any web process has been created**, * as early as possible in your application. Calling it later will make * your application crash. * * Since: 2.4 */ void webkit_web_context_set_process_model(WebKitWebContext* context, WebKitProcessModel processModel) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); if (processModel == context->priv->processModel) return; context->priv->processModel = processModel; switch (context->priv->processModel) { case WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS: context->priv->processPool->setMaximumNumberOfProcesses(1); break; case WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES: context->priv->processPool->setMaximumNumberOfProcesses(context->priv->processCountLimit); break; } } /** * webkit_web_context_get_process_model: * @context: the #WebKitWebContext * * Returns the current process model. For more information about this value * see webkit_web_context_set_process_model(). * * Returns: the current #WebKitProcessModel * * Since: 2.4 */ WebKitProcessModel webkit_web_context_get_process_model(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS); return context->priv->processModel; } /** * webkit_web_context_set_web_process_count_limit: * @context: the #WebKitWebContext * @limit: the maximum number of web processes * * Sets the maximum number of web processes that can be created at the same time for the @context. * The default value is 0 and means no limit. * * This method **must be called before any web process has been created**, * as early as possible in your application. Calling it later will make * your application crash. * * Since: 2.10 */ void webkit_web_context_set_web_process_count_limit(WebKitWebContext* context, guint limit) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); if (context->priv->processCountLimit == limit) return; context->priv->processCountLimit = limit; if (context->priv->processModel != WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS) context->priv->processPool->setMaximumNumberOfProcesses(limit); } /** * webkit_web_context_get_web_process_count_limit: * @context: the #WebKitWebContext * * Gets the maximum number of web processes that can be created at the same time for the @context. * * Returns: the maximum limit of web processes, or 0 if there isn't a limit. * * Since: 2.10 */ guint webkit_web_context_get_web_process_count_limit(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); return context->priv->processCountLimit; } static void addOriginToMap(WebKitSecurityOrigin* origin, HashMap>* map, bool allowed) { String string = webkitSecurityOriginGetSecurityOrigin(origin).toString(); if (string != "null") map->set(string, API::Boolean::create(allowed)); } /** * webkit_web_context_initialize_notification_permissions: * @context: the #WebKitWebContext * @allowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins * @disallowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins * * Sets initial desktop notification permissions for the @context. * @allowed_origins and @disallowed_origins must each be #GList of * #WebKitSecurityOrigin objects representing origins that will, * respectively, either always or never have permission to show desktop * notifications. No #WebKitNotificationPermissionRequest will ever be * generated for any of the security origins represented in * @allowed_origins or @disallowed_origins. This function is necessary * because some webpages proactively check whether they have permission * to display notifications without ever creating a permission request. * * This function only affects web processes that have not already been * created. The best time to call it is when handling * #WebKitWebContext::initialize-notification-permissions so as to * ensure that new web processes receive the most recent set of * permissions. * * Since: 2.16 */ void webkit_web_context_initialize_notification_permissions(WebKitWebContext* context, GList* allowedOrigins, GList* disallowedOrigins) { HashMap> map; g_list_foreach(allowedOrigins, [](gpointer data, gpointer userData) { addOriginToMap(static_cast(data), static_cast>*>(userData), true); }, &map); g_list_foreach(disallowedOrigins, [](gpointer data, gpointer userData) { addOriginToMap(static_cast(data), static_cast>*>(userData), false); }, &map); context->priv->notificationProvider->setNotificationPermissions(WTFMove(map)); } void webkitWebContextInitializeNotificationPermissions(WebKitWebContext* context) { g_signal_emit(context, signals[INITIALIZE_NOTIFICATION_PERMISSIONS], 0); } WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy) { GRefPtr download = downloadsMap().get(downloadProxy); if (download) return download.get(); download = adoptGRef(webkitDownloadCreate(downloadProxy)); downloadsMap().set(downloadProxy, download.get()); return download.get(); } WebKitDownload* webkitWebContextStartDownload(WebKitWebContext* context, const char* uri, WebPageProxy* initiatingPage) { WebCore::ResourceRequest request(String::fromUTF8(uri)); return webkitWebContextGetOrCreateDownload(context->priv->processPool->download(initiatingPage, request)); } void webkitWebContextRemoveDownload(DownloadProxy* downloadProxy) { downloadsMap().remove(downloadProxy); } void webkitWebContextDownloadStarted(WebKitWebContext* context, WebKitDownload* download) { g_signal_emit(context, signals[DOWNLOAD_STARTED], 0, download); } GVariant* webkitWebContextInitializeWebExtensions(WebKitWebContext* context) { g_signal_emit(context, signals[INITIALIZE_WEB_EXTENSIONS], 0); return g_variant_new("(msmv)", context->priv->webExtensionsDirectory.data(), context->priv->webExtensionsInitializationUserData.get()); } WebProcessPool& webkitWebContextGetProcessPool(WebKitWebContext* context) { g_assert(WEBKIT_IS_WEB_CONTEXT(context)); return *context->priv->processPool; } void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID, const WebCore::ResourceRequest& resourceRequest, CustomProtocolManagerProxy& manager) { GRefPtr request = adoptGRef(webkitURISchemeRequestCreate(customProtocolID, context, resourceRequest, manager)); String scheme(String::fromUTF8(webkit_uri_scheme_request_get_scheme(request.get()))); RefPtr handler = context->priv->uriSchemeHandlers.get(scheme); ASSERT(handler.get()); if (!handler->hasCallback()) return; context->priv->uriSchemeRequests.set(customProtocolID, request.get()); handler->performCallback(request.get()); } void webkitWebContextStopLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) { GRefPtr request = context->priv->uriSchemeRequests.get(customProtocolID); if (!request.get()) return; webkitURISchemeRequestCancel(request.get()); } void webkitWebContextInvalidateCustomProtocolRequests(WebKitWebContext* context, CustomProtocolManagerProxy& manager) { Vector> requests; copyValuesToVector(context->priv->uriSchemeRequests, requests); for (auto& request : requests) { if (webkitURISchemeRequestGetManager(request.get()) == &manager) webkitURISchemeRequestInvalidate(request.get()); } } void webkitWebContextDidFinishLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) { context->priv->uriSchemeRequests.remove(customProtocolID); } bool webkitWebContextIsLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) { return context->priv->uriSchemeRequests.get(customProtocolID); } void webkitWebContextCreatePageForWebView(WebKitWebContext* context, WebKitWebView* webView, WebKitUserContentManager* userContentManager, WebKitWebView* relatedView) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView); // FIXME: icon database private mode is global, not per page, so while there are // pages in private mode we need to enable the private mode in the icon database. webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(context, webView); auto pageConfiguration = API::PageConfiguration::create(); pageConfiguration->setProcessPool(context->priv->processPool.get()); pageConfiguration->setPreferences(webkitSettingsGetPreferences(webkit_web_view_get_settings(webView))); pageConfiguration->setRelatedPage(relatedView ? webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(relatedView)) : nullptr); pageConfiguration->setUserContentController(userContentManager ? webkitUserContentManagerGetUserContentControllerProxy(userContentManager) : nullptr); WebKitWebsiteDataManager* manager = webkitWebViewGetWebsiteDataManager(webView); if (!manager) manager = context->priv->websiteDataManager.get(); pageConfiguration->setWebsiteDataStore(&webkitWebsiteDataManagerGetDataStore(manager)); pageConfiguration->setSessionID(pageConfiguration->websiteDataStore()->websiteDataStore().sessionID()); webkitWebViewBaseCreateWebPage(webViewBase, WTFMove(pageConfiguration)); WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); context->priv->webViews.set(page->pageID(), webView); } void webkitWebContextWebViewDestroyed(WebKitWebContext* context, WebKitWebView* webView) { webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(context, webView); WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); context->priv->webViews.remove(page->pageID()); } WebKitWebView* webkitWebContextGetWebViewForPage(WebKitWebContext* context, WebPageProxy* page) { return page ? context->priv->webViews.get(page->pageID()) : 0; }