Diff
Modified: trunk/Source/WebCore/platform/gtk/po/POTFILES.in (211078 => 211079)
--- trunk/Source/WebCore/platform/gtk/po/POTFILES.in 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebCore/platform/gtk/po/POTFILES.in 2017-01-24 07:48:40 UTC (rev 211079)
@@ -15,6 +15,7 @@
../../../WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp
../../../WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp
../../../WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
+../../../WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp
../../../WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
../../../WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
../../../WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp
Modified: trunk/Source/WebKit2/ChangeLog (211078 => 211079)
--- trunk/Source/WebKit2/ChangeLog 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/ChangeLog 2017-01-24 07:48:40 UTC (rev 211079)
@@ -1,3 +1,42 @@
+2017-01-23 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Add API to WebKitWebsiteDataManager to handle website data
+ https://bugs.webkit.org/show_bug.cgi?id=146589
+
+ Reviewed by Michael Catanzaro.
+
+ Add WebKitWebsiteData boxed type to wrap a WebsiteDataRecord and new methods to WebKitWebsiteDataManager to
+ fetch, remove and clear website data.
+
+ * PlatformGTK.cmake: Add new files to compilation.
+ * UIProcess/API/gtk/WebKitWebsiteData.cpp: Added.
+ (_WebKitWebsiteData::_WebKitWebsiteData):
+ (recordContainsSupportedDataTypes): Helper function to check if the WebsiteDataRecord contains any type exposed
+ by our API.
+ (toWebKitWebsiteDataTypes): Convert from WebKit::WebsiteDataType to the GTK+ public API types.
+ (webkitWebsiteDataCreate): Create a new WebKitWebsiteData for the given WebsiteDataRecord if it contains any
+ supported type.
+ (webkitWebsiteDataGetRecord): Returns the wrapped WebsiteDataRecord.
+ (webkit_website_data_ref):
+ (webkit_website_data_unref):
+ (webkit_website_data_get_name): Return the display name.
+ (webkit_website_data_get_types): Returns the mask of types.
+ (webkit_website_data_get_size): Returns the size for the given types.
+ * UIProcess/API/gtk/WebKitWebsiteData.h: Added.
+ * UIProcess/API/gtk/WebKitWebsiteDataManager.cpp:
+ (toWebsiteDataTypes): Convert from GTK+ public API types to WebKit::WebsiteDataType.
+ (webkit_website_data_manager_fetch): Fetch website data of the given types.
+ (webkit_website_data_manager_fetch_finish):
+ (webkit_website_data_manager_remove): Remove the website data of the given types for the given WebKitWebsiteData list.
+ (webkit_website_data_manager_remove_finish):
+ (webkit_website_data_manager_clear): Clear all website data of the given types modified since the given time span.
+ (webkit_website_data_manager_clear_finish):
+ * UIProcess/API/gtk/WebKitWebsiteDataManager.h:
+ * UIProcess/API/gtk/WebKitWebsiteDataPrivate.h: Added.
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols.
+ * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section.
+ * UIProcess/API/gtk/webkit2.h: Inlcude WebKitWebsiteData.h
+
2017-01-23 Antti Koivisto <[email protected]>
Maintain ordering when doing speculative loads
Modified: trunk/Source/WebKit2/PlatformGTK.cmake (211078 => 211079)
--- trunk/Source/WebKit2/PlatformGTK.cmake 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/PlatformGTK.cmake 2017-01-24 07:48:40 UTC (rev 211079)
@@ -270,6 +270,9 @@
UIProcess/API/gtk/WebKitWebViewSessionState.cpp
UIProcess/API/gtk/WebKitWebViewSessionState.h
UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h
+ UIProcess/API/gtk/WebKitWebsiteData.cpp
+ UIProcess/API/gtk/WebKitWebsiteData.h
+ UIProcess/API/gtk/WebKitWebsiteDataPrivate.h
UIProcess/API/gtk/WebKitWebsiteDataManager.cpp
UIProcess/API/gtk/WebKitWebsiteDataManager.h
UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h
@@ -554,6 +557,7 @@
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWebView.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWebViewBase.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWebViewSessionState.h
+ ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWebsiteData.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWebsiteDataManager.h
${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitWindowProperties.h
${WEBKIT2_DIR}/UIProcess/API/gtk/webkit2.h
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp (0 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp 2017-01-24 07:48:40 UTC (rev 211079)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2017 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 "WebKitWebsiteData.h"
+
+#include "WebKitSecurityOriginPrivate.h"
+#include "WebKitWebsiteDataPrivate.h"
+#include <glib/gi18n.h>
+#include <wtf/HashTable.h>
+#include <wtf/Vector.h>
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitWebsiteData
+ * @Short_description: Website data
+ * @Title: WebKitWebsiteData
+ * @See_also: #WebKitWebsiteDataManager
+ *
+ * WebKitWebsiteData represents data stored in the client by a particular website.
+ * A website is normally a set of URLs grouped by domain name. You can get the website name,
+ * which is usually the domain, with webkit_website_data_get_name().
+ * Documents loaded from the file system, like file:// URIs, are all grouped in the same WebKitWebsiteData
+ * with the name "Local files".
+ *
+ * A website can store different types of data in the client side. #WebKitWebsiteDataTypes is an enum containing
+ * all the possible data types; use webkit_website_data_get_types() to get the bitmask of data types.
+ * It's also possible to know the size of the data stored for some of the #WebKitWebsiteDataTypes by using
+ * webkit_website_data_get_size().
+ *
+ * A list of WebKitWebsiteData can be retrieved with webkit_website_data_manager_fetch(). See #WebKitWebsiteDataManager
+ * for more information.
+ *
+ * Since: 2.16
+ */
+struct _WebKitWebsiteData {
+ explicit _WebKitWebsiteData(WebsiteDataRecord&& websiteDataDecord)
+ : record(WTFMove(websiteDataDecord))
+ {
+ }
+
+ WebsiteDataRecord record;
+ CString displayName;
+ int referenceCount { 1 };
+};
+
+G_DEFINE_BOXED_TYPE(WebKitWebsiteData, webkit_website_data, webkit_website_data_ref, webkit_website_data_unref)
+
+static bool recordContainsSupportedDataTypes(const WebsiteDataRecord& record)
+{
+ static const OptionSet<WebsiteDataType> typesSupported = {
+ WebsiteDataType::MemoryCache,
+ WebsiteDataType::DiskCache,
+ WebsiteDataType::OfflineWebApplicationCache,
+ WebsiteDataType::SessionStorage,
+ WebsiteDataType::LocalStorage,
+ WebsiteDataType::WebSQLDatabases,
+ WebsiteDataType::IndexedDBDatabases,
+ WebsiteDataType::PlugInData
+ };
+ return record.types.contains(typesSupported);
+}
+
+static WebKitWebsiteDataTypes toWebKitWebsiteDataTypes(OptionSet<WebsiteDataType> types)
+{
+ uint32_t returnValue = 0;
+ if (types.contains(WebsiteDataType::MemoryCache))
+ returnValue |= WEBKIT_WEBSITE_DATA_MEMORY_CACHE;
+ if (types.contains(WebsiteDataType::DiskCache))
+ returnValue |= WEBKIT_WEBSITE_DATA_DISK_CACHE;
+ if (types.contains(WebsiteDataType::OfflineWebApplicationCache))
+ returnValue |= WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE;
+ if (types.contains(WebsiteDataType::SessionStorage))
+ returnValue |= WEBKIT_WEBSITE_DATA_SESSION_STORAGE;
+ if (types.contains(WebsiteDataType::LocalStorage))
+ returnValue |= WEBKIT_WEBSITE_DATA_LOCAL_STORAGE;
+ if (types.contains(WebsiteDataType::WebSQLDatabases))
+ returnValue |= WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES;
+ if (types.contains(WebsiteDataType::IndexedDBDatabases))
+ returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES;
+ if (types.contains(WebsiteDataType::PlugInData))
+ returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA;
+ return static_cast<WebKitWebsiteDataTypes>(returnValue);
+}
+
+WebKitWebsiteData* webkitWebsiteDataCreate(WebsiteDataRecord&& record)
+{
+ if (!recordContainsSupportedDataTypes(record))
+ return nullptr;
+
+ WebKitWebsiteData* websiteData = static_cast<WebKitWebsiteData*>(fastMalloc(sizeof(WebKitWebsiteData)));
+ new (websiteData) WebKitWebsiteData(WTFMove(record));
+ return websiteData;
+}
+
+const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData* websiteData)
+{
+ ASSERT(websiteData);
+ return websiteData->record;
+}
+
+/**
+ * webkit_website_data_ref:
+ * @website_data: a #WebKitWebsiteData
+ *
+ * Atomically increments the reference count of @website_data by one.
+ * This function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed #WebKitWebsiteData
+ *
+ * Since: 2.16
+ */
+WebKitWebsiteData* webkit_website_data_ref(WebKitWebsiteData* websiteData)
+{
+ g_return_val_if_fail(websiteData, nullptr);
+
+ g_atomic_int_inc(&websiteData->referenceCount);
+ return websiteData;
+}
+
+/**
+ * webkit_website_data_unref:
+ * @website_data: A #WebKitWebsiteData
+ *
+ * Atomically decrements the reference count of @website_data by one.
+ * If the reference count drops to 0, all memory allocated by
+ * #WebKitWebsiteData is released. This function is MT-safe and may be
+ * called from any thread.
+ *
+ * Since: 2.16
+ */
+void webkit_website_data_unref(WebKitWebsiteData* websiteData)
+{
+ g_return_if_fail(websiteData);
+
+ if (g_atomic_int_dec_and_test(&websiteData->referenceCount)) {
+ websiteData->~WebKitWebsiteData();
+ fastFree(websiteData);
+ }
+}
+
+/**
+ * webkit_website_data_get_name:
+ * @website_data: a #WebKitWebsiteData
+ *
+ * Gets the name of #WebKitWebsiteData. This is the website name, normally represented by
+ * a domain or host name. All local documents are grouped in the same #WebKitWebsiteData using
+ * the name "Local files".
+ *
+ * Returns: the website name of @website_data.
+ *
+ * Since: 2.16
+ */
+const char* webkit_website_data_get_name(WebKitWebsiteData* websiteData)
+{
+ g_return_val_if_fail(websiteData, nullptr);
+
+ if (websiteData->displayName.isNull()) {
+ if (websiteData->record.displayName == "Local documents on your computer")
+ websiteData->displayName = _("Local files");
+ else
+ websiteData->displayName = websiteData->record.displayName.utf8();
+ }
+ return websiteData->displayName.data();
+}
+
+/**
+ * webkit_website_data_get_types:
+ * @website_data: a #WebKitWebsiteData
+ *
+ * Gets the types of data stored in the client for a #WebKitWebsiteData. These are the
+ * types actually present, not the types queried with webkit_website_data_manager_fetch().
+ *
+ * Returns: a bitmask of #WebKitWebsiteDataTypes in @website_data
+ *
+ * Since: 2.16
+ */
+WebKitWebsiteDataTypes webkit_website_data_get_types(WebKitWebsiteData* websiteData)
+{
+ g_return_val_if_fail(websiteData, static_cast<WebKitWebsiteDataTypes>(0));
+
+ return toWebKitWebsiteDataTypes(websiteData->record.types);
+}
+
+/**
+ * webkit_website_data_get_size:
+ * @website_data: a #WebKitWebsiteData
+ * @types: a bitmask of #WebKitWebsiteDataTypes
+ *
+ * Gets the size of the data of types @types in a #WebKitWebsiteData.
+ * Note that currently the data size is only known for %WEBKIT_WEBSITE_DATA_DISK_CACHE data type
+ * so for all other types 0 will be returned.
+ *
+ * Returns: the size of @website_data for the given @types.
+ *
+ * Since: 2.16
+ */
+guint64 webkit_website_data_get_size(WebKitWebsiteData* websiteData, WebKitWebsiteDataTypes types)
+{
+ g_return_val_if_fail(websiteData, 0);
+
+ if (!types || !websiteData->record.size)
+ return 0;
+
+ guint64 totalSize = 0;
+ for (auto type : websiteData->record.size->typeSizes.keys()) {
+ if (type & types)
+ totalSize += websiteData->record.size->typeSizes.get(type);
+ }
+
+ return totalSize;
+}
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h (0 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h 2017-01-24 07:48:40 UTC (rev 211079)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitWebsiteData_h
+#define WebKitWebsiteData_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_WEBSITE_DATA (webkit_website_data_get_type())
+
+typedef struct _WebKitWebsiteData WebKitWebsiteData;
+
+/**
+ * WebKitWebsiteDataTypes:
+ * @WEBKIT_WEBSITE_DATA_MEMORY_CACHE: Memory cache.
+ * @WEBKIT_WEBSITE_DATA_DISK_CACHE: HTTP disk cache.
+ * @WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE: Offline web application cache.
+ * @WEBKIT_WEBSITE_DATA_SESSION_STORAGE: Session storage data.
+ * @WEBKIT_WEBSITE_DATA_LOCAL_STORAGE: Local storage data.
+ * @WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES: WebSQL databases.
+ * @WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES: IndexedDB databases.
+ * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data.
+ * @WEBKIT_WEBSITE_DATA_ALL: All types.
+ *
+ * Enum values with flags representing types of Website data.
+ *
+ * Since: 2.16
+ */
+typedef enum {
+ WEBKIT_WEBSITE_DATA_MEMORY_CACHE = 1 << 0,
+ WEBKIT_WEBSITE_DATA_DISK_CACHE = 1 << 1,
+ WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE = 1 << 2,
+ WEBKIT_WEBSITE_DATA_SESSION_STORAGE = 1 << 3,
+ WEBKIT_WEBSITE_DATA_LOCAL_STORAGE = 1 << 4,
+ WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES = 1 << 5,
+ WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES = 1 << 6,
+ WEBKIT_WEBSITE_DATA_PLUGIN_DATA = 1 << 7,
+ WEBKIT_WEBSITE_DATA_ALL = (1 << 8) - 1
+} WebKitWebsiteDataTypes;
+
+WEBKIT_API GType
+webkit_website_data_get_type (void);
+
+WEBKIT_API WebKitWebsiteData *
+webkit_website_data_ref (WebKitWebsiteData *website_data);
+
+WEBKIT_API void
+webkit_website_data_unref (WebKitWebsiteData *website_data);
+
+WEBKIT_API const char *
+webkit_website_data_get_name (WebKitWebsiteData *website_data);
+
+WEBKIT_API WebKitWebsiteDataTypes
+webkit_website_data_get_types (WebKitWebsiteData *website_data);
+
+WEBKIT_API guint64
+webkit_website_data_get_size (WebKitWebsiteData *website_data,
+ WebKitWebsiteDataTypes types);
+
+G_END_DECLS
+
+#endif /* WebKitWebsiteData_h */
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp (211078 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp 2017-01-24 07:48:40 UTC (rev 211079)
@@ -22,6 +22,8 @@
#include "APIWebsiteDataStore.h"
#include "WebKitWebsiteDataManagerPrivate.h"
+#include "WebKitWebsiteDataPrivate.h"
+#include "WebsiteDataFetchOption.h"
#include <WebCore/FileSystem.h>
#include <glib/gi18n-lib.h>
#include <wtf/glib/GUniquePtr.h>
@@ -32,7 +34,7 @@
* SECTION: WebKitWebsiteDataManager
* @Short_description: Website data manager
* @Title: WebKitWebsiteDataManager
- * @See_also: #WebKitWebContext
+ * @See_also: #WebKitWebContext, #WebKitWebsiteData
*
* WebKitWebsiteDataManager allows you to manage the data that websites
* can store in the client file system like databases or caches.
@@ -54,6 +56,10 @@
* with the default configuration. To get the WebKitWebsiteDataManager of a #WebKitWebContext
* you can use webkit_web_context_get_website_data_manager().
*
+ * WebKitWebsiteDataManager can also be used to fetch websites data, remove data
+ * stored by particular websites, or clear data for all websites modified since a given
+ * period of time.
+ *
* Since: 2.10
*/
@@ -483,3 +489,188 @@
priv->webSQLDirectory.reset(g_strdup(API::WebsiteDataStore::defaultWebSQLDatabaseDirectory().utf8().data()));
return priv->webSQLDirectory.get();
}
+
+static OptionSet<WebsiteDataType> toWebsiteDataTypes(WebKitWebsiteDataTypes types)
+{
+ OptionSet<WebsiteDataType> returnValue;
+ if (types & WEBKIT_WEBSITE_DATA_MEMORY_CACHE)
+ returnValue |= WebsiteDataType::MemoryCache;
+ if (types & WEBKIT_WEBSITE_DATA_DISK_CACHE)
+ returnValue |= WebsiteDataType::DiskCache;
+ if (types & WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE)
+ returnValue |= WebsiteDataType::OfflineWebApplicationCache;
+ if (types & WEBKIT_WEBSITE_DATA_SESSION_STORAGE)
+ returnValue |= WebsiteDataType::SessionStorage;
+ if (types & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE)
+ returnValue |= WebsiteDataType::LocalStorage;
+ if (types & WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES)
+ returnValue |= WebsiteDataType::WebSQLDatabases;
+ if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES)
+ returnValue |= WebsiteDataType::IndexedDBDatabases;
+ if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA)
+ returnValue |= WebsiteDataType::PlugInData;
+ return returnValue;
+}
+
+/**
+ * webkit_website_data_manager_fetch:
+ * @manager: a #WebKitWebsiteDataManager
+ * @types: #WebKitWebsiteDataTypes
+ * @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 #WebKitWebsiteData for the given @types.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_website_data_manager_fetch_finish() to get the result of the operation.
+ *
+ * Since: 2.16
+ */
+void webkit_website_data_manager_fetch(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
+
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+ manager->priv->websiteDataStore->websiteDataStore().fetchData(toWebsiteDataTypes(types), WebsiteDataFetchOption::ComputeSizes, [task = WTFMove(task)] (Vector<WebsiteDataRecord> records) {
+ GList* dataList = nullptr;
+ while (!records.isEmpty()) {
+ if (auto* data = ""
+ dataList = g_list_prepend(dataList, data);
+ }
+
+ g_task_return_pointer(task.get(), dataList, [](gpointer data) {
+ g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
+ });
+ });
+}
+
+/**
+ * webkit_website_data_manager_fetch_finish:
+ * @manager: a #WebKitWebsiteDataManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_website_data_manager_fetch().
+ *
+ * Returns: (element-type WebKitWebsiteData) (transfer full): a #GList of #WebKitWebsiteData. You must free the #GList with
+ * g_list_free() and unref the #WebKitWebsiteData<!-- -->s with webkit_website_data_unref() when you're done with them.
+ *
+ * Since: 2.16
+ */
+GList* webkit_website_data_manager_fetch_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
+ g_return_val_if_fail(g_task_is_valid(result, manager), nullptr);
+
+ return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error));
+}
+
+/**
+ * webkit_website_data_manager_remove:
+ * @manager: a #WebKitWebsiteDataManager
+ * @types: #WebKitWebsiteDataTypes
+ * @website_data: (element-type WebKitWebsiteData): a #GList of #WebKitWebsiteData
+ * @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 removes the website data of the for the given @types for websites in the given @website_data list.
+ * Use webkit_website_data_manager_clear() if you want to remove the website data for all sites.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_website_data_manager_remove_finish() to get the result of the operation.
+ *
+ * Since: 2.16
+ */
+void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GList* websiteData, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
+ g_return_if_fail(websiteData);
+
+ Vector<WebsiteDataRecord> records;
+ for (GList* item = websiteData; item; item = g_list_next(item)) {
+ WebKitWebsiteData* data = ""
+
+ if (webkit_website_data_get_types(data) & types)
+ records.append(webkitWebsiteDataGetRecord(data));
+ }
+
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+ if (records.isEmpty()) {
+ g_task_return_boolean(task.get(), TRUE);
+ return;
+ }
+
+ manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), records, [task = WTFMove(task)] {
+ g_task_return_boolean(task.get(), TRUE);
+ });
+}
+
+/**
+ * webkit_website_data_manager_remove_finish:
+ * @manager: a #WebKitWebsiteDataManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_website_data_manager_remove().
+ *
+ * Returns: %TRUE if website data resources were succesfully removed, or %FALSE otherwise.
+ *
+ * Since: 2.16
+ */
+gboolean webkit_website_data_manager_remove_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
+ g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/**
+ * webkit_website_data_manager_clear:
+ * @manager: a #WebKitWebsiteDataManager
+ * @types: #WebKitWebsiteDataTypes
+ * @timespan: a #GTimeSpan
+ * @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 clear the website data of the given @types modified in the past @timespan.
+ * If @timespan is 0 all website data will be removed.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_website_data_manager_clear_finish() to get the result of the operation.
+ *
+ * Since: 2.16
+ */
+void webkit_website_data_manager_clear(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GTimeSpan timeSpan, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
+
+ std::chrono::system_clock::time_point timePoint = timeSpan ? std::chrono::system_clock::now() - std::chrono::microseconds(timeSpan) : std::chrono::system_clock::from_time_t(0);
+ GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData));
+ manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), timePoint, [task = WTFMove(task)] {
+ g_task_return_boolean(task.get(), TRUE);
+ });
+}
+
+/**
+ * webkit_website_data_manager_clear_finish:
+ * @manager: a #WebKitWebsiteDataManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_website_data_manager_clear()
+ *
+ * Returns: %TRUE if website data was succesfully cleared, or %FALSE otherwise.
+ *
+ * Since: 2.16
+ */
+gboolean webkit_website_data_manager_clear_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE);
+ g_return_val_if_fail(g_task_is_valid(result, manager), FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h (211078 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h 2017-01-24 07:48:40 UTC (rev 211079)
@@ -24,8 +24,9 @@
#ifndef WebKitWebsiteDataManager_h
#define WebKitWebsiteDataManager_h
-#include <glib-object.h>
+#include <gio/gio.h>
#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitWebsiteData.h>
G_BEGIN_DECLS
@@ -56,32 +57,68 @@
};
WEBKIT_API GType
-webkit_website_data_manager_get_type (void);
+webkit_website_data_manager_get_type (void);
WEBKIT_API WebKitWebsiteDataManager *
-webkit_website_data_manager_new (const gchar *first_option_name,
- ...);
+webkit_website_data_manager_new (const gchar *first_option_name,
+ ...);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_base_data_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_base_data_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_base_cache_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_base_cache_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_local_storage_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_local_storage_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_disk_cache_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_disk_cache_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_offline_application_cache_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_offline_application_cache_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_indexeddb_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_indexeddb_directory (WebKitWebsiteDataManager *manager);
WEBKIT_API const gchar *
-webkit_website_data_manager_get_websql_directory (WebKitWebsiteDataManager *manager);
+webkit_website_data_manager_get_websql_directory (WebKitWebsiteDataManager *manager);
+WEBKIT_API void
+webkit_website_data_manager_fetch (WebKitWebsiteDataManager *manager,
+ WebKitWebsiteDataTypes types,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API GList *
+webkit_website_data_manager_fetch_finish (WebKitWebsiteDataManager *manager,
+ GAsyncResult *result,
+ GError **error);
+WEBKIT_API void
+webkit_website_data_manager_remove (WebKitWebsiteDataManager *manager,
+ WebKitWebsiteDataTypes types,
+ GList *website_data,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+WEBKIT_API gboolean
+webkit_website_data_manager_remove_finish (WebKitWebsiteDataManager *manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_website_data_manager_clear (WebKitWebsiteDataManager *manager,
+ WebKitWebsiteDataTypes types,
+ GTimeSpan timespan,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gboolean
+webkit_website_data_manager_clear_finish (WebKitWebsiteDataManager *manager,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif
Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h (0 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h 2017-01-24 07:48:40 UTC (rev 211079)
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include "WebKitPrivate.h"
+#include "WebKitWebsiteData.h"
+#include "WebsiteDataRecord.h"
+
+WebKitWebsiteData* webkitWebsiteDataCreate(WebKit::WebsiteDataRecord&&);
+const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData*);
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (211078 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2017-01-24 07:48:40 UTC (rev 211079)
@@ -1244,6 +1244,12 @@
webkit_website_data_manager_get_offline_application_cache_directory
webkit_website_data_manager_get_indexeddb_directory
webkit_website_data_manager_get_websql_directory
+webkit_website_data_manager_fetch
+webkit_website_data_manager_fetch_finish
+webkit_website_data_manager_remove
+webkit_website_data_manager_remove_finish
+webkit_website_data_manager_clear
+webkit_website_data_manager_clear_finish
<SUBSECTION Standard>
WebKitWebsiteDataManagerClass
@@ -1260,6 +1266,23 @@
</SECTION>
<SECTION>
+<FILE>WebKitWebsiteData</FILE>
+WebKitWebsiteData
+WebKitWebsiteDataTypes
+webkit_website_data_ref
+webkit_website_data_unref
+webkit_website_data_get_name
+webkit_website_data_get_types
+webkit_website_data_get_size
+
+<SUBSECTION Standard>
+WEBKIT_TYPE_WEBSITE_DATA
+
+<SUBSECTION Private>
+webkit_website_data_get_type
+</SECTION>
+
+<SECTION>
<FILE>WebKitNetworkProxySettings</FILE>
WebKitNetworkProxySettings
webkit_network_proxy_settings_new
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml (211078 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml 2017-01-24 07:48:40 UTC (rev 211079)
@@ -53,6 +53,7 @@
<xi:include href=""
<xi:include href=""
<xi:include href=""
+ <xi:include href=""
<xi:include href=""
</chapter>
@@ -106,5 +107,15 @@
<xi:include href="" /></xi:include>
</index>
+ <index id="api-index-2-14" role="2.14">
+ <title>Index of new symbols in 2.14</title>
+ <xi:include href="" /></xi:include>
+ </index>
+
+ <index id="api-index-2-16" role="2.16">
+ <title>Index of new symbols in 2.16</title>
+ <xi:include href="" /></xi:include>
+ </index>
+
<xi:include href="" /></xi:include>
</book>
Modified: trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h (211078 => 211079)
--- trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h 2017-01-24 07:48:40 UTC (rev 211079)
@@ -77,6 +77,7 @@
#include <webkit2/WebKitWebView.h>
#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWebViewSessionState.h>
+#include <webkit2/WebKitWebsiteData.h>
#include <webkit2/WebKitWebsiteDataManager.h>
#include <webkit2/WebKitWindowProperties.h>
Modified: trunk/Tools/ChangeLog (211078 => 211079)
--- trunk/Tools/ChangeLog 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Tools/ChangeLog 2017-01-24 07:48:40 UTC (rev 211079)
@@ -1,3 +1,49 @@
+2017-01-23 Carlos Garcia Campos <[email protected]>
+
+ [GTK] Add API to WebKitWebsiteDataManager to handle website data
+ https://bugs.webkit.org/show_bug.cgi?id=146589
+
+ Reviewed by Michael Catanzaro.
+
+ Add about:data handler to MiniBrowser to manually test the website data API. Also add unit tests to test all the
+ new API, moving the WebKitWebsiteDataManager configuration API to the new file too.
+
+ * MiniBrowser/gtk/BrowserWindow.c:
+ (webViewDecidePolicy):
+ (newTabCallback):
+ * MiniBrowser/gtk/main.c:
+ (createBrowserTab):
+ (aboutDataRequestFree):
+ (aboutDataRequestNew):
+ (aboutDataRequestForView):
+ (websiteDataRemovedCallback):
+ (websiteDataClearedCallback):
+ (aboutDataScriptMessageReceivedCallback):
+ (domainListFree):
+ (aboutDataFillTable):
+ (gotWebsiteDataCallback):
+ (aboutDataHandleRequest):
+ (aboutURISchemeRequestCallback):
+ (main):
+ * TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt:
+ * TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp:
+ (serverCallback):
+ (beforeAll):
+ * TestWebKitAPI/Tests/WebKit2Gtk/TestWebsiteData.cpp: Added.
+ (serverCallback):
+ (WebsiteDataTest::WebsiteDataTest):
+ (WebsiteDataTest::~WebsiteDataTest):
+ (WebsiteDataTest::fetch):
+ (WebsiteDataTest::remove):
+ (WebsiteDataTest::clear):
+ (testWebsiteDataConfiguration):
+ (testWebsiteDataCache):
+ (testWebsiteDataStorage):
+ (testWebsiteDataDatabases):
+ (testWebsiteDataAppcache):
+ (beforeAll):
+ (afterAll):
+
2017-01-23 Commit Queue <[email protected]>
Unreviewed, rolling out r211062.
Modified: trunk/Tools/MiniBrowser/gtk/BrowserWindow.c (211078 => 211079)
--- trunk/Tools/MiniBrowser/gtk/BrowserWindow.c 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Tools/MiniBrowser/gtk/BrowserWindow.c 2017-01-24 07:48:40 UTC (rev 211079)
@@ -330,7 +330,11 @@
return FALSE;
/* Opening a new tab if link clicked with the middle button. */
- WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
+ WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "web-context", webkit_web_view_get_context(webView),
+ "settings", webkit_web_view_get_settings(webView),
+ "user-content-manager", webkit_web_view_get_user_content_manager(webView),
+ NULL));
browser_window_append_view(window, newWebView);
webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
@@ -466,8 +470,12 @@
WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
if (webkit_web_view_is_editable(webView))
return;
- WebKitSettings *settings = webkit_web_view_get_settings(webView);
- browser_window_append_view(window, WEBKIT_WEB_VIEW(webkit_web_view_new_with_settings(settings)));
+
+ browser_window_append_view(window, WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "web-context", webkit_web_view_get_context(webView),
+ "settings", webkit_web_view_get_settings(webView),
+ "user-content-manager", webkit_web_view_get_user_content_manager(webView),
+ NULL)));
gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), -1);
}
Modified: trunk/Tools/MiniBrowser/gtk/main.c (211078 => 211079)
--- trunk/Tools/MiniBrowser/gtk/main.c 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Tools/MiniBrowser/gtk/main.c 2017-01-24 07:48:40 UTC (rev 211079)
@@ -28,6 +28,7 @@
#include "cmakeconfig.h"
#include "BrowserWindow.h"
+#include <_javascript_Core/_javascript_.h>
#include <errno.h>
#include <gtk/gtk.h>
#include <string.h>
@@ -59,9 +60,9 @@
return fileURL;
}
-static WebKitWebView *createBrowserTab(BrowserWindow *window, WebKitSettings *webkitSettings)
+static WebKitWebView *createBrowserTab(BrowserWindow *window, WebKitSettings *webkitSettings, WebKitUserContentManager *userContentManager)
{
- WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_user_content_manager(userContentManager));
if (webkitSettings)
webkit_web_view_set_settings(webView, webkitSettings);
if (editorMode)
@@ -225,6 +226,194 @@
return TRUE;
}
+typedef struct {
+ WebKitURISchemeRequest *request;
+ GList *dataList;
+ GHashTable *dataMap;
+} AboutDataRequest;
+
+static GHashTable *aboutDataRequestMap;
+
+static void aboutDataRequestFree(AboutDataRequest *request)
+{
+ if (!request)
+ return;
+
+ g_list_free_full(request->dataList, g_object_unref);
+
+ if (request->request)
+ g_object_unref(request->request);
+ if (request->dataMap)
+ g_hash_table_destroy(request->dataMap);
+
+ g_slice_free(AboutDataRequest, request);
+}
+
+static AboutDataRequest* aboutDataRequestNew(WebKitURISchemeRequest *uriRequest)
+{
+ if (!aboutDataRequestMap)
+ aboutDataRequestMap = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)aboutDataRequestFree);
+
+ AboutDataRequest *request = g_slice_new0(AboutDataRequest);
+ request->request = g_object_ref(uriRequest);
+ g_hash_table_insert(aboutDataRequestMap, GUINT_TO_POINTER(webkit_web_view_get_page_id(webkit_uri_scheme_request_get_web_view(request->request))), request);
+
+ return request;
+}
+
+static AboutDataRequest *aboutDataRequestForView(guint64 pageID)
+{
+ return aboutDataRequestMap ? g_hash_table_lookup(aboutDataRequestMap, GUINT_TO_POINTER(pageID)) : NULL;
+}
+
+static void websiteDataRemovedCallback(WebKitWebsiteDataManager *manager, GAsyncResult *result, AboutDataRequest *dataRequest)
+{
+ if (webkit_website_data_manager_remove_finish(manager, result, NULL))
+ webkit_web_view_reload(webkit_uri_scheme_request_get_web_view(dataRequest->request));
+}
+
+static void websiteDataClearedCallback(WebKitWebsiteDataManager *manager, GAsyncResult *result, AboutDataRequest *dataRequest)
+{
+ if (webkit_website_data_manager_clear_finish(manager, result, NULL))
+ webkit_web_view_reload(webkit_uri_scheme_request_get_web_view(dataRequest->request));
+}
+
+static void aboutDataScriptMessageReceivedCallback(WebKitUserContentManager *userContentManager, WebKitJavascriptResult *message)
+{
+ JSValueRef jsValue = webkit_javascript_result_get_value(message);
+ JSStringRef jsString = JSValueToStringCopy(webkit_javascript_result_get_global_context(message), jsValue, NULL);
+ size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString);
+ if (!maxSize) {
+ JSStringRelease(jsString);
+ return;
+ }
+ char *messageString = g_malloc(maxSize);
+ JSStringGetUTF8CString(jsString, messageString, maxSize);
+ JSStringRelease(jsString);
+
+ char **tokens = g_strsplit(messageString, ":", 3);
+ g_free(messageString);
+
+ unsigned tokenCount = g_strv_length(tokens);
+ if (!tokens || tokenCount < 2) {
+ g_strfreev(tokens);
+ return;
+ }
+
+ guint64 pageID = g_ascii_strtoull(tokens[0], NULL, 10);
+ AboutDataRequest *dataRequest = aboutDataRequestForView(pageID);
+ if (!dataRequest) {
+ g_strfreev(tokens);
+ return;
+ }
+
+ WebKitWebsiteDataManager *manager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default());
+ guint64 types = g_ascii_strtoull(tokens[1], NULL, 10);
+ if (tokenCount == 2)
+ webkit_website_data_manager_clear(manager, types, 0, NULL, (GAsyncReadyCallback)websiteDataClearedCallback, dataRequest);
+ else {
+ guint64 domainID = g_ascii_strtoull(tokens[2], NULL, 10);
+ GList *dataList = g_hash_table_lookup(dataRequest->dataMap, GUINT_TO_POINTER(types));
+ WebKitWebsiteData *data = "" domainID);
+ if (data) {
+ GList dataList = { data, NULL, NULL };
+ webkit_website_data_manager_remove(manager, types, &dataList, NULL, (GAsyncReadyCallback)websiteDataRemovedCallback, dataRequest);
+ }
+ }
+ g_strfreev(tokens);
+}
+
+static void domainListFree(GList *domains)
+{
+ g_list_free_full(domains, (GDestroyNotify)webkit_website_data_unref);
+}
+
+static void aboutDataFillTable(GString *result, AboutDataRequest *dataRequest, GList* dataList, const char *title, WebKitWebsiteDataTypes types, const char *dataPath, guint64 pageID)
+{
+ guint64 totalDataSize = 0;
+ GList *domains = NULL;
+ GList *l;
+ for (l = dataList; l; l = g_list_next(l)) {
+ WebKitWebsiteData *data = "" *)l->data;
+
+ if (webkit_website_data_get_types(data) & types) {
+ domains = g_list_prepend(domains, webkit_website_data_ref(data));
+ totalDataSize += webkit_website_data_get_size(data, types);
+ }
+ }
+ if (!domains)
+ return;
+
+ if (!dataRequest->dataMap)
+ dataRequest->dataMap = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)domainListFree);
+ g_hash_table_insert(dataRequest->dataMap, GUINT_TO_POINTER(types), domains);
+
+ if (totalDataSize) {
+ char *totalDataSizeStr = g_format_size(totalDataSize);
+ g_string_append_printf(result, "<h1>%s (%s)</h1>\n<table>\n", title, totalDataSizeStr);
+ g_free(totalDataSizeStr);
+ } else
+ g_string_append_printf(result, "<h1>%s</h1>\n<table>\n", title);
+ if (dataPath)
+ g_string_append_printf(result, "<tr><td colspan=\"2\">Path: %s</td></tr>\n", dataPath);
+
+ unsigned index;
+ for (l = domains, index = 0; l; l = g_list_next(l), index++) {
+ WebKitWebsiteData *data = "" *)l->data;
+ const char *displayName = webkit_website_data_get_name(data);
+ guint64 dataSize = webkit_website_data_get_size(data, types);
+ if (dataSize) {
+ char *dataSizeStr = g_format_size(dataSize);
+ g_string_append_printf(result, "<tr><td>%s (%s)</td>", displayName, dataSizeStr);
+ g_free(dataSizeStr);
+ } else
+ g_string_append_printf(result, "<tr><td>%s</td>", displayName);
+ g_string_append_printf(result, "<td><input type=\"button\" value=\"Remove\" _onclick_=\"removeData('%"G_GUINT64_FORMAT":%u:%u');\"></td></tr>\n",
+ pageID, types, index);
+ }
+ g_string_append_printf(result, "<tr><td><input type=\"button\" value=\"Clear all\" _onclick_=\"clearData('%"G_GUINT64_FORMAT":%u');\"></td></tr></table>\n",
+ pageID, types);
+}
+
+static void gotWebsiteDataCallback(WebKitWebsiteDataManager *manager, GAsyncResult *asyncResult, AboutDataRequest *dataRequest)
+{
+ GList *dataList = webkit_website_data_manager_fetch_finish(manager, asyncResult, NULL);
+
+ GString *result = g_string_new(
+ "<html><head>"
+ "<script>"
+ " function removeData(domain) {"
+ " window.webkit.messageHandlers.aboutData.postMessage(domain);"
+ " }"
+ " function clearData(dataType) {"
+ " window.webkit.messageHandlers.aboutData.postMessage(dataType);"
+ " }"
+ "</script></head><body>\n");
+
+ guint64 pageID = webkit_web_view_get_page_id(webkit_uri_scheme_request_get_web_view(dataRequest->request));
+ aboutDataFillTable(result, dataRequest, dataList, "Memory Cache", WEBKIT_WEBSITE_DATA_MEMORY_CACHE, NULL, pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "Disk Cache", WEBKIT_WEBSITE_DATA_DISK_CACHE, webkit_website_data_manager_get_disk_cache_directory(manager), pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "Session Storage", WEBKIT_WEBSITE_DATA_SESSION_STORAGE, NULL, pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "Local Storage", WEBKIT_WEBSITE_DATA_LOCAL_STORAGE, webkit_website_data_manager_get_local_storage_directory(manager), pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "WebSQL Databases", WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES, webkit_website_data_manager_get_websql_directory(manager), pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "IndexedDB Databases", WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES, webkit_website_data_manager_get_indexeddb_directory(manager), pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "Plugins Data", WEBKIT_WEBSITE_DATA_PLUGIN_DATA, NULL, pageID);
+ aboutDataFillTable(result, dataRequest, dataList, "Offline Web Applications Cache", WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, webkit_website_data_manager_get_offline_application_cache_directory(manager), pageID);
+
+ result = g_string_append(result, "</body></html>");
+ gsize streamLength = result->len;
+ GInputStream *stream = g_memory_input_stream_new_from_data(g_string_free(result, FALSE), streamLength, g_free);
+ webkit_uri_scheme_request_finish(dataRequest->request, stream, streamLength, "text/html");
+ g_list_free_full(dataList, (GDestroyNotify)webkit_website_data_unref);
+}
+
+static void aboutDataHandleRequest(WebKitURISchemeRequest *request)
+{
+ AboutDataRequest *dataRequest = aboutDataRequestNew(request);
+ WebKitWebsiteDataManager *manager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default());
+ webkit_website_data_manager_fetch(manager, WEBKIT_WEBSITE_DATA_ALL, NULL, (GAsyncReadyCallback)gotWebsiteDataCallback, dataRequest);
+}
+
static void aboutURISchemeRequestCallback(WebKitURISchemeRequest *request, gpointer userData)
{
GInputStream *stream;
@@ -244,7 +433,9 @@
webkit_uri_scheme_request_finish(request, stream, streamLength, "text/html");
g_object_unref(stream);
- } else {
+ } else if (!g_strcmp0(path, "data"))
+ aboutDataHandleRequest(request);
+ else {
error = g_error_new(MINI_BROWSER_ERROR, MINI_BROWSER_ERROR_INVALID_ABOUT_PATH, "Invalid about:%s page.", path);
webkit_uri_scheme_request_finish_error(request, error);
g_error_free(error);
@@ -288,6 +479,10 @@
webkit_web_context_register_uri_scheme(webkit_web_context_get_default(), BROWSER_ABOUT_SCHEME, aboutURISchemeRequestCallback, NULL, NULL);
+ WebKitUserContentManager *userContentManager = webkit_user_content_manager_new();
+ webkit_user_content_manager_register_script_message_handler(userContentManager, "aboutData");
+ g_signal_connect(userContentManager, "script-message-received::aboutData", G_CALLBACK(aboutDataScriptMessageReceivedCallback), NULL);
+
BrowserWindow *mainWindow = BROWSER_WINDOW(browser_window_new(NULL));
if (geometry)
gtk_window_parse_geometry(GTK_WINDOW(mainWindow), geometry);
@@ -297,7 +492,7 @@
int i;
for (i = 0; uriArguments[i]; i++) {
- WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings);
+ WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager);
if (!i)
firstTab = GTK_WIDGET(webView);
gchar *url = ""
@@ -305,7 +500,7 @@
g_free(url);
}
} else {
- WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings);
+ WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings, userContentManager);
firstTab = GTK_WIDGET(webView);
if (backgroundColor)
@@ -323,6 +518,7 @@
gtk_widget_show(GTK_WIDGET(mainWindow));
g_clear_object(&webkitSettings);
+ g_clear_object(&userContentManager);
gtk_main();
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt (211078 => 211079)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt 2017-01-24 07:48:40 UTC (rev 211079)
@@ -125,6 +125,7 @@
ADD_WK2_TEST(TestWebKitWebContext TestWebKitWebContext.cpp)
ADD_WK2_TEST(TestWebKitWebView TestWebKitWebView.cpp)
ADD_WK2_TEST(TestWebKitUserContentManager TestWebKitUserContentManager.cpp)
+ADD_WK2_TEST(TestWebsiteData TestWebsiteData.cpp)
ADD_WK2_TEST(TestEditor TestEditor.cpp)
ADD_WK2_TEST(TestConsoleMessage TestConsoleMessage.cpp)
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp (211078 => 211079)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp 2017-01-24 06:52:49 UTC (rev 211078)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebKitWebContext.cpp 2017-01-24 07:48:40 UTC (rev 211079)
@@ -40,88 +40,6 @@
g_assert(webkit_web_context_get_default() != test->m_webContext.get());
}
-static void testWebContextConfiguration(WebViewTest* test, gconstpointer)
-{
- WebKitWebsiteDataManager* manager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
- g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
- test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(manager));
-
- // Base directories are not used by TestMain.
- g_assert(!webkit_website_data_manager_get_base_data_directory(manager));
- g_assert(!webkit_website_data_manager_get_base_cache_directory(manager));
-
- GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "local-storage", nullptr));
- g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(manager));
- g_assert(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR));
-
- test->loadURI(kServer->getURIForPath("/empty").data());
- test->waitUntilLoadFinished();
- test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr);
- GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "indexeddb", nullptr));
- g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(manager));
- g_assert(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR));
-
- test->loadURI(kServer->getURIForPath("/appcache").data());
- test->waitUntilLoadFinished();
- GUniquePtr<char> applicationCacheDirectory(g_build_filename(Test::dataDirectory(), "appcache", nullptr));
- g_assert_cmpstr(applicationCacheDirectory.get(), ==, webkit_website_data_manager_get_offline_application_cache_directory(manager));
- GUniquePtr<char> applicationCacheDatabase(g_build_filename(applicationCacheDirectory.get(), "ApplicationCache.db", nullptr));
- unsigned triesCount = 4;
- while (!g_file_test(applicationCacheDatabase.get(), G_FILE_TEST_IS_REGULAR) && --triesCount)
- test->wait(0.25);
- g_assert(triesCount);
-
-
- GUniquePtr<char> webSQLDirectory(g_build_filename(Test::dataDirectory(), "websql", nullptr));
- g_assert_cmpstr(webSQLDirectory.get(), ==, webkit_website_data_manager_get_websql_directory(manager));
- test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr);
- g_assert(g_file_test(webSQLDirectory.get(), G_FILE_TEST_IS_DIR));
-
- GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), "disk-cache", nullptr));
- g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(manager));
- g_assert(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR));
-
- // The default context should have a different manager with different configuration.
- WebKitWebsiteDataManager* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default());
- g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager));
- g_assert(manager != defaultManager);
- g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager));
- g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager));
- g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager));
- g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager));
- g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(manager), !=, webkit_website_data_manager_get_websql_directory(defaultManager));
-
- // Using Test::dataDirectory() we get the default configuration but for a differrent prefix.
- GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), nullptr));
- g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get()));
-
- localStorageDirectory.reset(g_build_filename(Test::dataDirectory(), "localstorage", nullptr));
- g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
-
- indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", "indexeddb", nullptr));
- g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
-
- applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "applications", nullptr));
- g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
-
- webSQLDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", nullptr));
- g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
-
- g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
-
- // Any specific configuration provided takes precedence over base dirs.
- indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb", nullptr));
- applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomappcache", nullptr));
- baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(),
- "indexeddb-directory", indexedDBDirectory.get(), "offline-application-cache-directory", applicationCacheDirectory.get(), nullptr));
- g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
- g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
- // The resutl should be the same as previous manager.
- g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
- g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
- g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
-}
-
class PluginsTest: public Test {
public:
MAKE_GLIB_TEST_FIXTURE(PluginsTest);
@@ -536,20 +454,6 @@
soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML));
soup_message_body_complete(message->response_body);
soup_message_set_status(message, SOUP_STATUS_OK);
- } else if (g_str_equal(path, "/appcache")) {
- const char* appcacheHTML = "<html manifest=appcache.manifest><body></body></html>";
- soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheHTML, strlen(appcacheHTML));
- soup_message_body_complete(message->response_body);
- soup_message_set_status(message, SOUP_STATUS_OK);
- } else if (g_str_equal(path, "/appcache.manifest")) {
- const char* appcacheManifest = "CACHE MANIFEST\nCACHE:\nappcache/foo.txt\n";
- soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheManifest, strlen(appcacheManifest));
- soup_message_body_complete(message->response_body);
- soup_message_set_status(message, SOUP_STATUS_OK);
- } else if (g_str_equal(path, "/appcache/foo.txt")) {
- soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo", 3);
- soup_message_body_complete(message->response_body);
- soup_message_set_status(message, SOUP_STATUS_OK);
} else if (g_str_equal(path, "/echoPort")) {
char* port = g_strdup_printf("%u", soup_server_get_port(server));
soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, port, strlen(port));
@@ -795,7 +699,6 @@
kServer->run(serverCallback);
Test::add("WebKitWebContext", "default-context", testWebContextDefault);
- WebViewTest::add("WebKitWebContext", "configuration", testWebContextConfiguration);
PluginsTest::add("WebKitWebContext", "get-plugins", testWebContextGetPlugins);
URISchemeTest::add("WebKitWebContext", "uri-scheme", testWebContextURIScheme);
Test::add("WebKitWebContext", "spell-checker", testWebContextSpellChecker);
Added: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebsiteData.cpp (0 => 211079)
--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebsiteData.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebsiteData.cpp 2017-01-24 07:48:40 UTC (rev 211079)
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2017 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 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 "WebKitTestServer.h"
+#include "WebViewTest.h"
+
+static WebKitTestServer* kServer;
+
+static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
+{
+ if (message->method != SOUP_METHOD_GET) {
+ soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ if (g_str_equal(path, "/empty")) {
+ const char* emptyHTML = "<html><body></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML));
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else if (g_str_equal(path, "/appcache")) {
+ const char* appcacheHTML = "<html manifest=appcache.manifest><body></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheHTML, strlen(appcacheHTML));
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else if (g_str_equal(path, "/appcache.manifest")) {
+ const char* appcacheManifest = "CACHE MANIFEST\nCACHE:\nappcache/foo.txt\n";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheManifest, strlen(appcacheManifest));
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else if (g_str_equal(path, "/appcache/foo.txt")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo", 3);
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else if (g_str_equal(path, "/sessionstorage")) {
+ const char* sessionStorageHTML = "<html><body _onload_=\"sessionStorage.foo = 'bar';\"></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, sessionStorageHTML, strlen(sessionStorageHTML));
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else if (g_str_equal(path, "/localstorage")) {
+ const char* localStorageHTML = "<html><body _onload_=\"localStorage.foo = 'bar';\"></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, localStorageHTML, strlen(localStorageHTML));
+ soup_message_body_complete(message->response_body);
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ } else
+ soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
+}
+
+class WebsiteDataTest : public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(WebsiteDataTest);
+
+
+ WebsiteDataTest()
+ : m_manager(webkit_web_context_get_website_data_manager(webkit_web_view_get_context(m_webView)))
+ {
+ g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(m_manager));
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_manager));
+ // WebsiteDataStore creates a new WebProcessPool when used before any secondary process has been created.
+ // Ensure we have a web process by always loading about:blank here.
+ loadURI("about:blank");
+ waitUntilLoadFinished();
+ }
+
+ ~WebsiteDataTest()
+ {
+ g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
+ }
+
+ GList* fetch(WebKitWebsiteDataTypes types)
+ {
+ if (m_dataList) {
+ g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
+ m_dataList = nullptr;
+ }
+ webkit_website_data_manager_fetch(m_manager, types, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
+ WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
+ test->m_dataList = webkit_website_data_manager_fetch_finish(test->m_manager, result, nullptr);
+ test->quitMainLoop();
+ }, this);
+ g_main_loop_run(m_mainLoop);
+ return m_dataList;
+ }
+
+ void remove(WebKitWebsiteDataTypes types, GList* dataList)
+ {
+ webkit_website_data_manager_remove(m_manager, types, dataList, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
+ WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
+ g_assert(webkit_website_data_manager_remove_finish(test->m_manager, result, nullptr));
+ test->quitMainLoop();
+ }, this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ void clear(WebKitWebsiteDataTypes types, GTimeSpan timeSpan)
+ {
+ webkit_website_data_manager_clear(m_manager, types, timeSpan, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
+ WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
+ g_assert(webkit_website_data_manager_clear_finish(test->m_manager, result, nullptr));
+ test->quitMainLoop();
+ }, this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ WebKitWebsiteDataManager* m_manager;
+ GList* m_dataList { nullptr };
+};
+
+static void testWebsiteDataConfiguration(WebsiteDataTest* test, gconstpointer)
+{
+ // Base directories are not used by TestMain.
+ g_assert(!webkit_website_data_manager_get_base_data_directory(test->m_manager));
+ g_assert(!webkit_website_data_manager_get_base_cache_directory(test->m_manager));
+
+ GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "local-storage", nullptr));
+ g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(test->m_manager));
+ g_assert(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR));
+
+ test->loadURI(kServer->getURIForPath("/empty").data());
+ test->waitUntilLoadFinished();
+ test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr);
+ GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "indexeddb", nullptr));
+ g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(test->m_manager));
+ g_assert(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR));
+
+ GUniquePtr<char> webSQLDirectory(g_build_filename(Test::dataDirectory(), "websql", nullptr));
+ g_assert_cmpstr(webSQLDirectory.get(), ==, webkit_website_data_manager_get_websql_directory(test->m_manager));
+ test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr);
+ g_assert(g_file_test(webSQLDirectory.get(), G_FILE_TEST_IS_DIR));
+
+ test->loadURI(kServer->getURIForPath("/appcache").data());
+ test->waitUntilLoadFinished();
+ GUniquePtr<char> applicationCacheDirectory(g_build_filename(Test::dataDirectory(), "appcache", nullptr));
+ g_assert_cmpstr(applicationCacheDirectory.get(), ==, webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager));
+ GUniquePtr<char> applicationCacheDatabase(g_build_filename(applicationCacheDirectory.get(), "ApplicationCache.db", nullptr));
+ unsigned triesCount = 4;
+ while (!g_file_test(applicationCacheDatabase.get(), G_FILE_TEST_IS_REGULAR) && --triesCount)
+ test->wait(0.25);
+ g_assert(triesCount);
+
+ GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), "disk-cache", nullptr));
+ g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(test->m_manager));
+ g_assert(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR));
+
+ // Clear all persistent caches, since the data dir is common to all test cases.
+ static const WebKitWebsiteDataTypes persistentCaches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DISK_CACHE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE
+ | WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES | WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
+ test->clear(persistentCaches, 0);
+ g_assert(!test->fetch(persistentCaches));
+
+ // The default context should have a different manager with different configuration.
+ WebKitWebsiteDataManager* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default());
+ g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager));
+ g_assert(test->m_manager != defaultManager);
+ g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(test->m_manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager));
+ g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(test->m_manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager));
+ g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager));
+ g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager));
+ g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(test->m_manager), !=, webkit_website_data_manager_get_websql_directory(defaultManager));
+
+ // Using Test::dataDirectory() we get the default configuration but for a differrent prefix.
+ GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), nullptr));
+ g_assert(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get()));
+
+ localStorageDirectory.reset(g_build_filename(Test::dataDirectory(), "localstorage", nullptr));
+ g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
+
+ indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", "indexeddb", nullptr));
+ g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
+
+ applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "applications", nullptr));
+ g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
+
+ webSQLDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", nullptr));
+ g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
+
+ g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
+
+ // Any specific configuration provided takes precedence over base dirs.
+ indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb", nullptr));
+ applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomappcache", nullptr));
+ baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(),
+ "indexeddb-directory", indexedDBDirectory.get(), "offline-application-cache-directory", applicationCacheDirectory.get(), nullptr));
+ g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
+ g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
+ // The result should be the same as previous manager.
+ g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
+ g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
+ g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
+}
+
+static void testWebsiteDataCache(WebsiteDataTest* test, gconstpointer)
+{
+ static const WebKitWebsiteDataTypes cacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ GList* dataList = test->fetch(cacheTypes);
+ g_assert(!dataList);
+
+ test->loadURI(kServer->getURIForPath("/empty").data());
+ test->waitUntilLoadFinished();
+
+ // Disk cache delays the storing of initial resources for 1 second to avoid
+ // affecting early page load. So, wait 1 second here to make sure resources
+ // have already been stored.
+ test->wait(1);
+
+ dataList = test->fetch(cacheTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ WebKitWebsiteData* data = ""
+ g_assert(data);
+ WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
+ g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
+ webkit_security_origin_unref(origin);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheTypes);
+ // Memory cache size is unknown.
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_MEMORY_CACHE), ==, 0);
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_DISK_CACHE), >, 0);
+
+ // Try again but only getting disk cache.
+ dataList = test->fetch(WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(data);
+ g_assert(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ g_assert(!(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE));
+
+ GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html", Test::getResourcesDir(Test::WebKit2Resources).data()));
+ test->loadURI(fileURL.get());
+ test->waitUntilLoadFinished();
+
+ fileURL.reset(g_strdup_printf("file://%s/simple2.html", Test::getResourcesDir(Test::WebKit2Resources).data()));
+ test->loadURI(fileURL.get());
+ test->waitUntilLoadFinished();
+
+ // Local files are grouped.
+ dataList = test->fetch(cacheTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 2);
+ GList* itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int {
+ WebKitWebsiteData* data = ""
+ return g_strcmp0(webkit_website_data_get_name(data), "Local files");
+ });
+ g_assert(itemList);
+ data = ""
+ g_assert(data);
+ g_assert(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE);
+ // Local files are never stored in disk cache.
+ g_assert(!(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE));
+
+ // Clear data modified since the last microsecond should not clear anything.
+ // Use disk-cache because memory cache ignores the modified since.
+ test->clear(WEBKIT_WEBSITE_DATA_DISK_CACHE, 1);
+ dataList = test->fetch(cacheTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 2);
+
+ // Remove memory cache only for local files.
+ itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int {
+ WebKitWebsiteData* data = ""
+ return g_strcmp0(webkit_website_data_get_name(data), "Local files");
+ });
+ g_assert(itemList);
+ GList removeList = { itemList->data, nullptr, nullptr };
+ test->remove(WEBKIT_WEBSITE_DATA_MEMORY_CACHE, &removeList);
+ dataList = test->fetch(cacheTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE);
+
+ // Clear all.
+ test->clear(cacheTypes, 0);
+ dataList = test->fetch(cacheTypes);
+ g_assert(!dataList);
+}
+
+static void testWebsiteDataStorage(WebsiteDataTest* test, gconstpointer)
+{
+ static const WebKitWebsiteDataTypes storageTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_SESSION_STORAGE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE);
+ GList* dataList = test->fetch(storageTypes);
+ g_assert(!dataList);
+
+ test->loadURI(kServer->getURIForPath("/sessionstorage").data());
+ test->waitUntilLoadFinished();
+
+ test->loadURI(kServer->getURIForPath("/localstorage").data());
+ test->waitUntilLoadFinished();
+
+ // Local storage uses a 1 second timer to update the database.
+ test->wait(1);
+
+ dataList = test->fetch(storageTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ WebKitWebsiteData* data = ""
+ g_assert(data);
+ WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
+ g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
+ webkit_security_origin_unref(origin);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes);
+ // Storage sizes are unknown.
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_SESSION_STORAGE), ==, 0);
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_LOCAL_STORAGE), ==, 0);
+
+ // Get also cached data, and clear it.
+ static const WebKitWebsiteDataTypes cacheAndStorageTypes = static_cast<WebKitWebsiteDataTypes>(storageTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ dataList = test->fetch(cacheAndStorageTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(data);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheAndStorageTypes);
+ test->clear(static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE), 0);
+
+ // Get all types again, but only storage is retrieved now.
+ dataList = test->fetch(cacheAndStorageTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(data);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes);
+
+ // Remove the session storage.
+ GList removeList = { data, nullptr, nullptr };
+ test->remove(WEBKIT_WEBSITE_DATA_SESSION_STORAGE, &removeList);
+ dataList = test->fetch(storageTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(!(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_SESSION_STORAGE));
+ g_assert(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE);
+
+ // Clear all.
+ test->clear(cacheAndStorageTypes, 0);
+ dataList = test->fetch(cacheAndStorageTypes);
+ g_assert(!dataList);
+}
+
+static void testWebsiteDataDatabases(WebsiteDataTest* test, gconstpointer)
+{
+ static const WebKitWebsiteDataTypes databaseTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES);
+ GList* dataList = test->fetch(databaseTypes);
+ g_assert(!dataList);
+
+ test->loadURI(kServer->getURIForPath("/empty").data());
+ test->waitUntilLoadFinished();
+ test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr);
+
+ dataList = test->fetch(databaseTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ WebKitWebsiteData* data = ""
+ g_assert(data);
+ WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
+ g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
+ webkit_security_origin_unref(origin);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES);
+ // Database sizes are unknown.
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0);
+
+ test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr);
+ dataList = test->fetch(databaseTypes);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ data = ""
+ g_assert(data);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, databaseTypes);
+ // Database sizes are unknown.
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0);
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES), ==, 0);
+
+ // Remove all databases at once.
+ GList removeList = { data, nullptr, nullptr };
+ test->remove(databaseTypes, &removeList);
+ dataList = test->fetch(databaseTypes);
+ g_assert(!dataList);
+
+ // Clear all.
+ static const WebKitWebsiteDataTypes cacheAndDatabaseTypes = static_cast<WebKitWebsiteDataTypes>(databaseTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ test->clear(cacheAndDatabaseTypes, 0);
+ dataList = test->fetch(cacheAndDatabaseTypes);
+ g_assert(!dataList);
+}
+
+static void testWebsiteDataAppcache(WebsiteDataTest* test, gconstpointer)
+{
+ GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
+ g_assert(!dataList);
+
+ test->loadURI(kServer->getURIForPath("/appcache").data());
+ test->waitUntilLoadFinished();
+
+ test->wait(1);
+ dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
+ g_assert(dataList);
+ g_assert_cmpuint(g_list_length(dataList), ==, 1);
+ WebKitWebsiteData* data = ""
+ g_assert(data);
+ WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
+ g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
+ webkit_security_origin_unref(origin);
+ g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
+ // Appcache size is unknown.
+ g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE), ==, 0);
+
+ GList removeList = { data, nullptr, nullptr };
+ test->remove(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, &removeList);
+ dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
+ g_assert(!dataList);
+
+ // Clear all.
+ static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
+ test->clear(cacheAndAppcacheTypes, 0);
+ dataList = test->fetch(cacheAndAppcacheTypes);
+ g_assert(!dataList);
+}
+
+void beforeAll()
+{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
+ WebsiteDataTest::add("WebKitWebsiteData", "configuration", testWebsiteDataConfiguration);
+ WebsiteDataTest::add("WebKitWebsiteData", "cache", testWebsiteDataCache);
+ WebsiteDataTest::add("WebKitWebsiteData", "storage", testWebsiteDataStorage);
+ WebsiteDataTest::add("WebKitWebsiteData", "databases", testWebsiteDataDatabases);
+ WebsiteDataTest::add("WebKitWebsiteData", "appcache", testWebsiteDataAppcache);
+}
+
+void afterAll()
+{
+ delete kServer;
+}