summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/gtk
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit2/UIProcess/API/gtk
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk')
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp262
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h104
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h28
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp14
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitError.h48
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp385
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h78
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h28
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp48
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h27
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp107
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h55
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h29
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp39
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp112
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h27
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp62
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp10
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp29
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h18
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp363
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h77
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h34
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp422
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h75
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp149
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h16
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml3
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt101
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types4
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am14
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp239
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp12
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h20
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp123
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp596
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp257
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp151
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h16
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/webkit2.h6
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list2
47 files changed, 4098 insertions, 121 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
index 9fadbeab5..8fbfe73f6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
@@ -39,7 +39,9 @@
#include "WebPageProxy.h"
#include "WebPopupMenuProxyGtk.h"
#include <WebCore/Cursor.h>
+#include <WebCore/EventNames.h>
#include <WebCore/GtkUtilities.h>
+#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
@@ -156,7 +158,7 @@ void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
notImplemented();
}
-void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportArguments&)
+void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&)
{
notImplemented();
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
index 6a1cb2459..54ad99f8f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
+++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
@@ -69,7 +69,7 @@ private:
virtual void toolTipChanged(const WTF::String&, const WTF::String&);
virtual void setCursor(const WebCore::Cursor&);
virtual void setCursorHiddenUntilMouseMoves(bool);
- virtual void didChangeViewportProperties(const WebCore::ViewportArguments&);
+ virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo);
virtual void clearAllEditCommands();
virtual bool canUndoRedo(WebPageProxy::UndoOrRedo);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
new file mode 100644
index 000000000..b993d2e83
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2012 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 "WebKitCookieManager.h"
+
+#include "WebKitCookieManagerPrivate.h"
+#include "WebKitEnumTypes.h"
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+enum {
+ CHANGED,
+
+ LAST_SIGNAL
+};
+
+struct _WebKitCookieManagerPrivate {
+ WKRetainPtr<WKCookieManagerRef> wkCookieManager;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT)
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, kWKHTTPCookieAcceptPolicyAlways);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, kWKHTTPCookieAcceptPolicyNever);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
+
+static void webkit_cookie_manager_init(WebKitCookieManager* manager)
+{
+ WebKitCookieManagerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(manager, WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerPrivate);
+ manager->priv = priv;
+ new (priv) WebKitCookieManagerPrivate();
+}
+
+static void webkitCookieManagerFinalize(GObject* object)
+{
+ WebKitCookieManagerPrivate* priv = WEBKIT_COOKIE_MANAGER(object)->priv;
+ WKCookieManagerStopObservingCookieChanges(priv->wkCookieManager.get());
+ priv->~WebKitCookieManagerPrivate();
+ G_OBJECT_CLASS(webkit_cookie_manager_parent_class)->finalize(object);
+}
+
+static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
+ gObjectClass->finalize = webkitCookieManagerFinalize;
+
+ g_type_class_add_private(findClass, sizeof(WebKitCookieManagerPrivate));
+
+ /**
+ * WebKitCookieManager::changed:
+ * @cookie_manager: the #WebKitCookieManager
+ *
+ * This signal is emitted when cookies are added, removed or modified.
+ */
+ signals[CHANGED] =
+ g_signal_new("changed",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void cookiesDidChange(WKCookieManagerRef, const void* clientInfo)
+{
+ g_signal_emit(WEBKIT_COOKIE_MANAGER(clientInfo), signals[CHANGED], 0);
+}
+
+WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef wkCookieManager)
+{
+ WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, NULL));
+ manager->priv->wkCookieManager = wkCookieManager;
+
+ WKCookieManagerClient wkCookieManagerClient = {
+ kWKCookieManagerClientCurrentVersion,
+ manager, // clientInfo
+ cookiesDidChange
+ };
+ WKCookieManagerSetClient(wkCookieManager, &wkCookieManagerClient);
+ WKCookieManagerStartObservingCookieChanges(wkCookieManager);
+
+ return manager;
+}
+
+/**
+ * webkit_cookie_manager_set_accept_policy:
+ * @cookie_manager: a #WebKitCookieManager
+ * @policy: a #WebKitCookieAcceptPolicy
+ *
+ * Set the cookie acceptance policy of @cookie_manager as @policy.
+ */
+void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKitCookieAcceptPolicy policy)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ WKCookieManagerSetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), policy);
+}
+
+static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy policy, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ g_simple_async_result_set_op_res_gpointer(result.get(), GUINT_TO_POINTER(policy), 0);
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_cookie_manager_get_accept_policy:
+ * @cookie_manager: a #WebKitCookieManager
+ * @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 cookie acceptance policy of @cookie_manager.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_get_accept_policy_finish() to get the result of the operation.
+ */
+void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
+ reinterpret_cast<gpointer>(webkit_cookie_manager_get_accept_policy));
+ WKCookieManagerGetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetAcceptPolicyCallback);
+}
+
+/**
+ * webkit_cookie_manager_get_accept_policy_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_get_accept_policy().
+ *
+ * Returns: the cookie acceptance policy of @cookie_manager as a #WebKitCookieAcceptPolicy.
+ */
+WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_accept_policy);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+
+ return static_cast<WebKitCookieAcceptPolicy>(GPOINTER_TO_UINT(g_simple_async_result_get_op_res_gpointer(simpleResult)));
+}
+
+static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomains, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ GPtrArray* domains = g_ptr_array_new_with_free_func(g_free);
+ for (size_t i = 0; i < WKArrayGetSize(wkDomains); ++i) {
+ WKStringRef wkDomain = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkDomains, i));
+ String domain = toImpl(wkDomain)->string();
+ if (domain.isEmpty())
+ continue;
+ g_ptr_array_add(domains, g_strdup(domain.utf8().data()));
+ }
+ g_ptr_array_add(domains, 0);
+ g_simple_async_result_set_op_res_gpointer(result.get(), domains, reinterpret_cast<GDestroyNotify>(g_ptr_array_unref));
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_cookie_manager_get_domains_with_cookies:
+ * @cookie_manager: a #WebKitCookieManager
+ * @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 domains for which @cookie_manager contains cookies.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_cookie_manager_get_domains_with_cookies_finish() to get the result of the operation.
+ */
+void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(manager), callback, userData,
+ reinterpret_cast<gpointer>(webkit_cookie_manager_get_domains_with_cookies));
+ WKCookieManagerGetHostnamesWithCookies(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetDomainsWithCookiesCallback);
+}
+
+/**
+ * webkit_cookie_manager_get_domains_with_cookies_finish:
+ * @cookie_manager: a #WebKitCookieManager
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_cookie_manager_get_domains_with_cookies().
+ * The return value is a %NULL terminated list of strings which should
+ * be released with g_strfreev().
+ *
+ * Returns: (transfer full) (array zero-terminated=1): A %NULL terminated array of domain names
+ * or %NULL in case of error.
+ */
+gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_cookie_manager_get_domains_with_cookies);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return 0;
+
+ GPtrArray* domains = static_cast<GPtrArray*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return reinterpret_cast<char**>(g_ptr_array_free(domains, FALSE));
+}
+
+/**
+ * webkit_cookie_manager_delete_cookies_for_domain:
+ * @cookie_manager: a #WebKitCookieManager
+ * @domain: a domain name
+ *
+ * Remove all cookies of @cookie_manager for the given @domain.
+ */
+void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manager, const gchar* domain)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+ g_return_if_fail(domain);
+
+ WKRetainPtr<WKStringRef> wkDomain(AdoptWK, WKStringCreateWithUTF8CString(domain));
+ WKCookieManagerDeleteCookiesForHostname(manager->priv->wkCookieManager.get(), wkDomain.get());
+}
+
+/**
+ * webkit_cookie_manager_delete_all_cookies:
+ * @cookie_manager: a #WebKitCookieManager
+ *
+ * Delete all cookies of @cookie_manager
+ */
+void webkit_cookie_manager_delete_all_cookies(WebKitCookieManager* manager)
+{
+ g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager));
+
+ WKCookieManagerDeleteAllCookies(manager->priv->wkCookieManager.get());
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
new file mode 100644
index 000000000..791a61d82
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitCookieManager_h
+#define WebKitCookieManager_h
+
+#include <gio/gio.h>
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_COOKIE_MANAGER (webkit_cookie_manager_get_type())
+#define WEBKIT_COOKIE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManager))
+#define WEBKIT_IS_COOKIE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_COOKIE_MANAGER))
+#define WEBKIT_COOKIE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerClass))
+#define WEBKIT_IS_COOKIE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_COOKIE_MANAGER))
+#define WEBKIT_COOKIE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_COOKIE_MANAGER, WebKitCookieManagerClass))
+
+typedef struct _WebKitCookieManager WebKitCookieManager;
+typedef struct _WebKitCookieManagerClass WebKitCookieManagerClass;
+typedef struct _WebKitCookieManagerPrivate WebKitCookieManagerPrivate;
+
+/**
+ * WebKitCookieAcceptPolicy:
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS: Accept all cookies unconditionally.
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_NEVER: Reject all cookies unconditionally.
+ * @WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY: Accept only cookies set by the main document loaded.
+ *
+ * Enum values used to denote the cookie acceptance policies.
+ */
+typedef enum {
+ WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS,
+ WEBKIT_COOKIE_POLICY_ACCEPT_NEVER,
+ WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY
+} WebKitCookieAcceptPolicy;
+
+struct _WebKitCookieManager {
+ GObject parent;
+
+ WebKitCookieManagerPrivate *priv;
+};
+
+struct _WebKitCookieManagerClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_cookie_manager_get_type (void);
+
+WEBKIT_API void
+webkit_cookie_manager_set_accept_policy (WebKitCookieManager *cookie_manager,
+ WebKitCookieAcceptPolicy policy);
+
+WEBKIT_API void
+webkit_cookie_manager_get_accept_policy (WebKitCookieManager *cookie_manager,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API WebKitCookieAcceptPolicy
+webkit_cookie_manager_get_accept_policy_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API gchar **
+webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager *cookie_manager,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_cookies_for_domain (WebKitCookieManager *cookie_manager,
+ const gchar *domain);
+
+WEBKIT_API void
+webkit_cookie_manager_delete_all_cookies (WebKitCookieManager *cookie_manager);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h
new file mode 100644
index 000000000..a387af907
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitCookieManagerPrivate_h
+#define WebKitCookieManagerPrivate_h
+
+#include "WebKitCookieManager.h"
+#include "WebKitPrivate.h"
+
+WebKitCookieManager* webkitCookieManagerCreate(WKCookieManagerRef);
+
+#endif // WebKitCookieManagerPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
index 42cf0ab35..daf09ecc2 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp
@@ -68,3 +68,17 @@ GQuark webkit_download_error_quark()
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_NETWORK, DownloadErrorNetwork);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, DownloadErrorCancelledByUser);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_DESTINATION, DownloadErrorDestination);
+
+GQuark webkit_print_error_quark()
+{
+ return g_quark_from_static_string(WebCore::errorDomainPrint);
+}
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange);
+
+GQuark webkit_javascript_error_quark()
+{
+ return g_quark_from_static_string("WebKitJavascriptError");
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
index 9b0e630c8..c20581683 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h
@@ -29,10 +29,12 @@
G_BEGIN_DECLS
-#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
-#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
-#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
-#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
+#define WEBKIT_POLICY_ERROR webkit_policy_error_quark ()
+#define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark ()
+#define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_PRINT_ERROR webkit_print_error_quark ()
+#define WEBKIT_JAVASCRIPT_ERROR webkit_print_error_quark ()
/**
* WebKitNetworkError:
@@ -104,17 +106,47 @@ typedef enum {
WEBKIT_DOWNLOAD_ERROR_DESTINATION = 401
} WebKitDownloadError;
+/**
+ * WebKitPrintError:
+ * @WEBKIT_PRINT_ERROR_GENERAL: Unspecified error during a print operation
+ * @WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND: Selected printer cannot be found
+ * @WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE: Invalid page range
+ *
+ * Enum values used to denote the various print errors.
+ */
+typedef enum {
+ WEBKIT_PRINT_ERROR_GENERAL = 599,
+ WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND = 500,
+ WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE = 501
+} WebKitPrintError;
+
+/**
+ * WebKitJavascriptError:
+ * @WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED: An exception was raised in Javascript execution
+ *
+ * Enum values used to denote errors happending when executing Javascript
+ */
+typedef enum {
+ WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED = 699
+} WebKitJavascriptError;
+
+WEBKIT_API GQuark
+webkit_network_error_quark (void);
+
+WEBKIT_API GQuark
+webkit_policy_error_quark (void);
+
WEBKIT_API GQuark
-webkit_network_error_quark (void);
+webkit_plugin_error_quark (void);
WEBKIT_API GQuark
-webkit_policy_error_quark (void);
+webkit_download_error_quark (void);
WEBKIT_API GQuark
-webkit_plugin_error_quark (void);
+webkit_print_error_quark (void);
WEBKIT_API GQuark
-webkit_download_error_quark (void);
+webkit_javascript_error_quark (void);
G_END_DECLS
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp
new file mode 100644
index 000000000..96b87a3ba
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2012 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 "WebKitFileChooserRequest.h"
+
+#include "WebKitFileChooserRequestPrivate.h"
+#include "WebOpenPanelParameters.h"
+#include <WebCore/FileSystem.h>
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitFileChooserRequest
+ * @Short_description: A request to open a file chooser
+ * @Title: WebKitFileChooserRequest
+ * @See_also: #WebKitWebView
+ *
+ * Whenever the user interacts with an &lt;input type='file' /&gt;
+ * HTML element, WebKit will need to show a dialog to choose one or
+ * more files to be uploaded to the server along with the rest of the
+ * form data. For that to happen in a general way, instead of just
+ * opening a #GtkFileChooserDialog (which might be not desirable in
+ * some cases, which could prefer to use their own file chooser
+ * dialog), WebKit will fire the #WebKitWebView::run-file-chooser
+ * signal with a #WebKitFileChooserRequest object, which will allow
+ * the client application to specify the files to be selected, to
+ * inspect the details of the request (e.g. if multiple selection
+ * should be allowed) and to cancel the request, in case nothing was
+ * selected.
+ *
+ * In case the client application does not wish to handle this signal,
+ * WebKit will provide a default handler which will asynchronously run
+ * a regular #GtkFileChooserDialog for the user to interact with.
+ */
+G_DEFINE_TYPE(WebKitFileChooserRequest, webkit_file_chooser_request, G_TYPE_OBJECT)
+
+struct _WebKitFileChooserRequestPrivate {
+ WKRetainPtr<WKOpenPanelParametersRef> wkParameters;
+ WKRetainPtr<WKOpenPanelResultListenerRef> wkListener;
+ GRefPtr<GtkFileFilter> filter;
+ GRefPtr<GPtrArray> mimeTypes;
+ GRefPtr<GPtrArray> selectedFiles;
+ bool handledRequest;
+};
+
+enum {
+ PROP_0,
+ PROP_FILTER,
+ PROP_MIME_TYPES,
+ PROP_SELECT_MULTIPLE,
+ PROP_SELECTED_FILES,
+};
+
+static void webkit_file_chooser_request_init(WebKitFileChooserRequest* request)
+{
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestPrivate);
+ new (request->priv) WebKitFileChooserRequestPrivate();
+}
+
+static void webkitFileChooserRequestFinalize(GObject* object)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+
+ // Make sure the request is always handled before finalizing.
+ if (!request->priv->handledRequest)
+ webkit_file_chooser_request_cancel(request);
+
+ request->priv->~WebKitFileChooserRequestPrivate();
+ G_OBJECT_CLASS(webkit_file_chooser_request_parent_class)->finalize(object);
+}
+
+static void webkitFileChooserRequestGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+ switch (propId) {
+ case PROP_FILTER:
+ g_value_set_object(value, webkit_file_chooser_request_get_mime_types_filter(request));
+ break;
+ case PROP_MIME_TYPES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_mime_types(request));
+ break;
+ case PROP_SELECT_MULTIPLE:
+ g_value_set_boolean(value, webkit_file_chooser_request_get_select_multiple(request));
+ break;
+ case PROP_SELECTED_FILES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_selected_files(request));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ break;
+ }
+}
+
+static void webkit_file_chooser_request_class_init(WebKitFileChooserRequestClass* requestClass)
+{
+ GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
+ objectClass->finalize = webkitFileChooserRequestFinalize;
+ objectClass->get_property = webkitFileChooserRequestGetProperty;
+ g_type_class_add_private(requestClass, sizeof(WebKitFileChooserRequestPrivate));
+
+ /**
+ * WebKitFileChooserRequest:filter:
+ *
+ * The filter currently associated with the request. See
+ * webkit_file_chooser_request_get_mime_types_filter() for more
+ * details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_FILTER,
+ g_param_spec_object("filter",
+ _("MIME types filter"),
+ _("The filter currently associated with the request"),
+ GTK_TYPE_FILE_FILTER,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:mime-types:
+ *
+ * A %NULL-terminated array of strings containing the list of MIME
+ * types the file chooser dialog should handle. See
+ * webkit_file_chooser_request_get_mime_types() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_MIME_TYPES,
+ g_param_spec_boxed("mime-types",
+ _("MIME types"),
+ _("The list of MIME types associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:select-multiple:
+ *
+ * Whether the file chooser should allow selecting multiple
+ * files. See
+ * webkit_file_chooser_request_get_select_multiple() for
+ * more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECT_MULTIPLE,
+ g_param_spec_boolean("select-multiple",
+ _("Select multiple files"),
+ _("Whether the file chooser should allow selecting multiple files"),
+ FALSE,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:selected-files:
+ *
+ * A %NULL-terminated array of strings containing the list of
+ * selected files associated to the current request. See
+ * webkit_file_chooser_request_get_selected_files() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECTED_FILES,
+ g_param_spec_boxed("selected-files",
+ _("Selected files"),
+ _("The list of selected files associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE));
+}
+
+WebKitFileChooserRequest* webkitFileChooserRequestCreate(WKOpenPanelParametersRef wkParameters, WKOpenPanelResultListenerRef wkListener)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(g_object_new(WEBKIT_TYPE_FILE_CHOOSER_REQUEST, NULL));
+ request->priv->wkParameters = wkParameters;
+ request->priv->wkListener = wkListener;
+ return request;
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of MIME types the file chooser dialog should handle,
+ * in the format specified in RFC 2046 for "media types". Its contents
+ * depend on the value of the 'accept' attribute for HTML input
+ * elements. This function should normally be called before presenting
+ * the file chooser dialog to the user, to decide whether to allow the
+ * user to select multiple files at once or only one.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if a list of accepted MIME types
+ * is defined or %NULL otherwise, meaning that any MIME type should be
+ * accepted. This array and its contents are owned by WebKitGTK+ and
+ * should not be modified or freed.
+ */
+const gchar* const* webkit_file_chooser_request_get_mime_types(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->mimeTypes)
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+
+ WKRetainPtr<WKArrayRef> wkMimeTypes(AdoptWK, WKOpenPanelParametersCopyAcceptedMIMETypes(request->priv->wkParameters.get()));
+ size_t numOfMimeTypes = WKArrayGetSize(wkMimeTypes.get());
+ if (!numOfMimeTypes)
+ return 0;
+
+ request->priv->mimeTypes = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ WKStringRef wkMimeType = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkMimeTypes.get(), i));
+ String mimeTypeString = toImpl(wkMimeType)->string();
+ if (mimeTypeString.isEmpty())
+ continue;
+ g_ptr_array_add(request->priv->mimeTypes.get(), g_strdup(mimeTypeString.utf8().data()));
+ }
+ g_ptr_array_add(request->priv->mimeTypes.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types_filter:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the filter currently associated with the request, ready to be
+ * used by #GtkFileChooser. This function should normally be called
+ * before presenting the file chooser dialog to the user, to decide
+ * whether to apply a filter so the user would not be allowed to
+ * select files with other MIME types.
+ *
+ * See webkit_file_chooser_request_get_mime_types() if you are
+ * interested in getting the list of accepted MIME types.
+ *
+ * Returns: (transfer none): a #GtkFileFilter if a list of accepted
+ * MIME types is defined or %NULL otherwise. The returned object is
+ * owned by WebKitGTK+ should not be modified or freed.
+ */
+GtkFileFilter* webkit_file_chooser_request_get_mime_types_filter(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->filter)
+ return request->priv->filter.get();
+
+ WKRetainPtr<WKArrayRef> wkMimeTypes(AdoptWK, WKOpenPanelParametersCopyAcceptedMIMETypes(request->priv->wkParameters.get()));
+ size_t numOfMimeTypes = WKArrayGetSize(wkMimeTypes.get());
+ if (!numOfMimeTypes)
+ return 0;
+
+ // Do not use adoptGRef here, since we want to sink the floating
+ // reference for the new instance of GtkFileFilter, so we make
+ // sure we keep the ownership during the lifetime of the request.
+ request->priv->filter = gtk_file_filter_new();
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ WKStringRef wkMimeType = static_cast<WKStringRef>(WKArrayGetItemAtIndex(wkMimeTypes.get(), i));
+ String mimeTypeString = toImpl(wkMimeType)->string();
+ if (mimeTypeString.isEmpty())
+ continue;
+ gtk_file_filter_add_mime_type(request->priv->filter.get(), mimeTypeString.utf8().data());
+ }
+
+ return request->priv->filter.get();
+}
+
+/**
+ * webkit_file_chooser_request_get_select_multiple:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Determine whether the file chooser associated to this
+ * #WebKitFileChooserRequest should allow selecting multiple files,
+ * which depends on the HTML input element having a 'multiple'
+ * attribute defined.
+ *
+ * Returns: %TRUE if the file chooser should allow selecting multiple files or %FALSE otherwise.
+ */
+gboolean webkit_file_chooser_request_get_select_multiple(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), FALSE);
+ return WKOpenPanelParametersGetAllowsMultipleFiles(request->priv->wkParameters.get());
+}
+
+/**
+ * webkit_file_chooser_request_select_files:
+ * @request: a #WebKitFileChooserRequest
+ * @files: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings, containing paths to local files.
+ *
+ * Ask WebKit to select local files for upload and complete the
+ * request.
+ */
+void webkit_file_chooser_request_select_files(WebKitFileChooserRequest* request, const gchar* const* files)
+{
+ g_return_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request));
+ g_return_if_fail(files);
+
+ GRefPtr<GPtrArray> selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ WKRetainPtr<WKMutableArrayRef> wkChosenFiles(AdoptWK, WKMutableArrayCreate());
+ for (int i = 0; files[i]; i++) {
+ GRefPtr<GFile> filename = adoptGRef(g_file_new_for_path(files[i]));
+
+ // Make sure the file path is presented as an URI (escaped
+ // string, with the 'file://' prefix) to WebCore otherwise the
+ // FileChooser won't actually choose it.
+ GOwnPtr<char> uri(g_file_get_uri(filename.get()));
+ WKRetainPtr<WKURLRef> wkURL(AdoptWK, WKURLCreateWithUTF8CString(uri.get()));
+ WKArrayAppendItem(wkChosenFiles.get(), wkURL.get());
+
+ // Do not use the URI here because this won't reach WebCore.
+ g_ptr_array_add(selectedFiles.get(), g_strdup(files[i]));
+ }
+ g_ptr_array_add(selectedFiles.get(), 0);
+
+ // Select the files in WebCore and update local private attributes.
+ WKOpenPanelResultListenerChooseFiles(request->priv->wkListener.get(), wkChosenFiles.get());
+ request->priv->selectedFiles = selectedFiles;
+ request->priv->handledRequest = true;
+}
+
+/**
+ * webkit_file_chooser_request_get_selected_files:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of selected files currently associated to the
+ * request. Initially, the return value of this method contains any
+ * files selected in previous file chooser requests for this HTML
+ * input element. Once webkit_file_chooser_request_select_files, the
+ * value will reflect whatever files are given.
+ *
+ * This function should normally be called only before presenting the
+ * file chooser dialog to the user, to decide whether to perform some
+ * extra action, like pre-selecting the files from a previous request.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if there are selected files
+ * associated with the request or %NULL otherwise. This array and its
+ * contents are owned by WebKitGTK+ and should not be modified or
+ * freed.
+ */
+const gchar* const* webkit_file_chooser_request_get_selected_files(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->selectedFiles)
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+
+ const Vector<String> selectedFileNames = toImpl(request->priv->wkParameters.get())->selectedFileNames();
+ size_t numOfFiles = selectedFileNames.size();
+ if (!numOfFiles)
+ return 0;
+
+ request->priv->selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfFiles; ++i) {
+ if (selectedFileNames[i].isEmpty())
+ continue;
+ CString filename = fileSystemRepresentation(selectedFileNames[i]);
+ g_ptr_array_add(request->priv->selectedFiles.get(), g_strdup(filename.data()));
+ }
+ g_ptr_array_add(request->priv->selectedFiles.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+}
+
+/**
+ * webkit_file_chooser_request_cancel:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Ask WebKit to cancel the request. It's important to do this in case
+ * no selection has been made in the client, otherwise the request
+ * won't be properly completed and the browser will keep the request
+ * pending forever, which might cause the browser to hang.
+ */
+void webkit_file_chooser_request_cancel(WebKitFileChooserRequest* request)
+{
+ g_return_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request));
+ WKOpenPanelResultListenerCancel(request->priv->wkListener.get());
+ request->priv->handledRequest = true;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h
new file mode 100644
index 000000000..88eec9966
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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 WebKitFileChooserRequest_h
+#define WebKitFileChooserRequest_h
+
+#include <gtk/gtk.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_FILE_CHOOSER_REQUEST (webkit_file_chooser_request_get_type())
+#define WEBKIT_FILE_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequest))
+#define WEBKIT_FILE_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestClass))
+#define WEBKIT_IS_FILE_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST))
+#define WEBKIT_IS_FILE_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_FILE_CHOOSER_REQUEST))
+#define WEBKIT_FILE_CHOOSER_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestClass))
+
+typedef struct _WebKitFileChooserRequest WebKitFileChooserRequest;
+typedef struct _WebKitFileChooserRequestClass WebKitFileChooserRequestClass;
+typedef struct _WebKitFileChooserRequestPrivate WebKitFileChooserRequestPrivate;
+
+struct _WebKitFileChooserRequest {
+ GObject parent;
+
+ /*< private >*/
+ WebKitFileChooserRequestPrivate *priv;
+};
+
+struct _WebKitFileChooserRequestClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_file_chooser_request_get_type (void);
+
+WEBKIT_API const gchar * const *
+webkit_file_chooser_request_get_mime_types (WebKitFileChooserRequest *request);
+
+WEBKIT_API GtkFileFilter *
+webkit_file_chooser_request_get_mime_types_filter (WebKitFileChooserRequest *request);
+
+WEBKIT_API gboolean
+webkit_file_chooser_request_get_select_multiple (WebKitFileChooserRequest *request);
+
+WEBKIT_API void
+webkit_file_chooser_request_select_files (WebKitFileChooserRequest *request,
+ const gchar * const *files);
+
+WEBKIT_API const gchar * const *
+webkit_file_chooser_request_get_selected_files (WebKitFileChooserRequest *request);
+
+WEBKIT_API void
+webkit_file_chooser_request_cancel (WebKitFileChooserRequest *request);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h
new file mode 100644
index 000000000..af7224a96
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitFileChooserRequestPrivate_h
+#define WebKitFileChooserRequestPrivate_h
+
+#include "WebKitFileChooserRequest.h"
+#include "WebKitPrivate.h"
+
+WebKitFileChooserRequest* webkitFileChooserRequestCreate(WKOpenPanelParametersRef, WKOpenPanelResultListenerRef);
+
+#endif // WebKitFileChooserRequestPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp
new file mode 100644
index 000000000..75b51e25d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 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 "WebKitFullscreenClient.h"
+
+#include "WebKitPrivate.h"
+#include "WebKitWebViewPrivate.h"
+
+using namespace WebKit;
+
+static bool willEnterFullScreen(const void* clientInfo)
+{
+ return webkitWebViewEnterFullScreen(WEBKIT_WEB_VIEW(clientInfo));
+}
+
+static bool willExitFullScreen(const void* clientInfo)
+{
+ return webkitWebViewLeaveFullScreen(WEBKIT_WEB_VIEW(clientInfo));
+}
+
+void attachFullScreenClientToView(WebKitWebView* webView)
+{
+ WKFullScreenClientGtk wkFullScreenClient = {
+ kWKFullScreenClientGtkCurrentVersion,
+ webView, // clientInfo
+ willEnterFullScreen,
+ willExitFullScreen
+ };
+ WKViewSetFullScreenClientGtk(toAPI(WEBKIT_WEB_VIEW_BASE(webView)), &wkFullScreenClient);
+}
+
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h
new file mode 100644
index 000000000..187c067af
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFullscreenClient.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitFullscreenClient_h
+#define WebKitFullscreenClient_h
+
+#include "WebKitWebView.h"
+
+void attachFullScreenClientToView(WebKitWebView*);
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp
new file mode 100644
index 000000000..84ad04d03
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 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 "WebKitJavascriptResult.h"
+
+#include "WebKitJavascriptResultPrivate.h"
+#include <wtf/gobject/GRefPtr.h>
+
+struct _WebKitJavascriptResult {
+ _WebKitJavascriptResult(WebKitWebView* view, WKSerializedScriptValueRef wkSerializedScriptValue)
+ : webView(view)
+ , referenceCount(1)
+ {
+ value = WKSerializedScriptValueDeserialize(wkSerializedScriptValue, webkit_web_view_get_javascript_global_context(view), 0);
+ }
+
+ GRefPtr<WebKitWebView> webView;
+ JSValueRef value;
+
+ int referenceCount;
+};
+
+G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref)
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WKSerializedScriptValueRef wkSerializedScriptValue)
+{
+ WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult);
+ new (result) WebKitJavascriptResult(webView, wkSerializedScriptValue);
+ return result;
+}
+
+/**
+ * webkit_javascript_result_ref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically increments the reference count of @js_result by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #WebKitJavascriptResult
+ */
+WebKitJavascriptResult* webkit_javascript_result_ref(WebKitJavascriptResult* javascriptResult)
+{
+ g_atomic_int_inc(&javascriptResult->referenceCount);
+ return javascriptResult;
+}
+
+/**
+ * webkit_javascript_result_unref:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Atomically decrements the reference count of @js_result by one. If the
+ * reference count drops to 0, all memory allocated by the #WebKitJavascriptResult is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ */
+void webkit_javascript_result_unref(WebKitJavascriptResult* javascriptResult)
+{
+ if (g_atomic_int_dec_and_test(&javascriptResult->referenceCount)) {
+ javascriptResult->~WebKitJavascriptResult();
+ g_slice_free(WebKitJavascriptResult, javascriptResult);
+ }
+}
+
+/**
+ * webkit_javascript_result_get_global_context:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the global Javascript context that should be used with the
+ * <function>JSValueRef</function> returned by webkit_javascript_result_get_value().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> for the #WebKitJavascriptResult
+ */
+JSGlobalContextRef webkit_javascript_result_get_global_context(WebKitJavascriptResult* javascriptResult)
+{
+ return webkit_web_view_get_javascript_global_context(javascriptResult->webView.get());
+}
+
+/**
+ * webkit_javascript_result_get_value:
+ * @js_result: a #WebKitJavascriptResult
+ *
+ * Get the value of @js_result. You should use the <function>JSGlobalContextRef</function>
+ * returned by webkit_javascript_result_get_global_context() to use the <function>JSValueRef</function>.
+ *
+ * Returns: the <function>JSValueRef</function> of the #WebKitJavascriptResult
+ */
+JSValueRef webkit_javascript_result_get_value(WebKitJavascriptResult* javascriptResult)
+{
+ return javascriptResult->value;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h
new file mode 100644
index 000000000..5a9f7389f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 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 WebKitJavascriptResult_h
+#define WebKitJavascriptResult_h
+
+#include <JavaScriptCore/JSBase.h>
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_JAVASCRIPT_RESULT (webkit_javascript_result_get_type())
+
+typedef struct _WebKitJavascriptResult WebKitJavascriptResult;
+
+
+WEBKIT_API GType
+webkit_javascript_result_get_type (void);
+
+WEBKIT_API WebKitJavascriptResult *
+webkit_javascript_result_ref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API void
+webkit_javascript_result_unref (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSGlobalContextRef
+webkit_javascript_result_get_global_context (WebKitJavascriptResult *js_result);
+
+WEBKIT_API JSValueRef
+webkit_javascript_result_get_value (WebKitJavascriptResult *js_result);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h
new file mode 100644
index 000000000..840ead058
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitJavascriptResultPrivate_h
+#define WebKitJavascriptResultPrivate_h
+
+#include "WebKitJavascriptResult.h"
+#include "WebKitPrivate.h"
+#include "WebKitWebView.h"
+
+WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WKSerializedScriptValueRef);
+
+#endif // WebKitJavascriptResultPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
index d79d40149..7da0b197a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp
@@ -28,7 +28,9 @@
#include <WebCore/GtkUtilities.h>
#include <WebCore/NotImplemented.h>
#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
#ifdef HAVE_GTK_UNIX_PRINTING
#include <gtk/gtkunixprint.h>
@@ -46,6 +48,7 @@ enum {
enum {
FINISHED,
+ FAILED,
LAST_SIGNAL
};
@@ -193,6 +196,24 @@ static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOp
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * WebKitPrintOperation::failed:
+ * @print_operation: the #WebKitPrintOperation on which the signal was emitted
+ * @error: the #GError that was triggered
+ *
+ * Emitted when an error occurs while printing. The given @error, of the domain
+ * %WEBKIT_PRINT_ERROR, contains further details of the failure.
+ * The #WebKitPrintOperation::finished signal is emitted after this one.
+ */
+ signals[FAILED] =
+ g_signal_new("failed",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
g_type_class_add_private(printOperationClass, sizeof(WebKitPrintOperationPrivate));
}
@@ -237,11 +258,19 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe
}
#endif
-static void drawPagesForPrintingCompleted(WKErrorRef, void* context)
+static void drawPagesForPrintingCompleted(WKErrorRef wkPrintError, WKErrorRef, void* context)
{
GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context));
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
page->endPrinting();
+
+ const WebCore::ResourceError& resourceError = toImpl(wkPrintError)->platformError();
+ if (!resourceError.isNull()) {
+ GOwnPtr<GError> printError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
+ resourceError.errorCode(),
+ resourceError.localizedDescription().utf8().data()));
+ g_signal_emit(printOperation.get(), signals[FAILED], 0, printError.get());
+ }
g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL);
}
@@ -249,7 +278,7 @@ static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOp
{
PrintInfo printInfo(printSettings, pageSetup);
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
- page->drawPagesForPrinting(webFrame, printInfo, VoidCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
+ page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
}
WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame)
@@ -368,7 +397,8 @@ void webkit_print_operation_set_page_setup(WebKitPrintOperation* printOperation,
* If the print dialog is cancelled %WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL
* is returned. If the user clicks on the print button, %WEBKIT_PRINT_OPERATION_RESPONSE_PRINT
* is returned and the print operation starts. In this case, the #WebKitPrintOperation::finished
- * signal is emitted when the operation finishes.
+ * signal is emitted when the operation finishes. If an error occurs while printing, the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
* If the print dialog is not cancelled current print settings and page setup of @print_operation
* are updated with options selected by the user when Print button is pressed in print dialog.
* You can get the updated print settings and page setup by calling
@@ -395,7 +425,8 @@ WebKitPrintOperationResponse webkit_print_operation_run_dialog(WebKitPrintOperat
* webkit_print_operation_set_page_setup(), the default options will be used
* and the print job will be sent to the default printer.
* The #WebKitPrintOperation::finished signal is emitted when the printing
- * operation finishes.
+ * operation finishes. If an error occurs while printing the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
*/
void webkit_print_operation_print(WebKitPrintOperation* printOperation)
{
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
index e785c3638..4b7e9ad49 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
@@ -29,7 +29,9 @@
#include <WebKit2/WKAPICast.h>
#include <WebKit2/WKDownload.h>
#include <WebKit2/WKFindOptions.h>
+#include <WebKit2/WKFullScreenClientGtk.h>
#include <WebKit2/WKRetainPtr.h>
+#include <WebKit2/WKSerializedScriptValue.h>
#include <WebKit2/WKString.h>
#include <WebKit2/WebKit2.h>
#include <glib.h>
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
new file mode 100644
index 000000000..1cd8aaf7f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 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 "WebKitResourceLoadClient.h"
+
+#include "WebContext.h"
+#include "WebKitURIRequestPrivate.h"
+#include "WebKitURIResponsePrivate.h"
+#include "WebKitWebResourcePrivate.h"
+#include "WebKitWebViewBasePrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include "WebURLResponse.h"
+#include <WebKit2/WKString.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+static void didInitiateLoadForResource(WKPageRef, WKFrameRef wkFrame, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, bool pageIsProvisionallyLoading, const void* clientInfo)
+{
+ GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
+ webkitWebViewResourceLoadStarted(WEBKIT_WEB_VIEW(clientInfo), wkFrame, resourceIdentifier, request.get(), pageIsProvisionallyLoading);
+}
+
+static void didSendRequestForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKURLRequestRef wkRequest, WKURLResponseRef wkRedirectResponse, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(toImpl(wkRequest)->resourceRequest()));
+ GRefPtr<WebKitURIResponse> redirectResponse = wkRedirectResponse ? adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkRedirectResponse)->resourceResponse())) : 0;
+ webkitWebResourceSentRequest(resource.get(), request.get(), redirectResponse.get());
+}
+
+static void didReceiveResponseForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKURLResponseRef wkResponse, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkResponse)->resourceResponse()));
+ webkitWebResourceSetResponse(resource.get(), response.get());
+}
+
+static void didReceiveContentLengthForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, uint64_t contentLength, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ webkitWebResourceNotifyProgress(resource.get(), contentLength);
+}
+
+static void didFinishLoadForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, const void* clientInfo)
+{
+ GRefPtr<WebKitWebResource> resource = webkitWebViewResourceLoadFinished(WEBKIT_WEB_VIEW(clientInfo), resourceIdentifier);
+ if (!resource)
+ return;
+
+ webkitWebResourceFinished(resource.get());
+}
+
+static void didFailLoadForResource(WKPageRef, WKFrameRef, uint64_t resourceIdentifier, WKErrorRef wkError, const void* clientInfo)
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(clientInfo);
+ GRefPtr<WebKitWebResource> resource = webkitWebViewGetLoadingWebResource(webView, resourceIdentifier);
+ if (!resource)
+ return;
+
+ const ResourceError& resourceError = toImpl(wkError)->platformError();
+ GOwnPtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
+ resourceError.errorCode(),
+ resourceError.localizedDescription().utf8().data()));
+ webkitWebResourceFailed(resource.get(), webError.get());
+ webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier);
+}
+
+void attachResourceLoadClientToView(WebKitWebView* webView)
+{
+ WKPageResourceLoadClient wkResourceLoadClient = {
+ kWKPageResourceLoadClientCurrentVersion,
+ webView, // ClientInfo
+ didInitiateLoadForResource,
+ didSendRequestForResource,
+ didReceiveResponseForResource,
+ didReceiveContentLengthForResource,
+ didFinishLoadForResource,
+ didFailLoadForResource,
+ };
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKPageSetPageResourceLoadClient(wkPage, &wkResourceLoadClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h
new file mode 100644
index 000000000..0e6a3613c
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResourceLoadClient.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitResourceLoadClient_h
+#define WebKitResourceLoadClient_h
+
+#include "WebKitWebView.h"
+
+void attachResourceLoadClientToView(WebKitWebView*);
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
index b4b267d1b..8bec722b3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
@@ -105,7 +105,8 @@ enum {
PROP_PRINT_BACKGROUNDS,
PROP_ENABLE_WEBAUDIO,
PROP_ENABLE_WEBGL,
- PROP_ZOOM_TEXT_ONLY
+ PROP_ZOOM_TEXT_ONLY,
+ PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD
};
static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
@@ -215,6 +216,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu
case PROP_ZOOM_TEXT_ONLY:
webkit_settings_set_zoom_text_only(settings, g_value_get_boolean(value));
break;
+ case PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD:
+ webkit_settings_set_javascript_can_access_clipboard(settings, g_value_get_boolean(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -328,6 +332,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val
case PROP_ZOOM_TEXT_ONLY:
g_value_set_boolean(value, webkit_settings_get_zoom_text_only(settings));
break;
+ case PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD:
+ g_value_set_boolean(value, webkit_settings_get_javascript_can_access_clipboard(settings));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -840,6 +847,21 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass)
FALSE,
readWriteConstructParamFlags));
+ /**
+ * WebKitSettings:javascript-can-access-clipboard:
+ *
+ * Whether JavaScript can access the clipboard. The default value is %FALSE. If
+ * set to %TRUE, document.execCommand() allows cut, copy and paste commands.
+ *
+ */
+ g_object_class_install_property(gObjectClass,
+ PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD,
+ g_param_spec_boolean("javascript-can-access-clipboard",
+ _("JavaScript can access clipboard"),
+ _("Whether JavaScript can access Clipboard"),
+ FALSE,
+ readWriteConstructParamFlags));
+
g_type_class_add_private(klass, sizeof(WebKitSettingsPrivate));
}
@@ -2133,3 +2155,41 @@ gboolean webkit_settings_get_zoom_text_only(WebKitSettings* settings)
return settings->priv->zoomTextOnly;
}
+/**
+ * webkit_settings_get_javascript_can_access_clipboard:
+ * @settings: a #WebKitSettings
+ *
+ * Get the #WebKitSettings:javascript-can-access-clipboard property.
+ *
+ * Returns: %TRUE If javascript-can-access-clipboard is enabled or %FALSE otherwise.
+ */
+gboolean webkit_settings_get_javascript_can_access_clipboard(WebKitSettings* settings)
+{
+ g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
+
+ return WKPreferencesGetJavaScriptCanAccessClipboard(settings->priv->preferences.get())
+ && WKPreferencesGetDOMPasteAllowed(settings->priv->preferences.get());
+}
+
+/**
+ * webkit_settings_set_javascript_can_access_clipboard:
+ * @settings: a #WebKitSettings
+ * @enabled: Value to be set
+ *
+ * Set the #WebKitSettings:javascript-can-access-clipboard property.
+ */
+void webkit_settings_set_javascript_can_access_clipboard(WebKitSettings* settings, gboolean enabled)
+{
+ g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
+
+ WebKitSettingsPrivate* priv = settings->priv;
+ bool currentValue = WKPreferencesGetJavaScriptCanAccessClipboard(priv->preferences.get())
+ && WKPreferencesGetDOMPasteAllowed(priv->preferences.get());
+ if (currentValue == enabled)
+ return;
+
+ WKPreferencesSetJavaScriptCanAccessClipboard(priv->preferences.get(), enabled);
+ WKPreferencesSetDOMPasteAllowed(priv->preferences.get(), enabled);
+
+ g_object_notify(G_OBJECT(settings), "javascript-can-access-clipboard");
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
index 25a78aca3..57bf3f17d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
@@ -314,6 +314,13 @@ webkit_settings_set_zoom_text_only (WebKitSettings *
WEBKIT_API gboolean
webkit_settings_get_zoom_text_only (WebKitSettings *settings);
+WEBKIT_API gboolean
+webkit_settings_get_javascript_can_access_clipboard (WebKitSettings *settings);
+
+WEBKIT_API void
+webkit_settings_set_javascript_can_access_clipboard (WebKitSettings *settings,
+ gboolean enabled);
+
G_END_DECLS
#endif /* WebKitSettings_h */
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
index 6f0e11c82..9f78c9cbf 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp
@@ -20,12 +20,14 @@
#include "config.h"
#include "WebKitUIClient.h"
+#include "WebKitFileChooserRequestPrivate.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebPageProxy.h"
#include <WebCore/GtkUtilities.h>
+#include <wtf/gobject/GRefPtr.h>
using namespace WebKit;
@@ -136,6 +138,12 @@ static void printFrame(WKPageRef page, WKFrameRef frame, const void*)
webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), frame);
}
+static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo)
+{
+ GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener));
+ webkitWebViewRunFileChooserRequest(WEBKIT_WEB_VIEW(clientInfo), request.get());
+}
+
void attachUIClientToView(WebKitWebView* webView)
{
WKPageUIClient wkUIClient = {
@@ -169,7 +177,7 @@ void attachUIClientToView(WebKitWebView* webView)
0, // didDraw
0, // pageDidScroll
0, // exceededDatabaseQuota
- 0, // runOpenPanel
+ runOpenPanel,
0, // decidePolicyForGeolocationPermissionRequest
0, // headerHeight
0, // footerHeight
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
index 360b0a627..0b68c086d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
@@ -21,6 +21,7 @@
#include "WebKitWebContext.h"
#include "WebContext.h"
+#include "WebKitCookieManagerPrivate.h"
#include "WebKitDownloadClient.h"
#include "WebKitDownloadPrivate.h"
#include "WebKitPrivate.h"
@@ -39,6 +40,8 @@ enum {
struct _WebKitWebContextPrivate {
WKRetainPtr<WKContextRef> context;
+
+ GRefPtr<WebKitCookieManager> cookieManager;
};
static guint signals[LAST_SIGNAL] = { 0, };
@@ -84,12 +87,11 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass
static gpointer createDefaultWebContext(gpointer)
{
- WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL));
+ static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL)));
webContext->priv->context = WKContextGetSharedProcessContext();
WKContextSetCacheModel(webContext->priv->context.get(), kWKCacheModelPrimaryWebBrowser);
- attachDownloadClientToContext(webContext);
-
- return webContext;
+ attachDownloadClientToContext(webContext.get());
+ return webContext.get();
}
/**
@@ -215,6 +217,25 @@ WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const
return download;
}
+/**
+ * webkit_web_context_get_cookie_manager:
+ * @context: a #WebKitWebContext
+ *
+ * Get the #WebKitCookieManager of @context.
+ *
+ * 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), 0);
+
+ WebKitWebContextPrivate* priv = context->priv;
+ if (!priv->cookieManager)
+ priv->cookieManager = adoptGRef(webkitCookieManagerCreate(WKContextGetCookieManager(priv->context.get())));
+
+ return priv->cookieManager.get();
+}
+
WebKitDownload* webkitWebContextGetOrCreateDownload(WKDownloadRef wkDownload)
{
GRefPtr<WebKitDownload> download = downloadsMap().get(wkDownload);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
index b88bed0da..45b6e6c1d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h
@@ -25,6 +25,7 @@
#define WebKitWebContext_h
#include <glib-object.h>
+#include <webkit2/WebKitCookieManager.h>
#include <webkit2/WebKitDefines.h>
#include <webkit2/WebKitDownload.h>
@@ -79,20 +80,23 @@ struct _WebKitWebContextClass {
};
WEBKIT_API GType
-webkit_web_context_get_type (void);
+webkit_web_context_get_type (void);
WEBKIT_API WebKitWebContext *
-webkit_web_context_get_default (void);
+webkit_web_context_get_default (void);
WEBKIT_API void
-webkit_web_context_set_cache_model (WebKitWebContext *context,
- WebKitCacheModel cache_model);
+webkit_web_context_set_cache_model (WebKitWebContext *context,
+ WebKitCacheModel cache_model);
WEBKIT_API WebKitCacheModel
-webkit_web_context_get_cache_model (WebKitWebContext *context);
+webkit_web_context_get_cache_model (WebKitWebContext *context);
WEBKIT_API WebKitDownload *
-webkit_web_context_download_uri (WebKitWebContext *context,
- const gchar *uri);
+webkit_web_context_download_uri (WebKitWebContext *context,
+ const gchar *uri);
+
+WEBKIT_API WebKitCookieManager *
+webkit_web_context_get_cookie_manager (WebKitWebContext *context);
G_END_DECLS
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
new file mode 100644
index 000000000..6bd51fa08
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2012 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 "WebKitWebResource.h"
+
+#include "WebKitMarshal.h"
+#include "WebKitURIRequest.h"
+#include "WebKitWebResourcePrivate.h"
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+enum {
+ SENT_REQUEST,
+ RECEIVED_DATA,
+ FINISHED,
+ FAILED,
+
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+
+ PROP_URI,
+ PROP_RESPONSE
+};
+
+
+struct _WebKitWebResourcePrivate {
+ WKRetainPtr<WKFrameRef> wkFrame;
+ CString uri;
+ GRefPtr<WebKitURIResponse> response;
+ bool isMainResource;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(WebKitWebResource, webkit_web_resource, G_TYPE_OBJECT)
+
+static void webkitWebResourceFinalize(GObject* object)
+{
+ WEBKIT_WEB_RESOURCE(object)->priv->~WebKitWebResourcePrivate();
+ G_OBJECT_CLASS(webkit_web_resource_parent_class)->finalize(object);
+}
+
+static void webkitWebResourceGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebResource* resource = WEBKIT_WEB_RESOURCE(object);
+
+ switch (propId) {
+ case PROP_URI:
+ g_value_set_string(value, webkit_web_resource_get_uri(resource));
+ break;
+ case PROP_RESPONSE:
+ g_value_set_object(value, webkit_web_resource_get_response(resource));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkit_web_resource_init(WebKitWebResource* resource)
+{
+ WebKitWebResourcePrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(resource, WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourcePrivate);
+ resource->priv = priv;
+ new (priv) WebKitWebResourcePrivate();
+}
+
+static void webkit_web_resource_class_init(WebKitWebResourceClass* resourceClass)
+{
+ GObjectClass* objectClass = G_OBJECT_CLASS(resourceClass);
+ objectClass->get_property = webkitWebResourceGetProperty;
+ objectClass->finalize = webkitWebResourceFinalize;
+
+ /**
+ * WebKitWebResource:uri:
+ *
+ * The current active URI of the #WebKitWebResource.
+ * See webkit_web_resource_get_uri() for more details.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_URI,
+ g_param_spec_string("uri",
+ _("URI"),
+ _("The current active URI of the result"),
+ 0,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebResource:response:
+ *
+ * The #WebKitURIResponse associated with this resource.
+ */
+ g_object_class_install_property(objectClass,
+ PROP_RESPONSE,
+ g_param_spec_object("response",
+ _("Response"),
+ _("The response of the resource"),
+ WEBKIT_TYPE_URI_RESPONSE,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebResource::sent-request:
+ * @resource: the #WebKitWebResource
+ * @request: a #WebKitURIRequest
+ * @redirected_response: a #WebKitURIResponse, or %NULL
+ *
+ * This signal is emitted when @request has been sent to the
+ * server. In case of a server redirection this signal is
+ * emitted again with the @request argument containing the new
+ * request sent to the server due to the redirection and the
+ * @redirected_response parameter containing the response
+ * received by the server for the initial request.
+ */
+ signals[SENT_REQUEST] =
+ g_signal_new("sent-request",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ webkit_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ WEBKIT_TYPE_URI_REQUEST,
+ WEBKIT_TYPE_URI_RESPONSE);
+
+ /**
+ * WebKitWebResource::received-data:
+ * @resource: the #WebKitWebResource
+ * @data_length: the length of data received in bytes
+ *
+ * This signal is emitted after response is received,
+ * every time new data has been received. It's
+ * useful to know the progress of the resource load operation.
+ */
+ signals[RECEIVED_DATA] =
+ g_signal_new("received-data",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ webkit_marshal_VOID__UINT64,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT64);
+
+ /**
+ * WebKitWebResource::finished:
+ * @resource: the #WebKitWebResource
+ *
+ * This signal is emitted when the resource load finishes successfully
+ * or due to an error. In case of errors #WebKitWebResource::failed signal
+ * is emitted before this one.
+ */
+ signals[FINISHED] =
+ g_signal_new("finished",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * WebKitWebResource::failed:
+ * @resource: the #WebKitWebResource
+ * @error: the #GError that was triggered
+ *
+ * This signal is emitted when an error occurs during the resource
+ * load operation.
+ */
+ signals[FAILED] =
+ g_signal_new("failed",
+ G_TYPE_FROM_CLASS(objectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ g_type_class_add_private(resourceClass, sizeof(WebKitWebResourcePrivate));
+}
+
+static void webkitWebResourceUpdateURI(WebKitWebResource* resource, const CString& requestURI)
+{
+ if (resource->priv->uri == requestURI)
+ return;
+
+ resource->priv->uri = requestURI;
+ g_object_notify(G_OBJECT(resource), "uri");
+}
+
+WebKitWebResource* webkitWebResourceCreate(WKFrameRef wkFrame, WebKitURIRequest* request, bool isMainResource)
+{
+ ASSERT(wkFrame);
+ WebKitWebResource* resource = WEBKIT_WEB_RESOURCE(g_object_new(WEBKIT_TYPE_WEB_RESOURCE, NULL));
+ resource->priv->wkFrame = wkFrame;
+ resource->priv->uri = webkit_uri_request_get_uri(request);
+ resource->priv->isMainResource = isMainResource;
+ return resource;
+}
+
+void webkitWebResourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+{
+ webkitWebResourceUpdateURI(resource, webkit_uri_request_get_uri(request));
+ g_signal_emit(resource, signals[SENT_REQUEST], 0, request, redirectResponse);
+}
+
+void webkitWebResourceSetResponse(WebKitWebResource* resource, WebKitURIResponse* response)
+{
+ resource->priv->response = response;
+ g_object_notify(G_OBJECT(resource), "response");
+}
+
+void webkitWebResourceNotifyProgress(WebKitWebResource* resource, guint64 bytesReceived)
+{
+ g_signal_emit(resource, signals[RECEIVED_DATA], 0, bytesReceived);
+}
+
+void webkitWebResourceFinished(WebKitWebResource* resource)
+{
+ g_signal_emit(resource, signals[FINISHED], 0, NULL);
+}
+
+void webkitWebResourceFailed(WebKitWebResource* resource, GError* error)
+{
+ g_signal_emit(resource, signals[FAILED], 0, error);
+ g_signal_emit(resource, signals[FINISHED], 0, NULL);
+}
+
+/**
+ * webkit_web_resource_get_uri:
+ * @resource: a #WebKitWebResource
+ *
+ * Returns the current active URI of @web_view. The active URI might change during
+ * a load operation:
+ *
+ * <orderedlist>
+ * <listitem><para>
+ * When the resource load starts, the active URI is the requested URI
+ * </para></listitem>
+ * <listitem><para>
+ * When the initial request is sent to the server, #WebKitWebResource::sent-request
+ * signal is emitted without a redirected response, the active URI is the URI of
+ * the request sent to the server.
+ * </para></listitem>
+ * <listitem><para>
+ * In case of a server redirection, #WebKitWebResource::sent-request signal
+ * is emitted again with a redirected response, the active URI is the URI the request
+ * was redirected to.
+ * </para></listitem>
+ * <listitem><para>
+ * When the response is received from the server, the active URI is the final
+ * one and it will not change again.
+ * </para></listitem>
+ * </orderedlist>
+ *
+ * You can monitor the active URI by connecting to the notify::uri
+ * signal of @resource.
+ *
+ * Returns: the current active URI of @resource
+ */
+const char* webkit_web_resource_get_uri(WebKitWebResource* resource)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+
+ return resource->priv->uri.data();
+}
+
+/**
+ * webkit_web_resource_get_response:
+ * @resource: a #WebKitWebResource
+ *
+ * Retrieves the #WebKitURIResponse of the resource load operation.
+ * This method returns %NULL if called before the response
+ * is received from the server. You can connect to notify::response
+ * signal to be notified when the response is received.
+ *
+ * Returns: (transfer none): the #WebKitURIResponse, or %NULL if
+ * the response hasn't been received yet.
+ */
+WebKitURIResponse* webkit_web_resource_get_response(WebKitWebResource* resource)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+
+ return resource->priv->response.get();
+}
+
+static void resourceDataCallback(WKDataRef data, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ g_simple_async_result_set_op_res_gpointer(result.get(), const_cast<OpaqueWKData*>(data), 0);
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_resource_get_data:
+ * @resource: a #WebKitWebResource
+ * @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 raw data for @resource.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_web_resource_get_data_finish() to get the result of the operation.
+ */
+void webkit_web_resource_get_data(WebKitWebResource* resource, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_RESOURCE(resource));
+
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(resource), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_resource_get_data));
+ if (resource->priv->isMainResource)
+ WKFrameGetMainResourceData(resource->priv->wkFrame.get(), resourceDataCallback, result);
+ else {
+ WKRetainPtr<WKURLRef> url(AdoptWK, WKURLCreateWithUTF8CString(resource->priv->uri.data()));
+ WKFrameGetResourceData(resource->priv->wkFrame.get(), url.get(), resourceDataCallback, result);
+ }
+}
+
+/**
+ * webkit_web_resource_get_data_finish:
+ * @resource: a #WebKitWebResource
+ * @result: a #GAsyncResult
+ * @length: (out): return location for the length of the resource data
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_resource_get_data().
+ *
+ * Returns: (transfer full): a string with the data of @resource, or %NULL in case
+ * of error. if @length is not %NULL, the size of the data will be assigned to it.
+ */
+guchar* webkit_web_resource_get_data_finish(WebKitWebResource* resource, GAsyncResult* result, gsize* length, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_RESOURCE(resource), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simple = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simple) == webkit_web_resource_get_data);
+
+ if (g_simple_async_result_propagate_error(simple, error))
+ return 0;
+
+ WKDataRef wkData = static_cast<WKDataRef>(g_simple_async_result_get_op_res_gpointer(simple));
+ if (length)
+ *length = WKDataGetSize(wkData);
+ return static_cast<guchar*>(g_memdup(WKDataGetBytes(wkData), WKDataGetSize(wkData)));
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
new file mode 100644
index 000000000..34af76e2b
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 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 WebKitWebResource_h
+#define WebKitWebResource_h
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitURIResponse.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_WEB_RESOURCE (webkit_web_resource_get_type())
+#define WEBKIT_WEB_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResource))
+#define WEBKIT_IS_WEB_RESOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_RESOURCE))
+#define WEBKIT_WEB_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourceClass))
+#define WEBKIT_IS_WEB_RESOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_RESOURCE))
+#define WEBKIT_WEB_RESOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_RESOURCE, WebKitWebResourceClass))
+
+typedef struct _WebKitWebResource WebKitWebResource;
+typedef struct _WebKitWebResourceClass WebKitWebResourceClass;
+typedef struct _WebKitWebResourcePrivate WebKitWebResourcePrivate;
+
+struct _WebKitWebResource {
+ GObject parent;
+
+ WebKitWebResourcePrivate *priv;
+};
+
+struct _WebKitWebResourceClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_web_resource_get_type (void);
+
+WEBKIT_API const gchar *
+webkit_web_resource_get_uri (WebKitWebResource *resource);
+
+WEBKIT_API WebKitURIResponse *
+webkit_web_resource_get_response (WebKitWebResource *resource);
+
+WEBKIT_API void
+webkit_web_resource_get_data (WebKitWebResource *resource,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+WEBKIT_API guchar *
+webkit_web_resource_get_data_finish (WebKitWebResource *resource,
+ GAsyncResult *result,
+ gsize *length,
+ GError **error);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
new file mode 100644
index 000000000..5011ae4dd
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef WebKitWebResourcePrivate_h
+#define WebKitWebResourcePrivate_h
+
+#include "WebKitPrivate.h"
+#include "WebKitWebResource.h"
+
+WebKitWebResource* webkitWebResourceCreate(WKFrameRef, WebKitURIRequest*, bool isMainResource);
+void webkitWebResourceSentRequest(WebKitWebResource*, WebKitURIRequest*, WebKitURIResponse*);
+void webkitWebResourceSetResponse(WebKitWebResource*, WebKitURIResponse*);
+void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived);
+void webkitWebResourceFinished(WebKitWebResource*);
+void webkitWebResourceFailed(WebKitWebResource*, GError*);
+
+
+#endif // WebKitWebResourcePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 4f17d4669..56b21df49 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -24,20 +24,25 @@
#include "WebKitBackForwardListPrivate.h"
#include "WebKitEnumTypes.h"
#include "WebKitError.h"
+#include "WebKitFullscreenClient.h"
#include "WebKitHitTestResultPrivate.h"
+#include "WebKitJavascriptResultPrivate.h"
#include "WebKitLoaderClient.h"
#include "WebKitMarshal.h"
#include "WebKitPolicyClient.h"
#include "WebKitPrintOperationPrivate.h"
#include "WebKitPrivate.h"
+#include "WebKitResourceLoadClient.h"
#include "WebKitScriptDialogPrivate.h"
#include "WebKitSettingsPrivate.h"
#include "WebKitUIClient.h"
#include "WebKitWebContextPrivate.h"
+#include "WebKitWebResourcePrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
#include "WebKitWindowPropertiesPrivate.h"
#include "WebPageProxy.h"
+#include <JavaScriptCore/APICast.h>
#include <WebCore/DragIcon.h>
#include <WebCore/GtkUtilities.h>
#include <glib/gi18n-lib.h>
@@ -64,6 +69,13 @@ enum {
PRINT_REQUESTED,
+ RESOURCE_LOAD_STARTED,
+
+ ENTER_FULLSCREEN,
+ LEAVE_FULLSCREEN,
+
+ RUN_FILE_CHOOSER,
+
LAST_SIGNAL
};
@@ -84,6 +96,9 @@ typedef enum {
DidReplaceContent
} ReplaceContentStatus;
+typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap;
+typedef HashMap<String, GRefPtr<WebKitWebResource> > ResourcesMap;
+
struct _WebKitWebViewPrivate {
WebKitWebContext* context;
CString title;
@@ -100,6 +115,11 @@ struct _WebKitWebViewPrivate {
unsigned mouseTargetModifiers;
GRefPtr<WebKitFindController> findController;
+ JSGlobalContextRef javascriptGlobalContext;
+
+ GRefPtr<WebKitWebResource> mainResource;
+ LoadingResourcesMap loadingResourcesMap;
+ ResourcesMap subresourcesMap;
};
static guint signals[LAST_SIGNAL] = { 0, };
@@ -188,6 +208,49 @@ static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* set
g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView);
}
+static void fileChooserDialogResponseCallback(GtkDialog* dialog, gint responseID, WebKitFileChooserRequest* request)
+{
+ GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
+ if (responseID == GTK_RESPONSE_ACCEPT) {
+ GOwnPtr<GSList> filesList(gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)));
+ GRefPtr<GPtrArray> filesArray = adoptGRef(g_ptr_array_new());
+ for (GSList* file = filesList.get(); file; file = g_slist_next(file))
+ g_ptr_array_add(filesArray.get(), file->data);
+ g_ptr_array_add(filesArray.get(), 0);
+ webkit_file_chooser_request_select_files(adoptedRequest.get(), reinterpret_cast<const gchar* const*>(filesArray->pdata));
+ } else
+ webkit_file_chooser_request_cancel(adoptedRequest.get());
+
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static gboolean webkitWebViewRunFileChooser(WebKitWebView* webView, WebKitFileChooserRequest* request)
+{
+ GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webView));
+ if (!widgetIsOnscreenToplevelWindow(toplevel))
+ toplevel = 0;
+
+ gboolean allowsMultipleSelection = webkit_file_chooser_request_get_select_multiple(request);
+ GtkWidget* dialog = gtk_file_chooser_dialog_new(allowsMultipleSelection ? _("Select Files") : _("Select File"),
+ toplevel ? GTK_WINDOW(toplevel) : 0,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ if (GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(request))
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), allowsMultipleSelection);
+
+ if (const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(request))
+ gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), selectedFiles[0]);
+
+ g_signal_connect(dialog, "response", G_CALLBACK(fileChooserDialogResponseCallback), g_object_ref(request));
+ gtk_widget_show(dialog);
+
+ return TRUE;
+}
+
static void webkitWebViewConstructed(GObject* object)
{
if (G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed)
@@ -202,6 +265,8 @@ static void webkitWebViewConstructed(GObject* object)
attachLoaderClientToView(webView);
attachUIClientToView(webView);
attachPolicyClientToPage(webView);
+ attachResourceLoadClientToView(webView);
+ attachFullScreenClientToView(webView);
WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase);
priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page))));
@@ -255,7 +320,10 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu
static void webkitWebViewFinalize(GObject* object)
{
- WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
+ WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(object)->priv;
+ if (priv->javascriptGlobalContext)
+ JSGlobalContextRelease(priv->javascriptGlobalContext);
+ priv->~WebKitWebViewPrivate();
G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
}
@@ -290,6 +358,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
webViewClass->create = webkitWebViewCreate;
webViewClass->script_dialog = webkitWebViewScriptDialog;
webViewClass->decide_policy = webkitWebViewDecidePolicy;
+ webViewClass->run_file_chooser = webkitWebViewRunFileChooser;
g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate));
@@ -666,6 +735,104 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
webkit_marshal_BOOLEAN__OBJECT,
G_TYPE_BOOLEAN, 1,
WEBKIT_TYPE_PRINT_OPERATION);
+
+ /**
+ * WebKitWebView::resource-load-started:
+ * @web_view: the #WebKitWebView on which the signal is emitted
+ * @resource: a #WebKitWebResource
+ * @request: a #WebKitURIRequest
+ *
+ * Emitted when a new resource is going to be loaded. The @request parameter
+ * contains the #WebKitURIRequest that will be sent to the server.
+ * You can monitor the load operation by connecting to the different signals
+ * of @resource.
+ */
+ signals[RESOURCE_LOAD_STARTED] =
+ g_signal_new("resource-load-started",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, resource_load_started),
+ 0, 0,
+ webkit_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ WEBKIT_TYPE_WEB_RESOURCE,
+ WEBKIT_TYPE_URI_REQUEST);
+
+ /**
+ * WebKitWebView::enter-fullscreen:
+ * @web_view: the #WebKitWebView on which the signal is emitted.
+ *
+ * Emitted when JavaScript code calls
+ * <function>element.webkitRequestFullScreen</function>. If the
+ * signal is not handled the #WebKitWebView will proceed to full screen
+ * its top level window. This signal can be used by client code to
+ * request permission to the user prior doing the full screen
+ * transition and eventually prepare the top-level window
+ * (e.g. hide some widgets that would otherwise be part of the
+ * full screen window).
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to continue emission of the event.
+ */
+ signals[ENTER_FULLSCREEN] =
+ g_signal_new("enter-fullscreen",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, enter_fullscreen),
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ /**
+ * WebKitWebView::leave-fullscreen:
+ * @web_view: the #WebKitWebView on which the signal is emitted.
+ *
+ * Emitted when the #WebKitWebView is about to restore its top level
+ * window out of its full screen state. This signal can be used by
+ * client code to restore widgets hidden during the
+ * #WebKitWebView::enter-fullscreen stage for instance.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to continue emission of the event.
+ */
+ signals[LEAVE_FULLSCREEN] =
+ g_signal_new("leave-fullscreen",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, leave_fullscreen),
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+ /**
+ * WebKitWebView::run-file-chooser:
+ * @web_view: the #WebKitWebView on which the signal is emitted
+ * @request: a #WebKitFileChooserRequest
+ *
+ * This signal is emitted when the user interacts with a &lt;input
+ * type='file' /&gt; HTML element, requesting from WebKit to show
+ * a dialog to select one or more files to be uploaded. To let the
+ * application know the details of the file chooser, as well as to
+ * allow the client application to either cancel the request or
+ * perform an actual selection of files, the signal will pass an
+ * instance of the #WebKitFileChooserRequest in the @request
+ * argument.
+ *
+ * The default signal handler will asynchronously run a regular
+ * #GtkFileChooserDialog for the user to interact with.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ *
+ */
+ signals[RUN_FILE_CHOOSER] =
+ g_signal_new("run-file-chooser",
+ G_TYPE_FROM_CLASS(webViewClass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
+ g_signal_accumulator_true_handled, 0 /* accumulator data */,
+ webkit_marshal_BOOLEAN__OBJECT,
+ G_TYPE_BOOLEAN, 1, /* number of parameters */
+ WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
}
static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent loadEvent)
@@ -689,6 +856,12 @@ static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent l
void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent)
{
+ if (loadEvent == WEBKIT_LOAD_STARTED) {
+ webView->priv->loadingResourcesMap.clear();
+ webView->priv->mainResource = 0;
+ } else if (loadEvent == WEBKIT_LOAD_COMMITTED)
+ webView->priv->subresourcesMap.clear();
+
if (updateReplaceContentStatus(webView, loadEvent))
return;
@@ -822,6 +995,77 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WKFrameRef wkFrame)
g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0);
}
+static inline bool webkitWebViewIsReplacingContentOrDidReplaceContent(WebKitWebView* webView)
+{
+ return (webView->priv->replaceContentStatus == ReplacingContent || webView->priv->replaceContentStatus == DidReplaceContent);
+}
+
+void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WKFrameRef wkFrame, uint64_t resourceIdentifier, WebKitURIRequest* request, bool isMainResource)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ WebKitWebResource* resource = webkitWebResourceCreate(wkFrame, request, isMainResource);
+ if (WKFrameIsMainFrame(wkFrame) && isMainResource)
+ priv->mainResource = resource;
+ priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource));
+ g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request);
+}
+
+WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return 0;
+
+ GRefPtr<WebKitWebResource> resource = webView->priv->loadingResourcesMap.get(resourceIdentifier);
+ ASSERT(resource.get());
+ return resource.get();
+}
+
+void webkitWebViewRemoveLoadingWebResource(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ ASSERT(priv->loadingResourcesMap.contains(resourceIdentifier));
+ priv->loadingResourcesMap.remove(resourceIdentifier);
+}
+
+WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView* webView, uint64_t resourceIdentifier)
+{
+ if (webkitWebViewIsReplacingContentOrDidReplaceContent(webView))
+ return 0;
+
+ WebKitWebViewPrivate* priv = webView->priv;
+ WebKitWebResource* resource = webkitWebViewGetLoadingWebResource(webView, resourceIdentifier);
+ if (resource != priv->mainResource)
+ priv->subresourcesMap.set(String::fromUTF8(webkit_web_resource_get_uri(resource)), resource);
+ webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier);
+ return resource;
+}
+
+bool webkitWebViewEnterFullScreen(WebKitWebView* webView)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[ENTER_FULLSCREEN], 0, &returnValue);
+ return !returnValue;
+}
+
+bool webkitWebViewLeaveFullScreen(WebKitWebView* webView)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[LEAVE_FULLSCREEN], 0, &returnValue);
+ return !returnValue;
+}
+
+void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChooserRequest* request)
+{
+ gboolean returnValue;
+ g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue);
+}
+
/**
* webkit_web_view_new:
*
@@ -1466,3 +1710,179 @@ WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView
return webView->priv->findController.get();
}
+
+/**
+ * webkit_web_view_get_javascript_global_context:
+ * @web_view: a #WebKitWebView
+ *
+ * Get the global JavaScript context used by @web_view to deserialize the
+ * result values of scripts executed with webkit_web_view_run_javascript().
+ *
+ * Returns: the <function>JSGlobalContextRef</function> used by @web_view to deserialize
+ * the result values of scripts.
+ */
+JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ if (!webView->priv->javascriptGlobalContext)
+ webView->priv->javascriptGlobalContext = JSGlobalContextCreate(0);
+ return webView->priv->javascriptGlobalContext;
+}
+
+static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context)
+{
+ GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
+ if (wkSerializedScriptValue) {
+ GRefPtr<WebKitWebView> webView = adoptGRef(WEBKIT_WEB_VIEW(g_async_result_get_source_object(G_ASYNC_RESULT(result.get()))));
+ WebKitJavascriptResult* scriptResult = webkitJavascriptResultCreate(webView.get(), wkSerializedScriptValue);
+ g_simple_async_result_set_op_res_gpointer(result.get(), scriptResult, reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref));
+ } else {
+ GError* error = 0;
+ g_set_error_literal(&error, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, _("An exception was raised in JavaScript"));
+ g_simple_async_result_take_error(result.get(), error);
+ }
+ g_simple_async_result_complete(result.get());
+}
+
+/**
+ * webkit_web_view_run_javascript:
+ * @web_view: a #WebKitWebView
+ * @script: the script to run
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Asynchronously run @script in the context of the current page in @web_view.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * webkit_web_view_run_javascript_finish() to get the result of the operation.
+ */
+void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GAsyncReadyCallback callback, gpointer userData)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
+ g_return_if_fail(script);
+
+ WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
+ WKRetainPtr<WKStringRef> wkScript = adoptWK(WKStringCreateWithUTF8CString(script));
+ GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
+ reinterpret_cast<gpointer>(webkit_web_view_run_javascript));
+ WKPageRunJavaScriptInMainFrame(wkPage, wkScript.get(), result, webkitWebViewRunJavaScriptCallback);
+}
+
+/**
+ * webkit_web_view_run_javascript_finish:
+ * @web_view: a #WebKitWebView
+ * @result: a #GAsyncResult
+ * @error: return location for error or %NULL to ignore
+ *
+ * Finish an asynchronous operation started with webkit_web_view_run_javascript().
+ *
+ * This is an example of using webkit_web_view_run_javascript() with a script returning
+ * a string:
+ *
+ * <informalexample><programlisting>
+ * static void
+ * web_view_javascript_finished (GObject *object,
+ * GAsyncResult *result,
+ * gpointer user_data)
+ * {
+ * WebKitJavascriptResult *js_result;
+ * JSValueRef value;
+ * JSGlobalContextRef context;
+ * GError *error = NULL;
+ *
+ * js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
+ * if (!js_result) {
+ * g_warning ("Error running javascript: %s", error->message);
+ * g_error_free (error);
+ * return;
+ * }
+ *
+ * context = webkit_javascript_result_get_global_context (js_result);
+ * value = webkit_javascript_result_get_value (js_result);
+ * if (JSValueIsString (context, value)) {
+ * JSStringRef *js_str_value;
+ * gchar *str_value;
+ * gsize str_length;
+ *
+ * js_str_value = JSValueToStringCopy (context, value, NULL));
+ * str_length = JSStringGetMaximumUTF8CStringSize (js_str_value);
+ * str_value = (gchar *)g_malloc (str_length));
+ * JSStringGetUTF8CString (js_str_value, str_value, str_length);
+ * JSStringRelease (js_str_value);
+ * g_print ("Script result: %s\n", str_value);
+ * g_free (str_value);
+ * } else {
+ * g_warning ("Error running javascript: unexpected return value");
+ * }
+ * webkit_javascript_result_unref (js_result);
+ * }
+ *
+ * static void
+ * web_view_get_link_url (WebKitWebView *web_view,
+ * const gchar *link_id)
+ * {
+ * gchar *script;
+ *
+ * script = g_strdup_printf ("window.document.getElementById('%s').href;", link_id);
+ * webkit_web_view_run_javascript (web_view, script, web_view_javascript_finished, NULL);
+ * g_free (script);
+ * }
+ * </programlisting></informalexample>
+ *
+ * Returns: (transfer full): a #WebKitJavascriptResult with the result of the last executed statement in @script
+ * or %NULL in case of error
+ */
+WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* webView, GAsyncResult* result, GError** error)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), 0);
+
+ GSimpleAsyncResult* simpleResult = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simpleResult) == webkit_web_view_run_javascript);
+
+ if (g_simple_async_result_propagate_error(simpleResult, error))
+ return 0;
+
+ WebKitJavascriptResult* scriptResult = static_cast<WebKitJavascriptResult*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return scriptResult ? webkit_javascript_result_ref(scriptResult) : 0;
+}
+
+/**
+ * webkit_web_view_get_main_resource:
+ * @web_view: a #WebKitWebView
+ *
+ * Return the main resource of @web_view.
+ * See also webkit_web_view_get_subresources():
+ *
+ * Returns: (transfer none): the main #WebKitWebResource of the view
+ * or %NULL if nothing has been loaded.
+ */
+WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ return webView->priv->mainResource.get();
+}
+
+/**
+ * webkit_web_view_get_subresources:
+ * @web_view: a #WebKitWebView
+ *
+ * Return the list of subresources of @web_view.
+ * See also webkit_web_view_get_main_resource().
+ *
+ * Returns: (element-type WebKitWebResource) (transfer container): a list of #WebKitWebResource.
+ */
+GList* webkit_web_view_get_subresources(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ GList* subresources = 0;
+ WebKitWebViewPrivate* priv = webView->priv;
+ ResourcesMap::const_iterator end = priv->subresourcesMap.end();
+ for (ResourcesMap::const_iterator it = priv->subresourcesMap.begin(); it != end; ++it)
+ subresources = g_list_prepend(subresources, it->second.get());
+
+ return g_list_reverse(subresources);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
index fb4c48a2d..c56205b96 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
@@ -28,17 +28,21 @@
#ifndef WebKitWebView_h
#define WebKitWebView_h
+#include <JavaScriptCore/JSBase.h>
#include <webkit2/WebKitBackForwardList.h>
#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitFileChooserRequest.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
+#include <webkit2/WebKitPolicyDecision.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitWebContext.h>
+#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWindowProperties.h>
-#include <webkit2/WebKitPolicyDecision.h>
G_BEGIN_DECLS
@@ -121,28 +125,35 @@ struct _WebKitWebView {
struct _WebKitWebViewClass {
WebKitWebViewBaseClass parent;
- void (* load_changed) (WebKitWebView *web_view,
- WebKitLoadEvent load_event);
- gboolean (* load_failed) (WebKitWebView *web_view,
- WebKitLoadEvent load_event,
- const gchar *failing_uri,
- GError *error);
-
- GtkWidget *(* create) (WebKitWebView *web_view);
- void (* ready_to_show) (WebKitWebView *web_view);
- void (* close) (WebKitWebView *web_view);
-
- gboolean (* script_dialog) (WebKitWebView *web_view,
- WebKitScriptDialog *dialog);
-
- gboolean (* decide_policy) (WebKitWebView *web_view,
- WebKitPolicyDecision *decision,
- WebKitPolicyDecisionType type);
- void (* mouse_target_changed) (WebKitWebView *web_view,
- WebKitHitTestResult *hit_test_result,
- guint modifiers);
- gboolean (* print_requested) (WebKitWebView *web_view,
- WebKitPrintOperation *print_operation);
+ void (* load_changed) (WebKitWebView *web_view,
+ WebKitLoadEvent load_event);
+ gboolean (* load_failed) (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ const gchar *failing_uri,
+ GError *error);
+
+ GtkWidget *(* create) (WebKitWebView *web_view);
+ void (* ready_to_show) (WebKitWebView *web_view);
+ void (* close) (WebKitWebView *web_view);
+
+ gboolean (* script_dialog) (WebKitWebView *web_view,
+ WebKitScriptDialog *dialog);
+
+ gboolean (* decide_policy) (WebKitWebView *web_view,
+ WebKitPolicyDecision *decision,
+ WebKitPolicyDecisionType type);
+ void (* mouse_target_changed) (WebKitWebView *web_view,
+ WebKitHitTestResult *hit_test_result,
+ guint modifiers);
+ gboolean (* print_requested) (WebKitWebView *web_view,
+ WebKitPrintOperation *print_operation);
+ void (* resource_load_started) (WebKitWebView *web_view,
+ WebKitWebResource *resource,
+ WebKitURIRequest *request);
+ gboolean (* enter_fullscreen) (WebKitWebView *web_view);
+ gboolean (* leave_fullscreen) (WebKitWebView *web_view);
+ gboolean (* run_file_chooser) (WebKitWebView *web_view,
+ WebKitFileChooserRequest *request);
/* Padding for future expansion */
void (*_webkit_reserved0) (void);
@@ -267,6 +278,24 @@ webkit_web_view_execute_editing_command (WebKitWebView *w
WEBKIT_API WebKitFindController *
webkit_web_view_get_find_controller (WebKitWebView *web_view);
+WEBKIT_API JSGlobalContextRef
+webkit_web_view_get_javascript_global_context (WebKitWebView *web_view);
+
+WEBKIT_API void
+webkit_web_view_run_javascript (WebKitWebView *web_view,
+ const gchar *script,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+WEBKIT_API WebKitJavascriptResult *
+webkit_web_view_run_javascript_finish (WebKitWebView *web_view,
+ GAsyncResult *result,
+ GError **error);
+
+WEBKIT_API WebKitWebResource *
+webkit_web_view_get_main_resource (WebKitWebView *web_view);
+
+WEBKIT_API GList *
+webkit_web_view_get_subresources (WebKitWebView *web_view);
G_END_DECLS
#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
index adcc34ae3..b2cdde564 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -35,6 +35,7 @@
#include "PageClientImpl.h"
#include "WebContext.h"
#include "WebEventFactory.h"
+#include "WebFullScreenClientGtk.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBaseAccessible.h"
#include "WebKitWebViewBasePrivate.h"
@@ -52,14 +53,24 @@
#include <WebCore/PasteboardHelper.h>
#include <WebCore/RefPtrCairo.h>
#include <WebCore/Region.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <wtf/HashMap.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
+#if ENABLE(FULLSCREEN_API)
+#include "WebFullScreenManagerProxy.h"
+#endif
+
using namespace WebKit;
using namespace WebCore;
+typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap;
+
struct _WebKitWebViewBasePrivate {
+ WebKitWebViewChildrenMap children;
OwnPtr<PageClientImpl> pageClient;
RefPtr<WebPageProxy> pageProxy;
bool isPageActive;
@@ -72,6 +83,10 @@ struct _WebKitWebViewBasePrivate {
IntSize resizerSize;
GRefPtr<AtkObject> accessible;
bool needsResizeOnMap;
+#if ENABLE(FULLSCREEN_API)
+ bool fullScreenModeActive;
+ WebFullScreenClientGtk fullScreenClient;
+#endif
};
G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
@@ -152,9 +167,53 @@ static void webkitWebViewBaseRealize(GtkWidget* widget)
static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* widget)
{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+
+ GtkAllocation childAllocation;
+ gtk_widget_get_allocation(widget, &childAllocation);
+ priv->children.set(widget, childAllocation);
+
gtk_widget_set_parent(widget, GTK_WIDGET(container));
}
+static void webkitWebViewBaseContainerRemove(GtkContainer* container, GtkWidget* widget)
+{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+ GtkWidget* widgetContainer = GTK_WIDGET(container);
+
+ ASSERT(priv->children.contains(widget));
+ gboolean wasVisible = gtk_widget_get_visible(widget);
+ gtk_widget_unparent(widget);
+
+ priv->children.remove(widget);
+ if (wasVisible && gtk_widget_get_visible(widgetContainer))
+ gtk_widget_queue_resize(widgetContainer);
+}
+
+static void webkitWebViewBaseContainerForall(GtkContainer* container, gboolean includeInternals, GtkCallback callback, gpointer callbackData)
+{
+ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
+ WebKitWebViewBasePrivate* priv = webView->priv;
+
+ WebKitWebViewChildrenMap children = priv->children;
+ WebKitWebViewChildrenMap::const_iterator end = children.end();
+ for (WebKitWebViewChildrenMap::const_iterator current = children.begin(); current != end; ++current)
+ (*callback)(current->first, callbackData);
+}
+
+void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* child, const IntRect& childRect)
+{
+ const IntRect& geometry = webView->priv->children.get(child);
+
+ if (geometry == childRect)
+ return;
+
+ webView->priv->children.set(child, childRect);
+ gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webView));
+}
+
static void webkitWebViewBaseFinalize(GObject* gobject)
{
WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(gobject);
@@ -203,10 +262,27 @@ static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr)
return FALSE;
}
-static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation)
+static void webkitWebViewBaseChildAllocate(GtkWidget* child, gpointer userData)
{
+ if (!gtk_widget_get_visible(child))
+ return;
+
+ WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(userData);
WebKitWebViewBasePrivate* priv = webViewBase->priv;
+ const IntRect& geometry = priv->children.get(child);
+ if (geometry.isEmpty())
+ return;
+
+ GtkAllocation childAllocation = geometry;
+ gtk_widget_size_allocate(child, &childAllocation);
+ priv->children.set(child, IntRect());
+}
+
+static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation)
+{
+ gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase);
+ WebKitWebViewBasePrivate* priv = webViewBase->priv;
if (priv->pageProxy->drawingArea())
priv->pageProxy->drawingArea()->setSize(IntSize(allocation->width, allocation->height), IntSize());
@@ -239,7 +315,6 @@ static void webkitWebViewBaseMap(GtkWidget* widget)
gtk_widget_get_allocation(widget, &allocation);
resizeWebKitWebViewBaseFromAllocation(webViewBase, &allocation);
webViewBase->priv->needsResizeOnMap = false;
-
}
static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event)
@@ -277,6 +352,20 @@ static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* e
WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
WebKitWebViewBasePrivate* priv = webViewBase->priv;
+#if ENABLE(FULLSCREEN_API)
+ if (priv->fullScreenModeActive) {
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ case GDK_KEY_f:
+ case GDK_KEY_F:
+ webkitWebViewBaseExitFullScreen(webViewBase);
+ return TRUE;
+ default:
+ break;
+ }
+ }
+#endif
+
// Since WebProcess key event handling is not synchronous, handle the event in two passes.
// When WebProcess processes the input event, it will call PageClientImpl::doneWithKeyEvent
// with event handled status which determines whether to pass the input event to parent or not
@@ -467,7 +556,8 @@ static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* con
return FALSE;
SandboxExtension::Handle handle;
- webViewBase->priv->pageProxy->performDrag(dragData.get(), String(), handle);
+ SandboxExtension::HandleArray sandboxExtensionForUpload;
+ webViewBase->priv->pageProxy->performDrag(dragData.get(), String(), handle, sandboxExtensionForUpload);
gtk_drag_finish(context, TRUE, FALSE, time);
return TRUE;
}
@@ -501,6 +591,8 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie
GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webkitWebViewBaseClass);
containerClass->add = webkitWebViewBaseContainerAdd;
+ containerClass->remove = webkitWebViewBaseContainerRemove;
+ containerClass->forall = webkitWebViewBaseContainerForall;
g_type_class_add_private(webkitWebViewBaseClass, sizeof(WebKitWebViewBasePrivate));
}
@@ -528,6 +620,10 @@ void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WKCont
priv->pageProxy = toImpl(context)->createWebPage(priv->pageClient.get(), toImpl(pageGroup));
priv->pageProxy->initializeWebPage();
+
+#if ENABLE(FULLSCREEN_API)
+ priv->pageProxy->fullScreenManager()->setWebView(webkitWebViewBase);
+#endif
}
void webkitWebViewBaseSetTooltipText(WebKitWebViewBase* webViewBase, const char* tooltip)
@@ -575,3 +671,50 @@ void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase)
{
webkitWebViewBase->priv->shouldForwardNextKeyEvent = TRUE;
}
+
+void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase)
+{
+#if ENABLE(FULLSCREEN_API)
+ WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
+ if (priv->fullScreenModeActive)
+ return;
+
+ if (!priv->fullScreenClient.willEnterFullScreen())
+ return;
+
+ WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
+ fullScreenManagerProxy->willEnterFullScreen();
+
+ GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
+ if (gtk_widget_is_toplevel(topLevelWindow))
+ gtk_window_fullscreen(GTK_WINDOW(topLevelWindow));
+ fullScreenManagerProxy->didEnterFullScreen();
+ priv->fullScreenModeActive = true;
+#endif
+}
+
+void webkitWebViewBaseExitFullScreen(WebKitWebViewBase* webkitWebViewBase)
+{
+#if ENABLE(FULLSCREEN_API)
+ WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
+ if (!priv->fullScreenModeActive)
+ return;
+
+ if (!priv->fullScreenClient.willExitFullScreen())
+ return;
+
+ WebFullScreenManagerProxy* fullScreenManagerProxy = priv->pageProxy->fullScreenManager();
+ fullScreenManagerProxy->willExitFullScreen();
+
+ GtkWidget* topLevelWindow = gtk_widget_get_toplevel(GTK_WIDGET(webkitWebViewBase));
+ if (gtk_widget_is_toplevel(topLevelWindow))
+ gtk_window_unfullscreen(GTK_WINDOW(topLevelWindow));
+ fullScreenManagerProxy->didExitFullScreen();
+ priv->fullScreenModeActive = false;
+#endif
+}
+
+void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase* webkitWebViewBase, const WKFullScreenClientGtk* wkClient)
+{
+ webkitWebViewBase->priv->fullScreenClient.initialize(wkClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index 3a9a40b86..cd4c1a1b5 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -28,28 +28,22 @@
#ifndef WebKitWebViewBasePrivate_h
#define WebKitWebViewBasePrivate_h
+#include "WebKitPrivate.h"
#include "WebKitWebViewBase.h"
#include "WebPageProxy.h"
-#include <WebKit2/WebKit2.h>
using namespace WebKit;
-G_BEGIN_DECLS
-
WebKitWebViewBase* webkitWebViewBaseCreate(WebContext*, WebPageGroup*);
-
GtkIMContext* webkitWebViewBaseGetIMContext(WebKitWebViewBase*);
-
WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase*);
-
void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WKContextRef, WKPageGroupRef);
-
void webkitWebViewBaseSetTooltipText(WebKitWebViewBase*, const char*);
-
void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase*);
-
void webkitWebViewBaseStartDrag(WebKitWebViewBase*, const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
-
-G_END_DECLS
+void webkitWebViewBaseChildMoveResize(WebKitWebViewBase*, GtkWidget*, const WebCore::IntRect&);
+void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*);
+void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*);
+void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase*, const WKFullScreenClientGtk*);
#endif // WebKitWebViewBasePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
index ad8ab2038..717d2c344 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h
@@ -45,5 +45,12 @@ WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& mess
void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*);
void webkitWebViewMouseTargetChanged(WebKitWebView*, WKHitTestResultRef, unsigned modifiers);
void webkitWebViewPrintFrame(WebKitWebView*, WKFrameRef);
+void webkitWebViewResourceLoadStarted(WebKitWebView*, WKFrameRef, uint64_t resourceIdentifier, WebKitURIRequest*, bool isMainResource);
+void webkitWebViewRunFileChooserRequest(WebKitWebView*, WebKitFileChooserRequest*);
+WebKitWebResource* webkitWebViewGetLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
+void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier);
+WebKitWebResource* webkitWebViewResourceLoadFinished(WebKitWebView*, uint64_t resourceIdentifier);
+bool webkitWebViewEnterFullScreen(WebKitWebView*);
+bool webkitWebViewLeaveFullScreen(WebKitWebView*);
#endif // WebKitWebViewPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
index 4a9cc798c..821127f3d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
@@ -26,8 +26,11 @@
<xi:include href="xml/WebKitResponsePolicyDecision.xml"/>
<xi:include href="xml/WebKitHitTestResult.xml"/>
<xi:include href="xml/WebKitPrintOperation.xml"/>
+ <xi:include href="xml/WebKitWebResource.xml"/>
<xi:include href="xml/WebKitError.xml"/>
+ <xi:include href="xml/WebKitFileChooserRequest.xml"/>
<xi:include href="xml/WebKitFindController.xml"/>
+ <xi:include href="xml/WebKitCookieManager.xml"/>
</chapter>
<index id="index-all">
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
index a8f54083a..dc5e65ac6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
@@ -28,6 +28,7 @@ webkit_web_context_get_default
webkit_web_context_get_cache_model
webkit_web_context_set_cache_model
webkit_web_context_download_uri
+webkit_web_context_get_cookie_manager
<SUBSECTION Standard>
WebKitWebContextClass
@@ -49,8 +50,6 @@ webkit_web_context_get_type
WebKitWebView
WebKitLoadEvent
WebKitPolicyDecisionType
-WebKitScriptDialog
-WebKitScriptDialogType
<SUBSECTION Editing Commands>
WEBKIT_EDITING_COMMAND_CUT
@@ -89,11 +88,27 @@ webkit_web_view_can_execute_editing_command
webkit_web_view_can_execute_editing_command_finish
webkit_web_view_execute_editing_command
webkit_web_view_get_find_controller
+webkit_web_view_get_javascript_global_context
+webkit_web_view_run_javascript
+webkit_web_view_run_javascript_finish
+
+<SUBSECTION WebKitJavascriptResult>
+WebKitJavascriptResult
+webkit_javascript_result_ref
+webkit_javascript_result_unref
+webkit_javascript_result_get_global_context
+webkit_javascript_result_get_value
+
+<SUBSECTION WebKitScriptDialog>
+WebKitScriptDialog
+WebKitScriptDialogType
webkit_script_dialog_get_dialog_type
webkit_script_dialog_get_message
webkit_script_dialog_confirm_set_confirmed
webkit_script_dialog_prompt_get_default_text
webkit_script_dialog_prompt_set_text
+webkit_web_view_get_main_resource
+webkit_web_view_get_subresources
<SUBSECTION Standard>
WebKitWebViewClass
@@ -103,10 +118,12 @@ WEBKIT_TYPE_WEB_VIEW
WEBKIT_WEB_VIEW_CLASS
WEBKIT_IS_WEB_VIEW_CLASS
WEBKIT_WEB_VIEW_GET_CLASS
+WEBKIT_TYPE_JAVASCRIPT_RESULT
WEBKIT_TYPE_SCRIPT_DIALOG
<SUBSECTION Private>
webkit_web_view_get_type
+webkit_javascript_result_get_type
webkit_script_dialog_get_type
WebKitWebViewPrivate
</SECTION>
@@ -232,6 +249,8 @@ webkit_settings_get_enable_webgl
webkit_settings_set_enable_webgl
webkit_settings_get_zoom_text_only
webkit_settings_set_zoom_text_only
+webkit_settings_get_javascript_can_access_clipboard
+webkit_settings_set_javascript_can_access_clipboard
<SUBSECTION Standard>
WebKitSettingsClass
@@ -458,19 +477,71 @@ webkit_print_operation_get_type
</SECTION>
<SECTION>
+<FILE>WebKitWebResource</FILE>
+WebKitWebResource
+webkit_web_resource_get_uri
+webkit_web_resource_get_response
+webkit_web_resource_get_data
+webkit_web_resource_get_data_finish
+
+<SUBSECTION Standard>
+WebKitWebResourceClass
+WEBKIT_TYPE_WEB_RESOURCE
+WEBKIT_WEB_RESOURCE
+WEBKIT_IS_WEB_RESOURCE
+WEBKIT_WEB_RESOURCE_CLASS
+WEBKIT_IS_WEB_RESOURCE_CLASS
+WEBKIT_WEB_RESOURCE_GET_CLASS
+
+<SUBSECTION Private>
+WebKitWebResourcePrivate
+webkit_web_resource_get_type
+</SECTION>
+
+<SECTION>
<FILE>WebKitError</FILE>
WEBKIT_NETWORK_ERROR
WEBKIT_PLUGIN_ERROR
WEBKIT_POLICY_ERROR
WEBKIT_DOWNLOAD_ERROR
+WEBKIT_PRINT_ERROR
+WEBKIT_JAVASCRIPT_ERROR
WebKitNetworkError
WebKitPluginError
WebKitPolicyError
WebKitDownloadError
+WebKitPrintError
+WebKitJavascriptError
webkit_network_error_quark
webkit_plugin_error_quark
webkit_policy_error_quark
webkit_download_error_quark
+webkit_print_error_quark
+webkit_javascript_error_quark
+</SECTION>
+
+<SECTION>
+<FILE>WebKitFileChooserRequest</FILE>
+WebKitFileChooserRequest
+webkit_file_chooser_request_get_mime_types
+webkit_file_chooser_request_get_mime_types_filter
+webkit_file_chooser_request_get_select_multiple
+webkit_file_chooser_request_select_files
+webkit_file_chooser_request_get_selected_files
+webkit_file_chooser_request_cancel
+
+<SUBSECTION Standard>
+WebKitFileChooserRequestClass
+WEBKIT_TYPE_FILE_CHOOSER_REQUEST
+WEBKIT_FILE_CHOOSER_REQUEST
+WEBKIT_IS_FILE_CHOOSER_REQUEST
+WEBKIT_FILE_CHOOSER_REQUEST_CLASS
+WEBKIT_IS_FILE_CHOOSER_REQUEST_CLASS
+WEBKIT_FILE_CHOOSER_REQUEST_GET_CLASS
+
+<SUBSECTION Private>
+WebKitFileChooserRequestPrivate
+webkit_file_chooser_request_get_type
</SECTION>
<SECTION>
@@ -500,3 +571,29 @@ WEBKIT_FIND_CONTROLLER_GET_CLASS
WebKitFindControllerPrivate
webkit_find_controller_get_type
</SECTION>
+
+<SECTION>
+<FILE>WebKitCookieManager</FILE>
+WebKitCookieManager
+WebKitCookieAcceptPolicy
+webkit_cookie_manager_set_accept_policy
+webkit_cookie_manager_get_accept_policy
+webkit_cookie_manager_get_accept_policy_finish
+webkit_cookie_manager_get_domains_with_cookies
+webkit_cookie_manager_get_domains_with_cookies_finish
+webkit_cookie_manager_delete_cookies_for_domain
+webkit_cookie_manager_delete_all_cookies
+
+<SUBSECTION Standard>
+WebKitCookieManagerClass
+WEBKIT_TYPE_COOKIE_MANAGER
+WEBKIT_COOKIE_MANAGER
+WEBKIT_IS_COOKIE_MANAGER
+WEBKIT_COOKIE_MANAGER_CLASS
+WEBKIT_IS_COOKIE_MANAGER_CLASS
+WEBKIT_COOKIE_MANAGER_GET_CLASS
+
+<SUBSECTION Private>
+WebKitCookieManagerPrivate
+webkit_cookie_manager_get_type
+</SECTION>
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
index 8e8d7b13a..1ca821b47 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
@@ -9,5 +9,9 @@ webkit_uri_response_get_type
webkit_uri_request_get_type
webkit_window_properties_get_type
webkit_download_get_type
+webkit_file_chooser_request_get_type
webkit_find_controller_get_type
webkit_script_dialog_get_type
+webkit_javascript_result_get_type
+webkit_web_resource_get_type
+webkit_cookie_manager_get_type
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
index 6adb2d5cd..b389f4954 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
@@ -2,9 +2,11 @@ if ENABLE_WEBKIT2
TEST_PROGS += \
Programs/WebKit2APITests/TestBackForwardList \
+ Programs/WebKit2APITests/TestCookieManager \
Programs/WebKit2APITests/TestDownloads \
Programs/WebKit2APITests/TestLoaderClient \
Programs/WebKit2APITests/TestPrinting \
+ Programs/WebKit2APITests/TestResources \
Programs/WebKit2APITests/TestWebKitFindController \
Programs/WebKit2APITests/TestWebKitPolicyClient \
Programs/WebKit2APITests/TestWebKitSettings \
@@ -135,4 +137,16 @@ Programs_WebKit2APITests_TestWebKitFindController_CPPFLAGS = $(webkit2_tests_cpp
Programs_WebKit2APITests_TestWebKitFindController_LDADD = $(webkit2_tests_ldadd)
Programs_WebKit2APITests_TestWebKitFindController_LDFLAGS = $(webkit2_tests_ldflags)
+Programs_WebKit2APITests_TestResources_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
+Programs_WebKit2APITests_TestResources_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestResources_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestResources_LDFLAGS = $(webkit2_tests_ldflags)
+
+Programs_WebKit2APITests_TestCookieManager_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
+Programs_WebKit2APITests_TestCookieManager_CPPFLAGS = $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestCookieManager_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestCookieManager_LDFLAGS = $(webkit2_tests_ldflags)
+
endif # ENABLE_WEBKIT2
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
new file mode 100644
index 000000000..6d2ecf528
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2012 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 "WebKitTestServer.h"
+#include "WebViewTest.h"
+
+static WebKitTestServer* kServer;
+
+static const char* kFirstPartyDomain = "127.0.0.1";
+static const char* kThirdPartyDomain = "localhost";
+static const char* kIndexHtmlFormat =
+ "<html><body>"
+ " <p>WebKitGTK+ Cookie Manager test</p>"
+ " <img src='http://localhost:%u/image.png' width=5 height=5></img>"
+ "</body></html>";
+
+class CookieManagerTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(CookieManagerTest);
+
+ static void cookiesChangedCallback(WebKitCookieManager*, CookieManagerTest* test)
+ {
+ test->m_cookiesChanged = true;
+ if (test->m_finishLoopWhenCookiesChange)
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ CookieManagerTest()
+ : WebViewTest()
+ , m_cookieManager(webkit_web_context_get_cookie_manager(webkit_web_view_get_context(m_webView)))
+ , m_acceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY)
+ , m_domains(0)
+ , m_cookiesChanged(false)
+ , m_finishLoopWhenCookiesChange(false)
+ {
+ g_signal_connect(m_cookieManager, "changed", G_CALLBACK(cookiesChangedCallback), this);
+ }
+
+ ~CookieManagerTest()
+ {
+ g_strfreev(m_domains);
+ g_signal_handlers_disconnect_matched(m_cookieManager, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ }
+
+ static void getAcceptPolicyReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ GOwnPtr<GError> error;
+ WebKitCookieAcceptPolicy policy = webkit_cookie_manager_get_accept_policy_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr());
+ g_assert(!error.get());
+
+ CookieManagerTest* test = static_cast<CookieManagerTest*>(userData);
+ test->m_acceptPolicy = policy;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ WebKitCookieAcceptPolicy getAcceptPolicy()
+ {
+ m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+ webkit_cookie_manager_get_accept_policy(m_cookieManager, getAcceptPolicyReadyCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_acceptPolicy;
+ }
+
+ void setAcceptPolicy(WebKitCookieAcceptPolicy policy)
+ {
+ webkit_cookie_manager_set_accept_policy(m_cookieManager, policy);
+ }
+
+ static void getDomainsReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ GOwnPtr<GError> error;
+ char** domains = webkit_cookie_manager_get_domains_with_cookies_finish(WEBKIT_COOKIE_MANAGER(object), result, &error.outPtr());
+ g_assert(!error.get());
+
+ CookieManagerTest* test = static_cast<CookieManagerTest*>(userData);
+ test->m_domains = domains;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ char** getDomains()
+ {
+ g_strfreev(m_domains);
+ m_domains = 0;
+ webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, getDomainsReadyCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_domains;
+ }
+
+ void deleteCookiesForDomain(const char* domain)
+ {
+ webkit_cookie_manager_delete_cookies_for_domain(m_cookieManager, domain);
+ }
+
+ void deleteAllCookies()
+ {
+ webkit_cookie_manager_delete_all_cookies(m_cookieManager);
+ }
+
+ void waitUntilCookiesChanged()
+ {
+ m_cookiesChanged = false;
+ m_finishLoopWhenCookiesChange = true;
+ g_main_loop_run(m_mainLoop);
+ m_finishLoopWhenCookiesChange = false;
+ }
+
+ WebKitCookieManager* m_cookieManager;
+ WebKitCookieAcceptPolicy m_acceptPolicy;
+ char** m_domains;
+ bool m_cookiesChanged;
+ bool m_finishLoopWhenCookiesChange;
+};
+
+static void testCookieManagerAcceptPolicy(CookieManagerTest* test, gconstpointer)
+{
+ // Default policy is NO_THIRD_PARTY.
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ char** domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 1);
+ g_assert_cmpstr(domains[0], ==, kFirstPartyDomain);
+ test->deleteAllCookies();
+
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 2);
+ g_assert_cmpstr(domains[0], ==, kFirstPartyDomain);
+ g_assert_cmpstr(domains[1], ==, kThirdPartyDomain);
+ test->deleteAllCookies();
+
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER);
+ g_assert_cmpint(test->getAcceptPolicy(), ==, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ domains = test->getDomains();
+ g_assert(domains);
+ g_assert_cmpint(g_strv_length(domains), ==, 0);
+}
+
+static void testCookieManagerDeleteCookies(CookieManagerTest* test, gconstpointer)
+{
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2);
+
+ // Delete first party cookies.
+ test->deleteCookiesForDomain(kFirstPartyDomain);
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 1);
+
+ // Delete third party cookies.
+ test->deleteCookiesForDomain(kThirdPartyDomain);
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0);
+
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 2);
+
+ // Delete all cookies.
+ test->deleteAllCookies();
+ g_assert_cmpint(g_strv_length(test->getDomains()), ==, 0);
+}
+
+static void testCookieManagerCookiesChanged(CookieManagerTest* test, gconstpointer)
+{
+ g_assert(!test->m_cookiesChanged);
+ test->setAcceptPolicy(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS);
+ test->loadURI(kServer->getURIForPath("/index.html").data());
+ test->waitUntilLoadFinished();
+ g_assert(test->m_cookiesChanged);
+
+ test->deleteCookiesForDomain(kFirstPartyDomain);
+ test->waitUntilCookiesChanged();
+ g_assert(test->m_cookiesChanged);
+
+ test->deleteAllCookies();
+ test->waitUntilCookiesChanged();
+ g_assert(test->m_cookiesChanged);
+}
+
+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;
+ }
+
+ soup_message_set_status(message, SOUP_STATUS_OK);
+ if (g_str_equal(path, "/index.html")) {
+ char* indexHtml = g_strdup_printf(kIndexHtmlFormat, soup_server_get_port(server));
+ soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar");
+ soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, indexHtml, strlen(indexHtml));
+ } else if (g_str_equal(path, "/image.png"))
+ soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux");
+ else
+ g_assert_not_reached();
+ soup_message_body_complete(message->response_body);
+}
+
+void beforeAll()
+{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
+ CookieManagerTest::add("WebKitCookieManager", "accept-policy", testCookieManagerAcceptPolicy);
+ CookieManagerTest::add("WebKitCookieManager", "delete-cookies", testCookieManagerDeleteCookies);
+ CookieManagerTest::add("WebKitCookieManager", "cookies-changed", testCookieManagerCookiesChanged);
+}
+
+void afterAll()
+{
+ delete kServer;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
index 461cefa0e..a119e4477 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestDownloads.cpp
@@ -173,15 +173,9 @@ public:
guint64 m_downloadSize;
};
-static CString getWebKit1TestResoucesDir()
-{
- GOwnPtr<char> resourcesDir(g_build_filename(WEBKIT_SRC_DIR, "Source", "WebKit", "gtk", "tests", "resources", NULL));
- return resourcesDir.get();
-}
-
static void testDownloadLocalFile(DownloadTest* test, gconstpointer)
{
- GOwnPtr<char> sourcePath(g_build_filename(getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
+ GOwnPtr<char> sourcePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
GRefPtr<GFileInfo> sourceInfo = adoptGRef(g_file_query_info(source.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0));
GOwnPtr<char> sourceURI(g_file_get_uri(source.get()));
@@ -258,7 +252,7 @@ static void testDownloadLocalFileError(DownloadErrorTest* test, gconstpointer)
g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
test->m_expectedError = WEBKIT_DOWNLOAD_ERROR_DESTINATION;
- GOwnPtr<char> path(g_build_filename(getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
+ GOwnPtr<char> path(g_build_filename(Test::getWebKit1TestResoucesDir().data(), "test.pdf", NULL));
GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get()));
GOwnPtr<char> uri(g_file_get_uri(file.get()));
download = adoptGRef(webkit_web_context_download_uri(test->m_webContext, uri.get()));
@@ -301,7 +295,7 @@ static void serverCallback(SoupServer* server, SoupMessage* message, const char*
return;
}
- GOwnPtr<char> filePath(g_build_filename(getWebKit1TestResoucesDir().data(), path, NULL));
+ GOwnPtr<char> filePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), path, NULL));
char* contents;
gsize contentsLength;
if (!g_file_get_contents(filePath.get(), &contents, &contentsLength, 0)) {
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h b/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
index 39a2000ac..219cb44ed 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestMain.h
@@ -20,9 +20,10 @@
#ifndef TestMain_h
#define TestMain_h
-#include <JavaScriptCore/GOwnPtr.h>
-#include <JavaScriptCore/HashSet.h>
#include <glib-object.h>
+#include <wtf/HashSet.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/text/CString.h>
#define MAKE_GLIB_TEST_FIXTURE(ClassName) \
static void setUp(ClassName* fixture, gconstpointer data) \
@@ -45,6 +46,15 @@ public:
~Test()
{
+ if (m_watchedObjects.isEmpty())
+ return;
+
+ g_print("Leaked objects:");
+ HashSet<GObject*>::const_iterator end = m_watchedObjects.end();
+ for (HashSet<GObject*>::const_iterator it = m_watchedObjects.begin(); it != end; ++it)
+ g_print(" %s(%p)", g_type_name_from_instance(reinterpret_cast<GTypeInstance*>(*it)), *it);
+ g_print("\n");
+
g_assert(m_watchedObjects.isEmpty());
}
@@ -59,6 +69,12 @@ public:
g_object_weak_ref(object, reinterpret_cast<GWeakNotify>(objectFinalized), this);
}
+ static CString getWebKit1TestResoucesDir()
+ {
+ GOwnPtr<char> resourcesDir(g_build_filename(WEBKIT_SRC_DIR, "Source", "WebKit", "gtk", "tests", "resources", NULL));
+ return resourcesDir.get();
+ }
+
HashSet<GObject*> m_watchedObjects;
};
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
index 1ddde0858..150c31bd3 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp
@@ -72,37 +72,63 @@ static void testWebViewPrintRequested(WebViewTest* test, gconstpointer)
}
#ifdef HAVE_GTK_UNIX_PRINTING
-static void testPrintOperationPrintLoadChanged(WebKitWebView*, WebKitLoadEvent loadEvent, WebViewTest* test)
-{
- if (loadEvent != WEBKIT_LOAD_FINISHED)
- return;
- g_main_loop_quit(test->m_mainLoop);
-}
+class PrintTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(PrintTest);
-static void testPrintOperationPrintFinished(WebKitPrintOperation* printOperation, WebViewTest* test)
-{
- g_object_unref(printOperation);
- g_main_loop_quit(test->m_mainLoop);
-}
+ static void printFinishedCallback(WebKitPrintOperation*, PrintTest* test)
+ {
+ g_main_loop_quit(test->m_mainLoop);
+ }
-static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
-{
- if (strcmp(gtk_printer_get_name(printer), "Print to File"))
- return FALSE;
+ static void printFailedCallback(WebKitPrintOperation*, GError* error, PrintTest* test)
+ {
+ g_assert(test->m_expectedError);
+ g_assert(error);
+ g_assert(g_error_matches(error, WEBKIT_PRINT_ERROR, test->m_expectedError));
+ }
- GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
- *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
- return TRUE;
-}
+ PrintTest()
+ : m_expectedError(0)
+ {
+ m_printOperation = adoptGRef(webkit_print_operation_new(m_webView));
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get()));
+ g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printFinishedCallback), this);
+ g_signal_connect(m_printOperation.get(), "failed", G_CALLBACK(printFailedCallback), this);
+ }
+
+ static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
+ {
+ if (strcmp(gtk_printer_get_name(printer), "Print to File"))
+ return FALSE;
+
+ GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
+ *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
+ return TRUE;
+ }
+
+ GtkPrinter* findPrintToFilePrinter()
+ {
+ GtkPrinter* printer = 0;
+ gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+ return printer;
+ }
-static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
+ void waitUntilPrintFinished()
+ {
+ g_main_loop_run(m_mainLoop);
+ }
+
+ GRefPtr<WebKitPrintOperation> m_printOperation;
+ unsigned int m_expectedError;
+};
+
+static void testPrintOperationPrint(PrintTest* test, gconstpointer)
{
- g_signal_connect(test->m_webView, "load-changed", G_CALLBACK(testPrintOperationPrintLoadChanged), test);
test->loadHtml("<html><body>WebKitGTK+ printing test</body></html>", 0);
- g_main_loop_run(test->m_mainLoop);
+ test->waitUntilLoadFinished();
- GtkPrinter* printer = 0;
- gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+ GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
if (!printer) {
g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
return;
@@ -113,16 +139,12 @@ static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
GOwnPtr<char> outputURI(g_file_get_uri(outputFile.get()));
GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
- gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer));
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get());
- g_object_unref(printer);
- GRefPtr<WebKitPrintOperation> printOperation = webkit_print_operation_new(test->m_webView);
- test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation.get()));
- g_signal_connect(printOperation.get(), "finished", G_CALLBACK(testPrintOperationPrintFinished), test);
- webkit_print_operation_set_print_settings(printOperation.get(), printSettings.get());
- webkit_print_operation_print(printOperation.get());
- g_main_loop_run(test->m_mainLoop);
+ webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(outputFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE","G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
static_cast<GFileQueryInfoFlags>(0), 0, 0));
@@ -132,6 +154,40 @@ static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
g_file_delete(outputFile.get(), 0, 0);
}
+
+static void testPrintOperationErrors(PrintTest* test, gconstpointer)
+{
+ test->loadHtml("<html><body>WebKitGTK+ printing errors test</body></html>", 0);
+ test->waitUntilLoadFinished();
+
+ GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
+ if (!printer) {
+ g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
+ return;
+ }
+
+ // General Error: invalid filename.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_GENERAL;
+ GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+ gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, "file:///foo/bar");
+ webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+
+ // Printer not found error.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND;
+ gtk_print_settings_set_printer(printSettings.get(), "The fake WebKit printer");
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+
+ // No pages to print: print even pages for a single page document.
+ test->m_expectedError = WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE;
+ gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+ gtk_print_settings_set_page_set(printSettings.get(), GTK_PAGE_SET_EVEN);
+ webkit_print_operation_print(test->m_printOperation.get());
+ test->waitUntilPrintFinished();
+}
#endif // HAVE_GTK_UNIX_PRINTING
void beforeAll()
@@ -142,7 +198,8 @@ void beforeAll()
WebViewTest::add("WebKitPrintOperation", "printing-settings", testPrintOperationPrintSettings);
WebViewTest::add("WebKitWebView", "print-requested", testWebViewPrintRequested);
#ifdef HAVE_GTK_UNIX_PRINTING
- WebViewTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+ PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+ PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors);
#endif
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
new file mode 100644
index 000000000..cc272c9e8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2012 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 "WebKitTestServer.h"
+#include "WebViewTest.h"
+#include <wtf/gobject/GRefPtr.h>
+
+static WebKitTestServer* kServer;
+
+static const char* kIndexHtml =
+ "<html><head>"
+ " <link rel='stylesheet' href='/style.css' type='text/css'>"
+ " <script language='javascript' src='/javascript.js'></script>"
+ "</head><body>WebKitGTK+ resources test</body></html>";
+
+static const char* kStyleCSS =
+ "body {"
+ " margin: 0px;"
+ " padding: 0px;"
+ " font-family: sans-serif;"
+ " background: url(/blank.ico) 0 0 no-repeat;"
+ " color: black;"
+ "}";
+
+static const char* kJavascript = "function foo () { var a = 1; }";
+
+class ResourcesTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ResourcesTest);
+
+ static void resourceSentRequestCallback(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, ResourcesTest* test)
+ {
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ if (redirectResponse)
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(redirectResponse));
+ test->resourceSentRequest(resource, request, redirectResponse);
+ }
+
+ static void resourceReceivedResponseCallback(WebKitWebResource* resource, GParamSpec*, ResourcesTest* test)
+ {
+ g_assert(webkit_web_resource_get_response(resource));
+ test->resourceReceivedResponse(resource);
+ }
+
+ static void resourceReceivedDataCallback(WebKitWebResource* resource, guint64 bytesReceived, ResourcesTest* test)
+ {
+ test->resourceReceivedData(resource, bytesReceived);
+ }
+
+ static void resourceFinishedCallback(WebKitWebResource* resource, ResourcesTest* test)
+ {
+ test->resourceFinished(resource);
+ }
+
+ static void resourceFailedCallback(WebKitWebResource* resource, GError* error, ResourcesTest* test)
+ {
+ g_assert(error);
+ test->resourceFailed(resource, error);
+ }
+
+ static void resourceLoadStartedCallback(WebKitWebView* webView, WebKitWebResource* resource, WebKitURIRequest* request, ResourcesTest* test)
+ {
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(resource));
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ test->resourceLoadStarted(resource, request);
+ g_signal_connect(resource, "sent-request", G_CALLBACK(resourceSentRequestCallback), test);
+ g_signal_connect(resource, "notify::response", G_CALLBACK(resourceReceivedResponseCallback), test);
+ g_signal_connect(resource, "received-data", G_CALLBACK(resourceReceivedDataCallback), test);
+ g_signal_connect(resource, "finished", G_CALLBACK(resourceFinishedCallback), test);
+ g_signal_connect(resource, "failed", G_CALLBACK(resourceFailedCallback), test);
+ }
+
+ ResourcesTest()
+ : WebViewTest()
+ , m_resourcesLoaded(0)
+ , m_resourcesToLoad(0)
+ , m_resourceDataSize(0)
+ {
+ g_signal_connect(m_webView, "resource-load-started", G_CALLBACK(resourceLoadStartedCallback), this);
+ }
+
+ virtual void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ }
+
+ virtual void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ }
+
+ virtual void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ }
+
+ virtual void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ }
+
+ virtual void resourceFinished(WebKitWebResource* resource)
+ {
+ g_signal_handlers_disconnect_matched(resource, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ if (++m_resourcesLoaded == m_resourcesToLoad)
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ virtual void resourceFailed(WebKitWebResource* resource, GError* error)
+ {
+ g_assert_not_reached();
+ }
+
+ void waitUntilResourcesLoaded(size_t resourcesCount)
+ {
+ m_resourcesLoaded = 0;
+ m_resourcesToLoad = resourcesCount;
+ g_main_loop_run(m_mainLoop);
+ }
+
+ static void resourceGetDataCallback(GObject* object, GAsyncResult* result, gpointer userData)
+ {
+ size_t dataSize;
+ GOwnPtr<GError> error;
+ unsigned char* data = webkit_web_resource_get_data_finish(WEBKIT_WEB_RESOURCE(object), result, &dataSize, &error.outPtr());
+ g_assert(!error.get());
+ g_assert(data);
+ g_assert_cmpint(dataSize, >, 0);
+
+ ResourcesTest* test = static_cast<ResourcesTest*>(userData);
+ test->m_resourceData.set(reinterpret_cast<char*>(data));
+ test->m_resourceDataSize = dataSize;
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ void checkResourceData(WebKitWebResource* resource)
+ {
+ m_resourceDataSize = 0;
+ webkit_web_resource_get_data(resource, resourceGetDataCallback, this);
+ g_main_loop_run(m_mainLoop);
+
+ const char* uri = webkit_web_resource_get_uri(resource);
+ if (uri == kServer->getURIForPath("/")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kIndexHtml));
+ g_assert(!strncmp(m_resourceData.get(), kIndexHtml, m_resourceDataSize));
+ } else if (uri == kServer->getURIForPath("/style.css")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kStyleCSS));
+ g_assert(!strncmp(m_resourceData.get(), kStyleCSS, m_resourceDataSize));
+ } else if (uri == kServer->getURIForPath("/javascript.js")) {
+ g_assert_cmpint(m_resourceDataSize, ==, strlen(kJavascript));
+ g_assert(!strncmp(m_resourceData.get(), kJavascript, m_resourceDataSize));
+ } else
+ g_assert_not_reached();
+ m_resourceData.clear();
+ }
+
+ size_t m_resourcesLoaded;
+ size_t m_resourcesToLoad;
+ GOwnPtr<char> m_resourceData;
+ size_t m_resourceDataSize;
+};
+
+static void testWebViewResources(ResourcesTest* test, gconstpointer)
+{
+ // Nothing loaded yet, there shoulnd't be resources.
+ g_assert(!webkit_web_view_get_main_resource(test->m_webView));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+
+ // Load simple page without subresources.
+ test->loadHtml("<html><body>Testing WebKitGTK+</body></html>", 0);
+ test->waitUntilLoadFinished();
+ WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+
+ // Load simple page with subresources.
+ test->loadURI(kServer->getURIForPath("/").data());
+ test->waitUntilResourcesLoaded(4);
+
+ resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ g_assert_cmpstr(webkit_web_view_get_uri(test->m_webView), ==, webkit_web_resource_get_uri(resource));
+ GOwnPtr<GList> subresources(webkit_web_view_get_subresources(test->m_webView));
+ g_assert(subresources);
+ g_assert_cmpint(g_list_length(subresources.get()), ==, 3);
+
+#if 0
+ // Load the same URI again.
+ // FIXME: we need a workaround for bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->loadURI(kServer->getURIForPath("/").data());
+ test->waitUntilResourcesLoaded(4);
+#endif
+
+ // Reload.
+ webkit_web_view_reload(test->m_webView);
+ test->waitUntilResourcesLoaded(4);
+}
+
+class SingleResourceLoadTest: public ResourcesTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(SingleResourceLoadTest);
+
+ enum LoadEvents {
+ Started,
+ SentRequest,
+ Redirected,
+ ReceivedResponse,
+ ReceivedData,
+ Finished,
+ Failed
+ };
+
+ SingleResourceLoadTest()
+ : ResourcesTest()
+ , m_resourceDataReceived(0)
+ {
+ m_resourcesToLoad = 2;
+ }
+
+ void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ if (resource == webkit_web_view_get_main_resource(m_webView))
+ return;
+
+ m_resourceDataReceived = 0;
+ m_resource = resource;
+ m_loadEvents.append(Started);
+ }
+
+ void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ if (resource != m_resource)
+ return;
+
+ if (redirectResponse)
+ m_loadEvents.append(Redirected);
+ else
+ m_loadEvents.append(SentRequest);
+ }
+
+ void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ if (resource != m_resource)
+ return;
+
+ m_loadEvents.append(ReceivedResponse);
+ }
+
+ void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ if (resource != m_resource)
+ return;
+
+ m_resourceDataReceived += bytesReceived;
+ if (!m_loadEvents.contains(ReceivedData))
+ m_loadEvents.append(ReceivedData);
+ }
+
+ void resourceFinished(WebKitWebResource* resource)
+ {
+ if (resource != m_resource) {
+ ResourcesTest::resourceFinished(resource);
+ return;
+ }
+
+ if (!m_loadEvents.contains(Failed)) {
+ WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get());
+ g_assert(response);
+ g_assert_cmpint(webkit_uri_response_get_content_length(response), ==, m_resourceDataReceived);
+ }
+ m_loadEvents.append(Finished);
+ ResourcesTest::resourceFinished(resource);
+ }
+
+ void resourceFailed(WebKitWebResource* resource, GError* error)
+ {
+ if (resource == m_resource)
+ m_loadEvents.append(Failed);
+ }
+
+ void waitUntilResourceLoadFinsihed()
+ {
+ m_resource = 0;
+ m_resourcesLoaded = 0;
+ g_main_loop_run(m_mainLoop);
+ }
+
+ int waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse()
+ {
+ waitUntilResourceLoadFinsihed();
+ g_assert(m_resource);
+ WebKitURIResponse* response = webkit_web_resource_get_response(m_resource.get());
+ g_assert(response);
+ return webkit_uri_response_get_status_code(response);
+ }
+
+ GRefPtr<WebKitWebResource> m_resource;
+ Vector<LoadEvents> m_loadEvents;
+ guint64 m_resourceDataReceived;
+};
+
+static void testWebResourceLoading(SingleResourceLoadTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ Vector<SingleResourceLoadTest::LoadEvents>& events = test->m_loadEvents;
+ g_assert_cmpint(events.size(), ==, 5);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::ReceivedResponse);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedData);
+ g_assert_cmpint(events[4], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+
+ test->loadURI(kServer->getURIForPath("/redirected-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ g_assert_cmpint(events.size(), ==, 6);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Redirected);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::ReceivedResponse);
+ g_assert_cmpint(events[4], ==, SingleResourceLoadTest::ReceivedData);
+ g_assert_cmpint(events[5], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+
+ test->loadURI(kServer->getURIForPath("/invalid-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+ g_assert(test->m_resource);
+ g_assert_cmpint(events.size(), ==, 4);
+ g_assert_cmpint(events[0], ==, SingleResourceLoadTest::Started);
+ g_assert_cmpint(events[1], ==, SingleResourceLoadTest::SentRequest);
+ g_assert_cmpint(events[2], ==, SingleResourceLoadTest::Failed);
+ g_assert_cmpint(events[3], ==, SingleResourceLoadTest::Finished);
+ events.clear();
+}
+
+static void testWebResourceResponse(SingleResourceLoadTest* test, gconstpointer)
+{
+ // No cached resource: First load.
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ gint statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // No cached resource: Second load.
+ test->loadURI(kServer->getURIForPath("/javascript.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // No cached resource: Reload.
+ webkit_web_view_reload(test->m_webView);
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: First load.
+ test->loadURI(kServer->getURIForPath("/image.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: Second load.
+ test->loadURI(kServer->getURIForPath("/image.html").data());
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_OK);
+
+ // Cached resource: Reload.
+ webkit_web_view_reload(test->m_webView);
+ statusCode = test->waitUntilResourceLoadFinsihedAndReturnHTTPStatusResponse();
+ g_assert_cmpint(statusCode, ==, SOUP_STATUS_NOT_MODIFIED);
+}
+
+class ResourceURITrackingTest: public SingleResourceLoadTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ResourceURITrackingTest);
+
+ ResourceURITrackingTest()
+ : SingleResourceLoadTest()
+ {
+ }
+
+ static void uriChanged(WebKitWebResource* resource, GParamSpec*, ResourceURITrackingTest* test)
+ {
+ g_assert(resource == test->m_resource.get());
+ g_assert_cmpstr(test->m_activeURI.data(), !=, webkit_web_resource_get_uri(test->m_resource.get()));
+ test->m_activeURI = webkit_web_resource_get_uri(test->m_resource.get());
+ }
+
+ void resourceLoadStarted(WebKitWebResource* resource, WebKitURIRequest* request)
+ {
+ if (resource == webkit_web_view_get_main_resource(m_webView))
+ return;
+
+ m_resource = resource;
+ m_activeURI = webkit_web_resource_get_uri(resource);
+ checkActiveURI("/redirected.css");
+ g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request));
+ g_signal_connect(resource, "notify::uri", G_CALLBACK(uriChanged), this);
+ }
+
+ void resourceSentRequest(WebKitWebResource* resource, WebKitURIRequest* request, WebKitURIResponse* redirectResponse)
+ {
+ if (resource != m_resource)
+ return;
+
+ if (redirectResponse)
+ checkActiveURI("/simple-style.css");
+ else
+ checkActiveURI("/redirected.css");
+ g_assert_cmpstr(m_activeURI.data(), ==, webkit_uri_request_get_uri(request));
+ }
+
+ void resourceReceivedResponse(WebKitWebResource* resource)
+ {
+ if (resource != m_resource)
+ return;
+
+ checkActiveURI("/simple-style.css");
+ }
+
+ void resourceReceivedData(WebKitWebResource* resource, guint64 bytesReceived)
+ {
+ }
+
+ void resourceFinished(WebKitWebResource* resource)
+ {
+ if (resource == m_resource)
+ checkActiveURI("/simple-style.css");
+ ResourcesTest::resourceFinished(resource);
+ }
+
+ void resourceFailed(WebKitWebResource*, GError*)
+ {
+ g_assert_not_reached();
+ }
+
+ CString m_activeURI;
+
+private:
+ void checkActiveURI(const char* uri)
+ {
+ // g_assert_cmpstr is a macro, so we need to cache the temporary string.
+ CString serverURI = kServer->getURIForPath(uri);
+ g_assert_cmpstr(m_activeURI.data(), ==, serverURI.data());
+ }
+};
+
+static void testWebResourceActiveURI(ResourceURITrackingTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/redirected-css.html").data());
+ test->waitUntilResourceLoadFinsihed();
+}
+
+static void testWebResourceGetData(ResourcesTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/").data());
+ // FIXME: this should be 4 instead of 3, but we don't get the css image resource
+ // due to bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->waitUntilResourcesLoaded(3);
+
+ WebKitWebResource* resource = webkit_web_view_get_main_resource(test->m_webView);
+ g_assert(resource);
+ test->checkResourceData(resource);
+
+ GOwnPtr<GList> subresources(webkit_web_view_get_subresources(test->m_webView));
+ for (GList* item = subresources.get(); item; item = g_list_next(item))
+ test->checkResourceData(WEBKIT_WEB_RESOURCE(item->data));
+}
+
+static void replacedContentResourceLoadStartedCallback()
+{
+ g_assert_not_reached();
+}
+
+static void testWebViewResourcesReplacedContent(ResourcesTest* test, gconstpointer)
+{
+ test->loadURI(kServer->getURIForPath("/").data());
+ // FIXME: this should be 4 instead of 3, but we don't get the css image resource
+ // due to bug https://bugs.webkit.org/show_bug.cgi?id=78510.
+ test->waitUntilResourcesLoaded(3);
+
+ static const char* replacedHtml =
+ "<html><head>"
+ " <title>Content Replaced</title>"
+ " <link rel='stylesheet' href='data:text/css,body { margin: 0px; padding: 0px; }' type='text/css'>"
+ " <script language='javascript' src='data:application/javascript,function foo () { var a = 1; }'></script>"
+ "</head><body onload='document.title=\"Loaded\"'>WebKitGTK+ resources on replaced content test</body></html>";
+ g_signal_connect(test->m_webView, "resource-load-started", G_CALLBACK(replacedContentResourceLoadStartedCallback), test);
+ test->replaceContent(replacedHtml, "http://error-page.foo", 0);
+ test->waitUntilTitleChangedTo("Loaded");
+
+ g_assert(!webkit_web_view_get_main_resource(test->m_webView));
+ g_assert(!webkit_web_view_get_subresources(test->m_webView));
+}
+
+static void addCacheHTTPHeadersToResponse(SoupMessage* message)
+{
+ // The actual date doesn't really matter.
+ SoupDate* soupDate = soup_date_new_from_now(0);
+ GOwnPtr<char> date(soup_date_to_string(soupDate, SOUP_DATE_HTTP));
+ soup_message_headers_append(message->response_headers, "Last-Modified", date.get());
+ soup_date_free(soupDate);
+ soup_message_headers_append(message->response_headers, "Cache-control", "public, max-age=31536000");
+ soupDate = soup_date_new_from_now(3600);
+ date.set(soup_date_to_string(soupDate, SOUP_DATE_HTTP));
+ soup_message_headers_append(message->response_headers, "Expires", date.get());
+ soup_date_free(soupDate);
+}
+
+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;
+ }
+
+ soup_message_set_status(message, SOUP_STATUS_OK);
+
+ if (soup_message_headers_get(message->request_headers, "If-Modified-Since")) {
+ soup_message_set_status(message, SOUP_STATUS_NOT_MODIFIED);
+ soup_message_body_complete(message->response_body);
+ return;
+ }
+
+ if (g_str_equal(path, "/")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kIndexHtml, strlen(kIndexHtml));
+ } else if (g_str_equal(path, "/javascript.html")) {
+ static const char* javascriptHtml = "<html><head><script language='javascript' src='/javascript.js'></script></head><body></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, javascriptHtml, strlen(javascriptHtml));
+ } else if (g_str_equal(path, "/image.html")) {
+ static const char* imageHTML = "<html><body><img src='/blank.ico'></img></body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, imageHTML, strlen(imageHTML));
+ } else if (g_str_equal(path, "/redirected-css.html")) {
+ static const char* redirectedCSSHtml = "<html><head><link rel='stylesheet' href='/redirected.css' type='text/css'></head><body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, redirectedCSSHtml, strlen(redirectedCSSHtml));
+ } else if (g_str_equal(path, "/invalid-css.html")) {
+ static const char* invalidCSSHtml = "<html><head><link rel='stylesheet' href='/invalid.css' type='text/css'></head><body></html>";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, invalidCSSHtml, strlen(invalidCSSHtml));
+ } else if (g_str_equal(path, "/style.css")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kStyleCSS, strlen(kStyleCSS));
+ addCacheHTTPHeadersToResponse(message);
+ } else if (g_str_equal(path, "/javascript.js")) {
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kJavascript, strlen(kJavascript));
+ } else if (g_str_equal(path, "/blank.ico")) {
+ GOwnPtr<char> filePath(g_build_filename(Test::getWebKit1TestResoucesDir().data(), path, NULL));
+ char* contents;
+ gsize contentsLength;
+ g_file_get_contents(filePath.get(), &contents, &contentsLength, 0);
+ soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, contents, contentsLength);
+ addCacheHTTPHeadersToResponse(message);
+ } else if (g_str_equal(path, "/simple-style.css")) {
+ static const char* simpleCSS =
+ "body {"
+ " margin: 0px;"
+ " padding: 0px;"
+ "}";
+ soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, simpleCSS, strlen(simpleCSS));
+ } else if (g_str_equal(path, "/redirected.css")) {
+ soup_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY);
+ soup_message_headers_append(message->response_headers, "Location", "/simple-style.css");
+ } else if (g_str_equal(path, "/invalid.css"))
+ soup_message_set_status(message, SOUP_STATUS_CANT_CONNECT);
+ soup_message_body_complete(message->response_body);
+}
+
+void beforeAll()
+{
+ kServer = new WebKitTestServer();
+ kServer->run(serverCallback);
+
+ ResourcesTest::add("WebKitWebView", "resources", testWebViewResources);
+ SingleResourceLoadTest::add("WebKitWebResource", "loading", testWebResourceLoading);
+ SingleResourceLoadTest::add("WebKitWebResource", "response", testWebResourceResponse);
+ ResourceURITrackingTest::add("WebKitWebResource", "active-uri", testWebResourceActiveURI);
+ ResourcesTest::add("WebKitWebResource", "get-data", testWebResourceGetData);
+ ResourcesTest::add("WebKitWebView", "replaced-content", testWebViewResourcesReplacedContent);
+}
+
+void afterAll()
+{
+ delete kServer;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
index 03c5f2fe8..19491c201 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "TestMain.h"
-#include <JavaScriptCore/GRefPtr.h>
#include <gtk/gtk.h>
#include <webkit2/webkit2.h>
+#include <wtf/gobject/GRefPtr.h>
static void testWebKitSettings(Test*, gconstpointer)
{
@@ -204,6 +204,11 @@ static void testWebKitSettings(Test*, gconstpointer)
webkit_settings_set_zoom_text_only(settings, TRUE);
g_assert(webkit_settings_get_zoom_text_only(settings));
+ // By default, JavaScript cannot access the clipboard.
+ g_assert(!webkit_settings_get_javascript_can_access_clipboard(settings));
+ webkit_settings_set_javascript_can_access_clipboard(settings, TRUE);
+ g_assert(webkit_settings_get_javascript_can_access_clipboard(settings));
+
g_object_unref(G_OBJECT(settings));
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
index bfeda169f..d65e8a641 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
@@ -332,6 +332,14 @@ static void testWebViewCreateReadyClose(UIClientTest* test, gconstpointer)
g_assert_cmpint(events[2], ==, UIClientTest::Close);
}
+static gboolean checkMimeTypeForFilter(GtkFileFilter* filter, const gchar* mimeType)
+{
+ GtkFileFilterInfo filterInfo;
+ filterInfo.contains = GTK_FILE_FILTER_MIME_TYPE;
+ filterInfo.mime_type = mimeType;
+ return gtk_file_filter_filter(filter, &filterInfo);
+}
+
static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer)
{
static const char* htmlOnLoadFormat = "<html><body onLoad=\"%s\"></body></html>";
@@ -452,6 +460,252 @@ static void testWebViewZoomLevel(WebViewTest* test, gconstpointer)
g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5);
}
+static void testWebViewRunJavaScript(WebViewTest* test, gconstpointer)
+{
+ static const char* html = "<html><body><a id='WebKitLink' href='http://www.webkitgtk.org/' title='WebKitGTK+ Title'>WebKitGTK+ Website</a></body></html>";
+ test->loadHtml(html, 0);
+ test->waitUntilLoadFinished();
+
+ GOwnPtr<GError> error;
+ WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').title;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ GOwnPtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Title");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').href;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "http://www.webkitgtk.org/");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.document.getElementById('WebKitLink').textContent", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ valueString.set(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_assert_cmpstr(valueString.get(), ==, "WebKitGTK+ Website");
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 25;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 25);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = 2.5;", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert_cmpfloat(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 2.5);
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = true", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = false", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(!WebViewTest::javascriptResultToBoolean(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("a = null", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsNull(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("function Foo() { a = 25; } Foo();", &error.outPtr());
+ g_assert(javascriptResult);
+ g_assert(!error.get());
+ g_assert(WebViewTest::javascriptResultIsUndefined(javascriptResult));
+
+ javascriptResult = test->runJavaScriptAndWaitUntilFinished("foo();", &error.outPtr());
+ g_assert(!javascriptResult);
+ g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
+}
+
+class FileChooserTest: public UIClientTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(FileChooserTest);
+
+ FileChooserTest()
+ {
+ g_signal_connect(m_webView, "run-file-chooser", G_CALLBACK(runFileChooserCallback), this);
+ }
+
+ static gboolean runFileChooserCallback(WebKitWebView*, WebKitFileChooserRequest* request, FileChooserTest* test)
+ {
+ test->runFileChooser(request);
+ return TRUE;
+ }
+
+ void runFileChooser(WebKitFileChooserRequest* request)
+ {
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ m_fileChooserRequest = request;
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ WebKitFileChooserRequest* clickMouseButtonAndWaitForFileChooserRequest(int x, int y)
+ {
+ clickMouseButton(x, y);
+ g_main_loop_run(m_mainLoop);
+ return m_fileChooserRequest.get();
+ }
+
+private:
+ GRefPtr<WebKitFileChooserRequest> m_fileChooserRequest;
+};
+
+static void testWebViewFileChooserRequest(FileChooserTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ static const char* fileChooserHTMLFormat = "<html><body><input style='position:absolute;left:0;top:0;margin:0;padding:0' type='file' %s/></body></html>";
+
+ // Multiple selections not allowed, no MIME filtering.
+ GOwnPtr<char> simpleFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, ""));
+ test->loadHtml(simpleFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ WebKitFileChooserRequest* fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ const gchar* const* mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(!mimeTypes);
+ GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(!filter);
+ const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+
+ // Multiple selections allowed, no MIME filtering, some pre-selected files.
+ GOwnPtr<char> multipleSelectionFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "multiple"));
+ test->loadHtml(multipleSelectionFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(!mimeTypes);
+ filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(!filter);
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+
+ // Select some files.
+ const gchar* filesToSelect[4] = { "/foo", "/foo/bar", "/foo/bar/baz", 0 };
+ webkit_file_chooser_request_select_files(fileChooserRequest, filesToSelect);
+
+ // Check the files that have been just selected.
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(selectedFiles);
+ g_assert_cmpstr(selectedFiles[0], ==, "/foo");
+ g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar");
+ g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz");
+ g_assert(!selectedFiles[3]);
+
+ // Perform another request to check if the list of files selected
+ // in the previous step appears now as part of the new request.
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(selectedFiles);
+ g_assert_cmpstr(selectedFiles[0], ==, "/foo");
+ g_assert_cmpstr(selectedFiles[1], ==, "/foo/bar");
+ g_assert_cmpstr(selectedFiles[2], ==, "/foo/bar/baz");
+ g_assert(!selectedFiles[3]);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+
+ // Multiple selections not allowed, only accept images, audio and video files..
+ GOwnPtr<char> mimeFilteredFileUploadHTML(g_strdup_printf(fileChooserHTMLFormat, "accept='audio/*,video/*,image/*'"));
+ test->loadHtml(mimeFilteredFileUploadHTML.get(), 0);
+ test->waitUntilLoadFinished();
+ fileChooserRequest = test->clickMouseButtonAndWaitForFileChooserRequest(5, 5);
+ g_assert(!webkit_file_chooser_request_get_select_multiple(fileChooserRequest));
+
+ mimeTypes = webkit_file_chooser_request_get_mime_types(fileChooserRequest);
+ g_assert(mimeTypes);
+ g_assert_cmpstr(mimeTypes[0], ==, "audio/*");
+ g_assert_cmpstr(mimeTypes[1], ==, "video/*");
+ g_assert_cmpstr(mimeTypes[2], ==, "image/*");
+ g_assert(!mimeTypes[3]);
+
+ filter = webkit_file_chooser_request_get_mime_types_filter(fileChooserRequest);
+ g_assert(GTK_IS_FILE_FILTER(filter));
+ g_assert(checkMimeTypeForFilter(filter, "audio/*"));
+ g_assert(checkMimeTypeForFilter(filter, "video/*"));
+ g_assert(checkMimeTypeForFilter(filter, "image/*"));
+
+ selectedFiles = webkit_file_chooser_request_get_selected_files(fileChooserRequest);
+ g_assert(!selectedFiles);
+ webkit_file_chooser_request_cancel(fileChooserRequest);
+}
+
+class FullScreenClientTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(FullScreenClientTest);
+
+ enum FullScreenEvent {
+ None,
+ Enter,
+ Leave
+ };
+
+ static gboolean viewEnterFullScreenCallback(WebKitWebView*, FullScreenClientTest* test)
+ {
+ test->m_event = Enter;
+ g_main_loop_quit(test->m_mainLoop);
+ return FALSE;
+ }
+
+ static gboolean viewLeaveFullScreenCallback(WebKitWebView*, FullScreenClientTest* test)
+ {
+ test->m_event = Leave;
+ g_main_loop_quit(test->m_mainLoop);
+ return FALSE;
+ }
+
+ FullScreenClientTest()
+ : m_event(None)
+ {
+ webkit_settings_set_enable_fullscreen(webkit_web_view_get_settings(m_webView), TRUE);
+ g_signal_connect(m_webView, "enter-fullscreen", G_CALLBACK(viewEnterFullScreenCallback), this);
+ g_signal_connect(m_webView, "leave-fullscreen", G_CALLBACK(viewLeaveFullScreenCallback), this);
+ }
+
+ ~FullScreenClientTest()
+ {
+ g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ }
+
+ void requestFullScreenAndWaitUntilEnteredFullScreen()
+ {
+ m_event = None;
+ webkit_web_view_run_javascript(m_webView, "document.documentElement.webkitRequestFullScreen();", 0, 0);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ static gboolean leaveFullScreenIdle(FullScreenClientTest* test)
+ {
+ test->keyStroke(GDK_KEY_Escape);
+ return FALSE;
+ }
+
+ void leaveFullScreenAndWaitUntilLeftFullScreen()
+ {
+ m_event = None;
+ g_idle_add(reinterpret_cast<GSourceFunc>(leaveFullScreenIdle), this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ FullScreenEvent m_event;
+};
+
+static void testWebViewFullScreen(FullScreenClientTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+ test->loadHtml("<html><body>FullScreen test</body></html>", 0);
+ test->waitUntilLoadFinished();
+ test->requestFullScreenAndWaitUntilEnteredFullScreen();
+ g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Enter);
+ test->leaveFullScreenAndWaitUntilLeftFullScreen();
+ g_assert_cmpint(test->m_event, ==, FullScreenClientTest::Leave);
+}
+
void beforeAll()
{
WebViewTest::add("WebKitWebView", "default-context", testWebViewDefaultContext);
@@ -463,6 +717,9 @@ void beforeAll()
UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties);
UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget);
WebViewTest::add("WebKitWebView", "zoom-level", testWebViewZoomLevel);
+ WebViewTest::add("WebKitWebView", "run-javascript", testWebViewRunJavaScript);
+ FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest);
+ FullScreenClientTest::add("WebKitWebView", "fullscreen", testWebViewFullScreen);
}
void afterAll()
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
index 31de72911..7a9e49bc6 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
@@ -21,12 +21,14 @@
#include "config.h"
#include "WebViewTest.h"
+#include <JavaScriptCore/JSRetainPtr.h>
#include <WebCore/GOwnPtrGtk.h>
WebViewTest::WebViewTest()
: m_webView(WEBKIT_WEB_VIEW(g_object_ref_sink(webkit_web_view_new())))
, m_mainLoop(g_main_loop_new(0, TRUE))
, m_parentWindow(0)
+ , m_javascriptResult(0)
{
assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_webView));
}
@@ -35,6 +37,8 @@ WebViewTest::~WebViewTest()
{
if (m_parentWindow)
gtk_widget_destroy(m_parentWindow);
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
g_object_unref(m_webView);
g_main_loop_unref(m_mainLoop);
}
@@ -74,15 +78,7 @@ void WebViewTest::loadRequest(WebKitURIRequest* request)
void WebViewTest::replaceContent(const char* html, const char* contentURI, const char* baseURI)
{
- // FIXME: The active uri should be the contentURI,
- // but WebPageProxy doesn't return the unreachableURL
- // when the page has been loaded with AlternateHTML()
- // See https://bugs.webkit.org/show_bug.cgi?id=75465.
-#if 0
m_activeURI = contentURI;
-#else
- m_activeURI = "about:blank";
-#endif
webkit_web_view_replace_content(m_webView, html, contentURI, baseURI);
}
@@ -202,3 +198,142 @@ void WebViewTest::mouseMoveTo(int x, int y, unsigned int mouseModifiers)
gtk_main_do_event(event.get());
}
+void WebViewTest::clickMouseButton(int x, int y, unsigned int button, unsigned int mouseModifiers)
+{
+ doMouseButtonEvent(GDK_BUTTON_PRESS, x, y, button, mouseModifiers);
+ doMouseButtonEvent(GDK_BUTTON_RELEASE, x, y, button, mouseModifiers);
+}
+
+void WebViewTest::keyStroke(unsigned int keyVal, unsigned int keyModifiers)
+{
+ g_assert(m_parentWindow);
+ GtkWidget* viewWidget = GTK_WIDGET(m_webView);
+ g_assert(gtk_widget_get_realized(viewWidget));
+
+ GOwnPtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS));
+ event->key.keyval = keyVal;
+
+ event->key.time = GDK_CURRENT_TIME;
+ event->key.window = gtk_widget_get_window(viewWidget);
+ g_object_ref(event->key.window);
+ gdk_event_set_device(event.get(), gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget))));
+ event->key.state = keyModifiers;
+
+ // When synthesizing an event, an invalid hardware_keycode value can cause it to be badly processed by GTK+.
+ GOwnPtr<GdkKeymapKey> keys;
+ int keysCount;
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyVal, &keys.outPtr(), &keysCount))
+ event->key.hardware_keycode = keys.get()[0].keycode;
+
+ gtk_main_do_event(event.get());
+ event->key.type = GDK_KEY_RELEASE;
+ gtk_main_do_event(event.get());
+}
+
+void WebViewTest::doMouseButtonEvent(GdkEventType eventType, int x, int y, unsigned int button, unsigned int mouseModifiers)
+{
+ g_assert(m_parentWindow);
+ GtkWidget* viewWidget = GTK_WIDGET(m_webView);
+ g_assert(gtk_widget_get_realized(viewWidget));
+
+ GOwnPtr<GdkEvent> event(gdk_event_new(eventType));
+ event->button.window = gtk_widget_get_window(viewWidget);
+ g_object_ref(event->button.window);
+
+ event->button.time = GDK_CURRENT_TIME;
+ event->button.x = x;
+ event->button.y = y;
+ event->button.axes = 0;
+ event->button.state = mouseModifiers;
+ event->button.button = button;
+
+ event->button.device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(viewWidget)));
+
+ int xRoot, yRoot;
+ gdk_window_get_root_coords(gtk_widget_get_window(viewWidget), x, y, &xRoot, &yRoot);
+ event->button.x_root = xRoot;
+ event->button.y_root = yRoot;
+ gtk_main_do_event(event.get());
+}
+
+static void runJavaScriptReadyCallback(GObject*, GAsyncResult* result, WebViewTest* test)
+{
+ test->m_javascriptResult = webkit_web_view_run_javascript_finish(test->m_webView, result, test->m_javascriptError);
+ g_main_loop_quit(test->m_mainLoop);
+}
+
+WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const char* javascript, GError** error)
+{
+ if (m_javascriptResult)
+ webkit_javascript_result_unref(m_javascriptResult);
+ m_javascriptResult = 0;
+ m_javascriptError = error;
+ webkit_web_view_run_javascript(m_webView, javascript, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
+ g_main_loop_run(m_mainLoop);
+
+ return m_javascriptResult;
+}
+
+static char* jsValueToCString(JSGlobalContextRef context, JSValueRef value)
+{
+ g_assert(value);
+ g_assert(JSValueIsString(context, value));
+
+ JSRetainPtr<JSStringRef> stringValue(Adopt, JSValueToStringCopy(context, value, 0));
+ g_assert(stringValue);
+
+ size_t cStringLength = JSStringGetMaximumUTF8CStringSize(stringValue.get());
+ char* cString = static_cast<char*>(g_malloc(cStringLength));
+ JSStringGetUTF8CString(stringValue.get(), cString, cStringLength);
+ return cString;
+}
+
+char* WebViewTest::javascriptResultToCString(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ return jsValueToCString(context, webkit_javascript_result_get_value(javascriptResult));
+}
+
+double WebViewTest::javascriptResultToNumber(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsNumber(context, value));
+
+ return JSValueToNumber(context, value, 0);
+}
+
+bool WebViewTest::javascriptResultToBoolean(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+ g_assert(JSValueIsBoolean(context, value));
+
+ return JSValueToBoolean(context, value);
+}
+
+bool WebViewTest::javascriptResultIsNull(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsNull(context, value);
+}
+
+bool WebViewTest::javascriptResultIsUndefined(WebKitJavascriptResult* javascriptResult)
+{
+ JSGlobalContextRef context = webkit_javascript_result_get_global_context(javascriptResult);
+ g_assert(context);
+ JSValueRef value = webkit_javascript_result_get_value(javascriptResult);
+ g_assert(value);
+
+ return JSValueIsUndefined(context, value);
+}
+
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
index 01f468562..92e123630 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
@@ -47,12 +47,28 @@ public:
void showInWindowAndWaitUntilMapped();
void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0);
+ void clickMouseButton(int x, int y, unsigned int button = 1, unsigned int mouseModifiers = 0);
+ void keyStroke(unsigned int keyVal, unsigned int keyModifiers = 0);
+
+ WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**);
+
+ // Javascript result helpers.
+ static char* javascriptResultToCString(WebKitJavascriptResult*);
+ static double javascriptResultToNumber(WebKitJavascriptResult*);
+ static bool javascriptResultToBoolean(WebKitJavascriptResult*);
+ static bool javascriptResultIsNull(WebKitJavascriptResult*);
+ static bool javascriptResultIsUndefined(WebKitJavascriptResult*);
WebKitWebView* m_webView;
GMainLoop* m_mainLoop;
CString m_activeURI;
GtkWidget* m_parentWindow;
CString m_expectedTitle;
+ WebKitJavascriptResult* m_javascriptResult;
+ GError** m_javascriptError;
+
+private:
+ void doMouseButtonEvent(GdkEventType, int, int, unsigned int, unsigned int);
};
#endif // WebViewTest_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
index 0a807bc3d..c5460f333 100644
--- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h
+++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
@@ -25,21 +25,25 @@
#include <webkit2/WebKitBackForwardList.h>
#include <webkit2/WebKitBackForwardListItem.h>
+#include <webkit2/WebKitCookieManager.h>
#include <webkit2/WebKitDefines.h>
#include <webkit2/WebKitDownload.h>
#include <webkit2/WebKitEditingCommands.h>
#include <webkit2/WebKitEnumTypes.h>
#include <webkit2/WebKitError.h>
+#include <webkit2/WebKitFileChooserRequest.h>
#include <webkit2/WebKitFindController.h>
#include <webkit2/WebKitHitTestResult.h>
+#include <webkit2/WebKitJavascriptResult.h>
#include <webkit2/WebKitPrintOperation.h>
#include <webkit2/WebKitScriptDialog.h>
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitURIResponse.h>
#include <webkit2/WebKitWebContext.h>
-#include <webkit2/WebKitWebViewBase.h>
+#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebView.h>
+#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWindowProperties.h>
#undef __WEBKIT2_H_INSIDE__
diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
index 5f7356039..de3032819 100644
--- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
+++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list
@@ -3,8 +3,10 @@ BOOLEAN:ENUM,STRING,POINTER
BOOLEAN:OBJECT
BOOLEAN:OBJECT,ENUM
BOOLEAN:STRING
+BOOLEAN:VOID
OBJECT:VOID
VOID:OBJECT,UINT
+VOID:OBJECT,OBJECT
VOID:OBJECT,POINTER
VOID:UINT64