summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess')
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferences.cpp20
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferences.h4
-rw-r--r--Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h4
-rw-r--r--Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.cpp37
-rw-r--r--Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h61
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp12
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp62
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h15
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp60
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h6
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp18
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp445
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h83
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebInspectorPrivate.h28
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp27
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp79
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h7
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp61
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt29
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types1
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am9
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp357
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp5
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp2
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp17
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h3
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/webkit2.h1
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKView.mm22
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp33
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp136
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h10
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h14
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp38
-rw-r--r--Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h1
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp4
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp1
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml8
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_doubleTapToZoom.qml15
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml113
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml7
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_fitToView.qml99
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml62
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml6
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/evaluatejavascript.html10
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/link.html6
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/redirect.html8
-rw-r--r--Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/selectwithsize.html18
-rw-r--r--Source/WebKit2/UIProcess/WebBackForwardList.cpp69
-rw-r--r--Source/WebKit2/UIProcess/WebContext.cpp18
-rw-r--r--Source/WebKit2/UIProcess/WebContext.h2
-rw-r--r--Source/WebKit2/UIProcess/WebInspectorProxy.h16
-rw-r--r--Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp2
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.cpp3
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.h16
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.messages.in2
-rw-r--r--Source/WebKit2/UIProcess/WebProcessProxy.messages.in2
-rw-r--r--Source/WebKit2/UIProcess/cf/WebBackForwardListCF.cpp40
-rw-r--r--Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp84
-rw-r--r--Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h52
-rw-r--r--Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp (renamed from Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp)103
-rw-r--r--Source/WebKit2/UIProcess/mac/BackingStoreMac.mm3
-rw-r--r--Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm1
-rw-r--r--Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm10
-rw-r--r--Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h4
-rw-r--r--Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm4
-rw-r--r--Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp107
-rw-r--r--Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h24
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebError.cpp5
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebError.h2
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp40
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h8
-rw-r--r--Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp9
79 files changed, 2372 insertions, 331 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
index a92104dac..9fe8d6ab9 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
@@ -328,6 +328,16 @@ bool WKPreferencesGetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef)
return toImpl(preferencesRef)->developerExtrasEnabled();
}
+void WKPreferencesSetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef, bool enabled)
+{
+ toImpl(preferencesRef)->setJavaScriptExperimentsEnabled(enabled);
+}
+
+bool WKPreferencesGetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->javaScriptExperimentsEnabled();
+}
+
void WKPreferencesSetTextAreasAreResizable(WKPreferencesRef preferencesRef, bool resizable)
{
toImpl(preferencesRef)->setTextAreasAreResizable(resizable);
@@ -428,6 +438,16 @@ bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef preferencesRef)
return toImpl(preferencesRef)->cssRegionsEnabled();
}
+void WKPreferencesSetCSSGridLayoutEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+ toImpl(preferencesRef)->setCSSGridLayoutEnabled(flag);
+}
+
+bool WKPreferencesGetCSSGridLayoutEnabled(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->cssGridLayoutEnabled();
+}
+
void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef preferencesRef, bool flag)
{
toImpl(preferencesRef)->setRegionBasedColumnsEnabled(flag);
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.h b/Source/WebKit2/UIProcess/API/C/WKPreferences.h
index 5e885738e..42f94957e 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferences.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.h
@@ -133,6 +133,10 @@ WK_EXPORT bool WKPreferencesGetPrivateBrowsingEnabled(WKPreferencesRef preferenc
WK_EXPORT void WKPreferencesSetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef, bool enabled);
WK_EXPORT bool WKPreferencesGetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef);
+// Defaults to false.
+WK_EXPORT void WKPreferencesSetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef);
+
// Defaults to true.
WK_EXPORT void WKPreferencesSetTextAreasAreResizable(WKPreferencesRef preferencesRef, bool resizable);
WK_EXPORT bool WKPreferencesGetTextAreasAreResizable(WKPreferencesRef preferencesRef);
diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
index cbe6b4fd6..6dbc47310 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h
@@ -96,6 +96,10 @@ WK_EXPORT void WKPreferencesSetCSSRegionsEnabled(WKPreferencesRef, bool flag);
WK_EXPORT bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef);
// Defaults to false
+WK_EXPORT void WKPreferencesSetCSSGridLayoutEnabled(WKPreferencesRef, bool flag);
+WK_EXPORT bool WKPreferencesGetCSSGridLayoutEnabled(WKPreferencesRef);
+
+// Defaults to false
WK_EXPORT void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef, bool flag);
WK_EXPORT bool WKPreferencesGetRegionBasedColumnsEnabled(WKPreferencesRef);
diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.cpp b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.cpp
new file mode 100644
index 000000000..c9d777c4d
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WKInspectorClientGtk.h"
+
+#include "WKAPICast.h"
+#include "WebInspectorProxy.h"
+
+using namespace WebKit;
+
+void WKInspectorSetInspectorClientGtk(WKInspectorRef inspectorRef, const WKInspectorClientGtk* wkClient)
+{
+ toImpl(inspectorRef)->initializeInspectorClientGtk(wkClient);
+}
diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h
new file mode 100644
index 000000000..865e19ae3
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKInspectorClientGtk_h
+#define WKInspectorClientGtk_h
+
+#include <WebKit2/WKBase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef bool (*WKInspectorClientGtkInspectorCallback)(WKInspectorRef inspector, const void* clientInfo);
+typedef void (*WKInspectorClientGtkInspectorDidCloseCallback)(WKInspectorRef inspector, const void* clientInfo);
+typedef void (*WKInspectorClientGtkInspectedURLChangedCallback)(WKInspectorRef inspector, WKStringRef url, const void* clientInfo);
+typedef void (*WKInspectorClientGtkDidChangeAttachedHeightCallback)(WKInspectorRef inspector, unsigned height, const void* clientInfo);
+
+struct WKInspectorClientGtk {
+ int version;
+ const void* clientInfo;
+ WKInspectorClientGtkInspectorCallback openWindow;
+ WKInspectorClientGtkInspectorDidCloseCallback didClose;
+ WKInspectorClientGtkInspectorCallback bringToFront;
+ WKInspectorClientGtkInspectedURLChangedCallback inspectedURLChanged;
+ WKInspectorClientGtkInspectorCallback attach;
+ WKInspectorClientGtkInspectorCallback detach;
+ WKInspectorClientGtkDidChangeAttachedHeightCallback didChangeAttachedHeight;
+};
+typedef struct WKInspectorClientGtk WKInspectorClientGtk;
+
+enum { kWKInspectorClientGtkCurrentVersion = 0 };
+
+WK_EXPORT void WKInspectorSetInspectorClientGtk(WKInspectorRef inspectorRef, const WKInspectorClientGtk* client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKInspectorClientGtk_h */
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp
index 1caca868e..ebeb92034 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp
@@ -254,7 +254,8 @@ GList* webkit_back_forward_list_get_back_list(WebKitBackForwardList* backForward
g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);
guint limit = WKBackForwardListGetBackListCount(backForwardList->priv->wkList);
- return webkitBackForwardListCreateList(backForwardList, WKBackForwardListCopyBackListWithLimit(backForwardList->priv->wkList, limit));
+ WKRetainPtr<WKArrayRef> wkList(AdoptWK, WKBackForwardListCopyBackListWithLimit(backForwardList->priv->wkList, limit));
+ return webkitBackForwardListCreateList(backForwardList, wkList.get());
}
/**
@@ -269,7 +270,8 @@ GList* webkit_back_forward_list_get_back_list_with_limit(WebKitBackForwardList*
{
g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);
- return webkitBackForwardListCreateList(backForwardList, WKBackForwardListCopyBackListWithLimit(backForwardList->priv->wkList, limit));
+ WKRetainPtr<WKArrayRef> wkList(AdoptWK, WKBackForwardListCopyBackListWithLimit(backForwardList->priv->wkList, limit));
+ return webkitBackForwardListCreateList(backForwardList, wkList.get());
}
/**
@@ -284,7 +286,8 @@ GList* webkit_back_forward_list_get_forward_list(WebKitBackForwardList* backForw
g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);
guint limit = WKBackForwardListGetForwardListCount(backForwardList->priv->wkList);
- return webkitBackForwardListCreateList(backForwardList, WKBackForwardListCopyForwardListWithLimit(backForwardList->priv->wkList, limit));
+ WKRetainPtr<WKArrayRef> wkList(AdoptWK, WKBackForwardListCopyForwardListWithLimit(backForwardList->priv->wkList, limit));
+ return webkitBackForwardListCreateList(backForwardList, wkList.get());
}
/**
@@ -299,5 +302,6 @@ GList* webkit_back_forward_list_get_forward_list_with_limit(WebKitBackForwardLis
{
g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0);
- return webkitBackForwardListCreateList(backForwardList, WKBackForwardListCopyForwardListWithLimit(backForwardList->priv->wkList, limit));
+ WKRetainPtr<WKArrayRef> wkList(AdoptWK, WKBackForwardListCopyForwardListWithLimit(backForwardList->priv->wkList, limit));
+ return webkitBackForwardListCreateList(backForwardList, wkList.get());
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
index b993d2e83..7d8a10e1f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp
@@ -117,16 +117,28 @@ void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKi
WKCookieManagerSetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), policy);
}
+struct GetAcceptPolicyAsyncData {
+ WKHTTPCookieAcceptPolicy policy;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(GetAcceptPolicyAsyncData)
+
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);
+ GetAcceptPolicyAsyncData* data = static_cast<GetAcceptPolicyAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else
+ data->policy = policy;
g_simple_async_result_complete(result.get());
}
/**
* webkit_cookie_manager_get_accept_policy:
* @cookie_manager: a #WebKitCookieManager
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
@@ -135,12 +147,16 @@ static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy
* 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)
+void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GCancellable* cancellable, 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));
+ GetAcceptPolicyAsyncData* data = createGetAcceptPolicyAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyGetAcceptPolicyAsyncData));
+
WKCookieManagerGetHTTPCookieAcceptPolicy(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetAcceptPolicyCallback);
}
@@ -165,28 +181,41 @@ WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCo
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)));
+ GetAcceptPolicyAsyncData* data = static_cast<GetAcceptPolicyAsyncData*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return static_cast<WebKitCookieAcceptPolicy>(data->policy);
}
+struct GetDomainsWithCookiesAsyncData {
+ GRefPtr<GPtrArray> domains;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(GetDomainsWithCookiesAsyncData)
+
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()));
+ GetDomainsWithCookiesAsyncData* data = static_cast<GetDomainsWithCookiesAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else {
+ data->domains = adoptGRef(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(data->domains.get(), g_strdup(domain.utf8().data()));
+ }
+ g_ptr_array_add(data->domains.get(), 0);
}
- 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
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
@@ -195,12 +224,15 @@ static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomain
* 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)
+void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GCancellable* cancellable, 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));
+ GetDomainsWithCookiesAsyncData* data = createGetDomainsWithCookiesAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyGetDomainsWithCookiesAsyncData));
WKCookieManagerGetHostnamesWithCookies(manager->priv->wkCookieManager.get(), result, webkitCookieManagerGetDomainsWithCookiesCallback);
}
@@ -228,8 +260,8 @@ gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManage
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));
+ GetDomainsWithCookiesAsyncData* data = static_cast<GetDomainsWithCookiesAsyncData*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return reinterpret_cast<char**>(g_ptr_array_free(data->domains.leakRef(), FALSE));
}
/**
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
index 791a61d82..2472d96a2 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h
@@ -74,6 +74,7 @@ webkit_cookie_manager_set_accept_policy (WebKitCookieManager *
WEBKIT_API void
webkit_cookie_manager_get_accept_policy (WebKitCookieManager *cookie_manager,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -84,6 +85,7 @@ webkit_cookie_manager_get_accept_policy_finish (WebKitCookieManager *
WEBKIT_API void
webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
index 4b7e9ad49..b7c537015 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h
@@ -30,6 +30,8 @@
#include <WebKit2/WKDownload.h>
#include <WebKit2/WKFindOptions.h>
#include <WebKit2/WKFullScreenClientGtk.h>
+#include <WebKit2/WKInspector.h>
+#include <WebKit2/WKInspectorClientGtk.h>
#include <WebKit2/WKRetainPtr.h>
#include <WebKit2/WKSerializedScriptValue.h>
#include <WebKit2/WKString.h>
@@ -44,6 +46,19 @@
#define COMPILE_ASSERT_MATCHING_ENUM(webkitName, webcoreName) \
COMPILE_ASSERT(int(webkitName) == int(webcoreName), mismatchingEnums)
+#define WEBKIT_DEFINE_ASYNC_DATA_STRUCT(structName) \
+static structName* create##structName() \
+{ \
+ structName* data = g_slice_new0(structName); \
+ new (data) structName(); \
+ return data; \
+} \
+static void destroy##structName(structName* data) \
+{ \
+ data->~structName(); \
+ g_slice_free(structName, data); \
+}
+
unsigned wkEventModifiersToGdkModifiers(WKEventModifiers);
#endif // WebKitPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
index cd04eb12b..02e82b020 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp
@@ -108,7 +108,8 @@ enum {
PROP_ZOOM_TEXT_ONLY,
PROP_JAVASCRIPT_CAN_ACCESS_CLIPBOARD,
PROP_MEDIA_PLAYBACK_REQUIRES_USER_GESTURE,
- PROP_MEDIA_PLAYBACK_ALLOWS_INLINE
+ PROP_MEDIA_PLAYBACK_ALLOWS_INLINE,
+ PROP_DRAW_COMPOSITING_INDICATORS
};
static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
@@ -227,6 +228,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu
case PROP_MEDIA_PLAYBACK_ALLOWS_INLINE:
webkit_settings_set_media_playback_allows_inline(settings, g_value_get_boolean(value));
break;
+ case PROP_DRAW_COMPOSITING_INDICATORS:
+ webkit_settings_set_draw_compositing_indicators(settings, g_value_get_boolean(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -349,6 +353,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val
case PROP_MEDIA_PLAYBACK_ALLOWS_INLINE:
g_value_set_boolean(value, webkit_settings_get_media_playback_allows_inline(settings));
break;
+ case PROP_DRAW_COMPOSITING_INDICATORS:
+ g_value_set_boolean(value, webkit_settings_get_draw_compositing_indicators(settings));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
break;
@@ -908,6 +915,21 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass)
TRUE,
readWriteConstructParamFlags));
+ /**
+ * WebKitSettings:draw-compositing-indicators:
+ *
+ * Whether to draw compositing borders and repaint counters on layers drawn
+ * with accelerated compositing. This is useful for debugging issues related
+ * to web content that is composited with the GPU.
+ */
+ g_object_class_install_property(gObjectClass,
+ PROP_DRAW_COMPOSITING_INDICATORS,
+ g_param_spec_boolean("draw-compositing-indicators",
+ _("Draw compositing indicators"),
+ _("Whether to draw compositing borders and repaint counters"),
+ FALSE,
+ readWriteConstructParamFlags));
+
g_type_class_add_private(klass, sizeof(WebKitSettingsPrivate));
}
@@ -2313,3 +2335,39 @@ gboolean webkit_settings_get_media_playback_allows_inline(WebKitSettings* settin
return WKPreferencesGetMediaPlaybackAllowsInline(settings->priv->preferences.get());
}
+
+/**
+ * webkit_settings_set_draw_compositing_indicators:
+ * @settings: a #WebKitSettings
+ * @enabled: Value to be set
+ *
+ * Set the #WebKitSettings:draw-compositing-indicators property.
+ */
+void webkit_settings_set_draw_compositing_indicators(WebKitSettings* settings, gboolean enabled)
+{
+ g_return_if_fail(WEBKIT_IS_SETTINGS(settings));
+
+ WebKitSettingsPrivate* priv = settings->priv;
+ if (WKPreferencesGetCompositingBordersVisible(priv->preferences.get()) == enabled
+ && WKPreferencesGetCompositingRepaintCountersVisible(priv->preferences.get()) == enabled)
+ return;
+
+ WKPreferencesSetCompositingBordersVisible(priv->preferences.get(), enabled);
+ WKPreferencesSetCompositingRepaintCountersVisible(priv->preferences.get(), enabled);
+ g_object_notify(G_OBJECT(settings), "draw-compositing-indicators");
+}
+
+/**
+ * webkit_settings_get_draw_compositing_indicators:
+ * @settings: a #WebKitSettings
+ *
+ * Get the #WebKitSettings:draw-compositing-indicators property.
+ *
+ * Returns: %TRUE If compositing borders are drawn or %FALSE otherwise.
+ */
+gboolean webkit_settings_get_draw_compositing_indicators(WebKitSettings* settings)
+{
+ g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE);
+ return WKPreferencesGetCompositingBordersVisible(settings->priv->preferences.get())
+ && WKPreferencesGetCompositingRepaintCountersVisible(settings->priv->preferences.get());
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
index fda7089d0..53ebda299 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h
@@ -334,6 +334,12 @@ webkit_settings_get_media_playback_allows_inline (WebKitSettings *
WEBKIT_API void
webkit_settings_set_media_playback_allows_inline (WebKitSettings *settings,
gboolean enabled);
+WEBKIT_API gboolean
+webkit_settings_get_draw_compositing_indicators (WebKitSettings *settings);
+
+WEBKIT_API void
+webkit_settings_set_draw_compositing_indicators (WebKitSettings *settings,
+ gboolean enabled);
G_END_DECLS
#endif /* WebKitSettings_h */
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
index 5ec64d9d5..681c0d12b 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
@@ -256,19 +256,7 @@ void webkit_web_context_set_additional_plugins_directory(WebKitWebContext* conte
struct GetPluginsAsyncData {
Vector<PluginModuleInfo> plugins;
};
-
-static GetPluginsAsyncData* getPluginsAsyncDataCreate()
-{
- GetPluginsAsyncData* data = g_slice_new(GetPluginsAsyncData);
- new (data) GetPluginsAsyncData();
- return data;
-}
-
-static void getPluginsAsyncDataDestroy(GetPluginsAsyncData* data)
-{
- data->~GetPluginsAsyncData();
- g_slice_free(GetPluginsAsyncData, data);
-}
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(GetPluginsAsyncData)
static void webkitWebContextGetPluginThread(GSimpleAsyncResult* result, GObject* object, GCancellable*)
{
@@ -294,8 +282,8 @@ void webkit_web_context_get_plugins(WebKitWebContext* context, GCancellable* can
GRefPtr<GSimpleAsyncResult> result = adoptGRef(g_simple_async_result_new(G_OBJECT(context), callback, userData,
reinterpret_cast<gpointer>(webkit_web_context_get_plugins)));
- g_simple_async_result_set_op_res_gpointer(result.get(), getPluginsAsyncDataCreate(),
- reinterpret_cast<GDestroyNotify>(getPluginsAsyncDataDestroy));
+ g_simple_async_result_set_op_res_gpointer(result.get(), createGetPluginsAsyncData(),
+ reinterpret_cast<GDestroyNotify>(destroyGetPluginsAsyncData));
g_simple_async_result_run_in_thread(result.get(), webkitWebContextGetPluginThread, G_PRIORITY_DEFAULT, cancellable);
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp
new file mode 100644
index 000000000..25023cf94
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp
@@ -0,0 +1,445 @@
+/*
+ * 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 "WebKitWebInspector.h"
+
+#include "WebInspectorProxy.h"
+#include "WebKitMarshal.h"
+#include "WebKitWebInspectorPrivate.h"
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+enum {
+ OPEN_WINDOW,
+ BRING_TO_FRONT,
+ CLOSED,
+ ATTACH,
+ DETACH,
+
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+
+ PROP_INSPECTED_URI,
+ PROP_ATTACHED_HEIGHT
+};
+
+struct _WebKitWebInspectorPrivate {
+ WKRetainPtr<WKInspectorRef> wkInspector;
+ CString inspectedURI;
+ unsigned attachedHeight;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(WebKitWebInspector, webkit_web_inspector, G_TYPE_OBJECT)
+
+static void webkitWebInspectorGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(object);
+
+ switch (propId) {
+ case PROP_INSPECTED_URI:
+ g_value_set_string(value, webkit_web_inspector_get_inspected_uri(inspector));
+ break;
+ case PROP_ATTACHED_HEIGHT:
+ g_value_set_uint(value, webkit_web_inspector_get_attached_height(inspector));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ }
+}
+
+static void webkitWebInspectorFinalize(GObject* object)
+{
+ WebKitWebInspectorPrivate* priv = WEBKIT_WEB_INSPECTOR(object)->priv;
+ WKInspectorSetInspectorClientGtk(priv->wkInspector.get(), 0);
+ priv->~WebKitWebInspectorPrivate();
+ G_OBJECT_CLASS(webkit_web_inspector_parent_class)->finalize(object);
+}
+
+static void webkit_web_inspector_init(WebKitWebInspector* inspector)
+{
+ WebKitWebInspectorPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(inspector, WEBKIT_TYPE_WEB_INSPECTOR, WebKitWebInspectorPrivate);
+ inspector->priv = priv;
+ new (priv) WebKitWebInspectorPrivate();
+}
+
+static void webkit_web_inspector_class_init(WebKitWebInspectorClass* findClass)
+{
+ GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
+ gObjectClass->finalize = webkitWebInspectorFinalize;
+ gObjectClass->get_property = webkitWebInspectorGetProperty;
+
+ g_type_class_add_private(findClass, sizeof(WebKitWebInspectorPrivate));
+
+ /**
+ * WebKitWebInspector:inspected-uri:
+ *
+ * The URI that is currently being inspected.
+ */
+ g_object_class_install_property(gObjectClass,
+ PROP_INSPECTED_URI,
+ g_param_spec_string("inspected-uri",
+ _("Inspected URI"),
+ _("The URI that is currently being inspected"),
+ 0,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitWebInspector:attached-height:
+ *
+ * The height that the inspector view should have when it is attached.
+ */
+ g_object_class_install_property(gObjectClass,
+ PROP_ATTACHED_HEIGHT,
+ g_param_spec_uint("attached-height",
+ _("Attached Height"),
+ _("The height that the inspector view should have when it is attached"),
+ 0, G_MAXUINT, 0,
+ WEBKIT_PARAM_READABLE));
+
+ /**
+ * WebKitWebInspector::open-window:
+ * @inspector: the #WebKitWebInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to open in a separate window.
+ * If this signal is not handled, a #GtkWindow with the inspector will be
+ * created and shown, so you only need to handle this signal if you want
+ * to use your own window.
+ * This signal is emitted after #WebKitWebInspector::detach to show
+ * the inspector in a separate window after being detached.
+ *
+ * To prevent the inspector from being shown you can connect to this
+ * signal and simply return %TRUE
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ */
+ signals[OPEN_WINDOW] =
+ g_signal_new("open-window",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ /**
+ * WebKitWebInspector::bring-to-front:
+ * @inspector: the #WebKitWebInspector on which the signal is emitted
+ *
+ * Emitted when the inspector should be shown.
+ *
+ * If the inspector is not attached the inspector window should be shown
+ * on top of any other windows.
+ * If the inspector is attached the inspector view should be made visible.
+ * For example, if the inspector view is attached using a tab in a browser
+ * window, the browser window should be raised and the tab containing the
+ * inspector view should be the active one.
+ * In both cases, if this signal is not handled, the default implementation
+ * calls gtk_window_present() on the current toplevel #GtkWindow of the
+ * inspector view.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ */
+ signals[BRING_TO_FRONT] =
+ g_signal_new("bring-to-front",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ /**
+ * WebKitWebInspector::closed:
+ * @inspector: the #WebKitWebInspector on which the signal is emitted
+ *
+ * Emitted when the inspector page is closed. If you are using your own
+ * inspector window, you should connect to this signal and destroy your
+ * window.
+ */
+ signals[CLOSED] =
+ g_signal_new("closed",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0, 0, 0,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * WebKitWebInspector::attach:
+ * @inspector: the #WebKitWebInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to be attached to the window
+ * where the inspected web view is.
+ * If this signal is not handled the inspector view will be automatically
+ * attached to the inspected view, so you only need to handle this signal
+ * if you want to attach the inspector view yourself (for example, to add
+ * the inspector view to a browser tab).
+ *
+ * To prevent the inspector vew from being attached you can connect to this
+ * signal and simply return %TRUE.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ */
+ signals[ATTACH] =
+ g_signal_new("attach",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ /**
+ * WebKitWebInspector::detach:
+ * @inspector: the #WebKitWebInspector on which the signal is emitted
+ *
+ * Emitted when the inspector is requested to be detached from the window
+ * it is currently attached to. The inspector is detached when the inspector page
+ * is about to be closed, and this signal is emitted right before
+ * #WebKitWebInspector::closed, or when the user clicks on the detach button
+ * in the inspector view to show the inspector in a separate window. In this case
+ * the signal #WebKitWebInspector::open-window is emitted after this one.
+ *
+ * To prevent the inspector vew from being detached you can connect to this
+ * signal and simply return %TRUE.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ */
+ signals[DETACH] =
+ g_signal_new("detach",
+ G_TYPE_FROM_CLASS(gObjectClass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, 0,
+ webkit_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+}
+
+static bool openWindow(WKInspectorRef, const void* clientInfo)
+{
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[OPEN_WINDOW], 0, &returnValue);
+ return returnValue;
+}
+
+static void didClose(WKInspectorRef, const void* clientInfo)
+{
+ g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[CLOSED], 0);
+}
+
+static bool bringToFront(WKInspectorRef, const void* clientInfo)
+{
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[BRING_TO_FRONT], 0, &returnValue);
+ return returnValue;
+}
+
+static void inspectedURLChanged(WKInspectorRef, WKStringRef url, const void* clientInfo)
+{
+ WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(clientInfo);
+ CString uri = toImpl(url)->string().utf8();
+ if (uri == inspector->priv->inspectedURI)
+ return;
+ inspector->priv->inspectedURI = uri;
+ g_object_notify(G_OBJECT(inspector), "inspected-uri");
+}
+
+static bool attach(WKInspectorRef, const void* clientInfo)
+{
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[ATTACH], 0, &returnValue);
+ return returnValue;
+}
+
+static bool detach(WKInspectorRef inspector, const void* clientInfo)
+{
+ gboolean returnValue;
+ g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[DETACH], 0, &returnValue);
+ return returnValue;
+}
+
+static void didChangeAttachedHeight(WKInspectorRef, unsigned height, const void* clientInfo)
+{
+ WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(clientInfo);
+ if (inspector->priv->attachedHeight == height)
+ return;
+ inspector->priv->attachedHeight = height;
+ g_object_notify(G_OBJECT(inspector), "attached-height");
+}
+
+WebKitWebInspector* webkitWebInspectorCreate(WKInspectorRef wkInspector)
+{
+ WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL));
+ inspector->priv->wkInspector = wkInspector;
+
+ WKInspectorClientGtk wkInspectorClientGtk = {
+ kWKInspectorClientGtkCurrentVersion,
+ inspector, // clientInfo
+ openWindow,
+ didClose,
+ bringToFront,
+ inspectedURLChanged,
+ attach,
+ detach,
+ didChangeAttachedHeight
+ };
+ WKInspectorSetInspectorClientGtk(wkInspector, &wkInspectorClientGtk);
+
+ return inspector;
+}
+
+/**
+ * webkit_web_inspector_get_web_view:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Get the #WebKitWebViewBase used to display the inspector.
+ * This might be %NULL if the inspector hasn't been loaded yet,
+ * or it has been closed.
+ *
+ * Returns: (transfer none): the #WebKitWebViewBase used to display the inspector or %NULL
+ */
+WebKitWebViewBase* webkit_web_inspector_get_web_view(WebKitWebInspector* inspector)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), 0);
+
+ return WEBKIT_WEB_VIEW_BASE(toImpl(inspector->priv->wkInspector.get())->inspectorView());
+}
+
+/**
+ * webkit_web_inspector_get_inspected_uri:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Get the URI that is currently being inspected. This can be %NULL if
+ * nothing has been loaded yet in the inspected view, if the inspector
+ * has been closed or when inspected view was loaded from a HTML string
+ * instead of a URI.
+ *
+ * Returns: the URI that is currently being inspected or %NULL
+ */
+const char* webkit_web_inspector_get_inspected_uri(WebKitWebInspector* inspector)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), 0);
+
+ return inspector->priv->inspectedURI.data();
+}
+
+/**
+ * webkit_web_inspector_is_attached:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Whether the @inspector view is currently attached to the same window that contains
+ * the inspected view.
+ *
+ * Returns: %TRUE if @inspector is currently attached or %FALSE otherwise
+ */
+gboolean webkit_web_inspector_is_attached(WebKitWebInspector* inspector)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), FALSE);
+
+ return WKInspectorIsAttached(inspector->priv->wkInspector.get());
+}
+
+/**
+ * webkit_web_inspector_attach:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Request @inspector to be attached. The signal #WebKitWebInspector::attach
+ * will be emitted. If the inspector is already attached it does nothing.
+ */
+void webkit_web_inspector_attach(WebKitWebInspector* inspector)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector));
+
+ if (WKInspectorIsAttached(inspector->priv->wkInspector.get()))
+ return;
+ WKInspectorAttach(inspector->priv->wkInspector.get());
+}
+
+/**
+ * webkit_web_inspector_detach:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Request @inspector to be detached. The signal #WebKitWebInspector::detach
+ * will be emitted. If the inspector is already detached it does nothing.
+ */
+void webkit_web_inspector_detach(WebKitWebInspector* inspector)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector));
+
+ if (!WKInspectorIsAttached(inspector->priv->wkInspector.get()))
+ return;
+ WKInspectorDetach(inspector->priv->wkInspector.get());
+}
+
+/**
+ * webkit_web_inspector_show:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Request @inspector to be shown.
+ */
+void webkit_web_inspector_show(WebKitWebInspector* inspector)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector));
+
+ WKInspectorShow(inspector->priv->wkInspector.get());
+}
+
+/**
+ * webkit_web_inspector_close:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Request @inspector to be closed.
+ */
+void webkit_web_inspector_close(WebKitWebInspector* inspector)
+{
+ g_return_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector));
+
+ WKInspectorClose(inspector->priv->wkInspector.get());
+}
+
+/**
+ * webkit_web_inspector_get_attached_height:
+ * @inspector: a #WebKitWebInspector
+ *
+ * Get the height that the inspector view should have when
+ * it's attached. If the inspector view is not attached this
+ * returns 0.
+ *
+ * Returns: the height of the inspector view when attached
+ */
+guint webkit_web_inspector_get_attached_height(WebKitWebInspector* inspector)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), 0);
+
+ if (!WKInspectorIsAttached(inspector->priv->wkInspector.get()))
+ return 0;
+ return inspector->priv->attachedHeight;
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h
new file mode 100644
index 000000000..10c281094
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h
@@ -0,0 +1,83 @@
+/*
+ * 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 WebKitWebInspector_h
+#define WebKitWebInspector_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+#include <webkit2/WebKitWebViewBase.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_WEB_INSPECTOR (webkit_web_inspector_get_type())
+#define WEBKIT_WEB_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_INSPECTOR, WebKitWebInspector))
+#define WEBKIT_IS_WEB_INSPECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_INSPECTOR))
+#define WEBKIT_WEB_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_INSPECTOR, WebKitWebInspectorClass))
+#define WEBKIT_IS_WEB_INSPECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_INSPECTOR))
+#define WEBKIT_WEB_INSPECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_INSPECTOR, WebKitWebInspectorClass))
+
+typedef struct _WebKitWebInspector WebKitWebInspector;
+typedef struct _WebKitWebInspectorClass WebKitWebInspectorClass;
+typedef struct _WebKitWebInspectorPrivate WebKitWebInspectorPrivate;
+
+struct _WebKitWebInspector {
+ GObject parent;
+
+ WebKitWebInspectorPrivate *priv;
+};
+
+struct _WebKitWebInspectorClass {
+ GObjectClass parent_class;
+};
+
+WEBKIT_API GType
+webkit_web_inspector_get_type (void);
+
+WEBKIT_API WebKitWebViewBase *
+webkit_web_inspector_get_web_view (WebKitWebInspector *inspector);
+
+WEBKIT_API const char *
+webkit_web_inspector_get_inspected_uri (WebKitWebInspector *inspector);
+
+WEBKIT_API gboolean
+webkit_web_inspector_is_attached (WebKitWebInspector *inspector);
+
+WEBKIT_API void
+webkit_web_inspector_attach (WebKitWebInspector *inspector);
+
+WEBKIT_API void
+webkit_web_inspector_detach (WebKitWebInspector *inspector);
+
+WEBKIT_API void
+webkit_web_inspector_show (WebKitWebInspector *inspector);
+
+WEBKIT_API void
+webkit_web_inspector_close (WebKitWebInspector *inspector);
+
+WEBKIT_API guint
+webkit_web_inspector_get_attached_height (WebKitWebInspector *inspector);
+
+G_END_DECLS
+
+#endif
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspectorPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspectorPrivate.h
new file mode 100644
index 000000000..703472137
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspectorPrivate.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 WebKitWebInspectorPrivate_h
+#define WebKitWebInspectorPrivate_h
+
+#include "WebKitPrivate.h"
+#include "WebKitWebInspector.h"
+
+WebKitWebInspector* webkitWebInspectorCreate(WKInspectorRef);
+
+#endif // WebKitWebInspectorPrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
index 6bd51fa08..7fbe28a0a 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp
@@ -301,16 +301,28 @@ WebKitURIResponse* webkit_web_resource_get_response(WebKitWebResource* resource)
return resource->priv->response.get();
}
-static void resourceDataCallback(WKDataRef data, WKErrorRef, void* context)
+struct ResourceGetDataAsyncData {
+ WKDataRef wkData;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ResourceGetDataAsyncData)
+
+static void resourceDataCallback(WKDataRef wkData, 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);
+ ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else
+ data->wkData = wkData;
g_simple_async_result_complete(result.get());
}
/**
* webkit_web_resource_get_data:
* @resource: a #WebKitWebResource
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
@@ -319,12 +331,15 @@ static void resourceDataCallback(WKDataRef data, WKErrorRef, void* context)
* 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)
+void webkit_web_resource_get_data(WebKitWebResource* resource, GCancellable* cancellable, 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));
+ ResourceGetDataAsyncData* data = createResourceGetDataAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyResourceGetDataAsyncData));
if (resource->priv->isMainResource)
WKFrameGetMainResourceData(resource->priv->wkFrame.get(), resourceDataCallback, result);
else {
@@ -356,8 +371,8 @@ guchar* webkit_web_resource_get_data_finish(WebKitWebResource* resource, GAsyncR
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));
+ ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_simple_async_result_get_op_res_gpointer(simple));
if (length)
- *length = WKDataGetSize(wkData);
- return static_cast<guchar*>(g_memdup(WKDataGetBytes(wkData), WKDataGetSize(wkData)));
+ *length = WKDataGetSize(data->wkData);
+ return static_cast<guchar*>(g_memdup(WKDataGetBytes(data->wkData), WKDataGetSize(data->wkData)));
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
index 34af76e2b..1cfada0fb 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.h
@@ -63,6 +63,7 @@ webkit_web_resource_get_response (WebKitWebResource *resource);
WEBKIT_API void
webkit_web_resource_get_data (WebKitWebResource *resource,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
index 56b21df49..65dab6ec2 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp
@@ -37,6 +37,7 @@
#include "WebKitSettingsPrivate.h"
#include "WebKitUIClient.h"
#include "WebKitWebContextPrivate.h"
+#include "WebKitWebInspectorPrivate.h"
#include "WebKitWebResourcePrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include "WebKitWebViewPrivate.h"
@@ -120,6 +121,8 @@ struct _WebKitWebViewPrivate {
GRefPtr<WebKitWebResource> mainResource;
LoadingResourcesMap loadingResourcesMap;
ResourcesMap subresourcesMap;
+
+ GRefPtr<WebKitWebInspector> inspector;
};
static guint signals[LAST_SIGNAL] = { 0, };
@@ -1618,10 +1621,21 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView)
return zoomTextOnly ? WKPageGetTextZoomFactor(wkPage) : WKPageGetPageZoomFactor(wkPage);
}
+struct ValidateEditingCommandAsyncData {
+ bool isEnabled;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ValidateEditingCommandAsyncData)
+
static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t state, WKErrorRef, void* context)
{
GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
- g_simple_async_result_set_op_res_gboolean(result.get(), isEnabled);
+ ValidateEditingCommandAsyncData* data = static_cast<ValidateEditingCommandAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else
+ data->isEnabled = isEnabled;
g_simple_async_result_complete(result.get());
}
@@ -1629,6 +1643,7 @@ static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t stat
* webkit_web_view_can_execute_editing_command:
* @web_view: a #WebKitWebView
* @command: the command to check
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: (closure): the data to pass to callback function
*
@@ -1637,13 +1652,17 @@ static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t stat
* When the operation is finished, @callback will be called. You can then call
* webkit_web_view_can_execute_editing_command_finish() to get the result of the operation.
*/
-void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const char* command, GAsyncReadyCallback callback, gpointer userData)
+void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const char* command, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(command);
GSimpleAsyncResult* result = g_simple_async_result_new(G_OBJECT(webView), callback, userData,
reinterpret_cast<gpointer>(webkit_web_view_can_execute_editing_command));
+ ValidateEditingCommandAsyncData* data = createValidateEditingCommandAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyValidateEditingCommandAsyncData));
+
WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
WKRetainPtr<WKStringRef> wkCommand(AdoptWK, WKStringCreateWithUTF8CString(command));
WKPageValidateCommand(toAPI(page), wkCommand.get(), result, didValidateCommand);
@@ -1669,7 +1688,9 @@ gboolean webkit_web_view_can_execute_editing_command_finish(WebKitWebView* webVi
if (g_simple_async_result_propagate_error(simple, error))
return FALSE;
- return g_simple_async_result_get_op_res_gboolean(simple);
+
+ ValidateEditingCommandAsyncData* data = static_cast<ValidateEditingCommandAsyncData*>(g_simple_async_result_get_op_res_gpointer(simple));
+ return data->isEnabled;
}
/**
@@ -1730,15 +1751,29 @@ JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView*
return webView->priv->javascriptGlobalContext;
}
+struct RunJavaScriptAsyncData {
+ ~RunJavaScriptAsyncData()
+ {
+ if (scriptResult)
+ webkit_javascript_result_unref(scriptResult);
+ }
+
+ WebKitJavascriptResult* scriptResult;
+ GRefPtr<GCancellable> cancellable;
+};
+WEBKIT_DEFINE_ASYNC_DATA_STRUCT(RunJavaScriptAsyncData)
+
static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context)
{
GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context));
- if (wkSerializedScriptValue) {
+ RunJavaScriptAsyncData* data = static_cast<RunJavaScriptAsyncData*>(g_simple_async_result_get_op_res_gpointer(result.get()));
+ GError* error = 0;
+ if (g_cancellable_set_error_if_cancelled(data->cancellable.get(), &error))
+ g_simple_async_result_take_error(result.get(), error);
+ else 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));
+ data->scriptResult = webkitJavascriptResultCreate(webView.get(), wkSerializedScriptValue);
} 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);
}
@@ -1749,6 +1784,7 @@ static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSeri
* webkit_web_view_run_javascript:
* @web_view: a #WebKitWebView
* @script: the script to run
+ * @cancellable: (allow-none): a #GCancellable or %NULL to ignore
* @callback: (scope async): a #GAsyncReadyCallback to call when the script finished
* @user_data: (closure): the data to pass to callback function
*
@@ -1757,7 +1793,7 @@ static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSeri
* 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)
+void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(script);
@@ -1766,6 +1802,9 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script,
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));
+ RunJavaScriptAsyncData* data = createRunJavaScriptAsyncData();
+ data->cancellable = cancellable;
+ g_simple_async_result_set_op_res_gpointer(result, data, reinterpret_cast<GDestroyNotify>(destroyRunJavaScriptAsyncData));
WKPageRunJavaScriptInMainFrame(wkPage, wkScript.get(), result, webkitWebViewRunJavaScriptCallback);
}
@@ -1844,8 +1883,8 @@ WebKitJavascriptResult* webkit_web_view_run_javascript_finish(WebKitWebView* web
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;
+ RunJavaScriptAsyncData* data = static_cast<RunJavaScriptAsyncData*>(g_simple_async_result_get_op_res_gpointer(simpleResult));
+ return data->scriptResult ? webkit_javascript_result_ref(data->scriptResult) : 0;
}
/**
@@ -1886,3 +1925,23 @@ GList* webkit_web_view_get_subresources(WebKitWebView* webView)
return g_list_reverse(subresources);
}
+
+/**
+ * webkit_web_view_get_inspector:
+ * @web_view: a #WebKitWebView
+ *
+ * Get the #WebKitWebInspector associated to @web_view
+ *
+ * Returns: (transfer none): the #WebKitWebInspector of @web_view
+ */
+WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
+
+ if (!webView->priv->inspector) {
+ WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView));
+ webView->priv->inspector = adoptGRef(webkitWebInspectorCreate(toAPI(page->inspector())));
+ }
+
+ return webView->priv->inspector.get();
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
index c56205b96..4f5fe1869 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h
@@ -40,6 +40,7 @@
#include <webkit2/WebKitSettings.h>
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitWebContext.h>
+#include <webkit2/WebKitWebInspector.h>
#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebViewBase.h>
#include <webkit2/WebKitWindowProperties.h>
@@ -263,6 +264,7 @@ webkit_web_view_get_zoom_level (WebKitWebView *w
WEBKIT_API void
webkit_web_view_can_execute_editing_command (WebKitWebView *web_view,
const gchar *command,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -284,6 +286,7 @@ webkit_web_view_get_javascript_global_context (WebKitWebView *w
WEBKIT_API void
webkit_web_view_run_javascript (WebKitWebView *web_view,
const gchar *script,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
WEBKIT_API WebKitJavascriptResult *
@@ -296,6 +299,10 @@ webkit_web_view_get_main_resource (WebKitWebView *w
WEBKIT_API GList *
webkit_web_view_get_subresources (WebKitWebView *web_view);
+
+WEBKIT_API WebKitWebInspector *
+webkit_web_view_get_inspector (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 b2cdde564..4faa75fb0 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -36,6 +36,7 @@
#include "WebContext.h"
#include "WebEventFactory.h"
#include "WebFullScreenClientGtk.h"
+#include "WebInspectorProxy.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBaseAccessible.h"
#include "WebKitWebViewBasePrivate.h"
@@ -87,10 +88,15 @@ struct _WebKitWebViewBasePrivate {
bool fullScreenModeActive;
WebFullScreenClientGtk fullScreenClient;
#endif
+ GtkWidget* inspectorView;
+ unsigned inspectorViewHeight;
};
G_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER)
+// Keep this in sync with the value minimumAttachedHeight in WebInspectorProxy.
+static const unsigned gMinimumAttachedInspectorHeight = 250;
+
static void webkitWebViewBaseNotifyResizerSizeForWindow(WebKitWebViewBase* webViewBase, GtkWindow* window)
{
gboolean resizerVisible;
@@ -170,9 +176,16 @@ static void webkitWebViewBaseContainerAdd(GtkContainer* container, GtkWidget* wi
WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(container);
WebKitWebViewBasePrivate* priv = webView->priv;
- GtkAllocation childAllocation;
- gtk_widget_get_allocation(widget, &childAllocation);
- priv->children.set(widget, childAllocation);
+ if (WEBKIT_IS_WEB_VIEW_BASE(widget)
+ && WebInspectorProxy::isInspectorPage(WEBKIT_WEB_VIEW_BASE(widget)->priv->pageProxy.get())) {
+ ASSERT(priv->inspectorView);
+ priv->inspectorView = widget;
+ priv->inspectorViewHeight = gMinimumAttachedInspectorHeight;
+ } else {
+ GtkAllocation childAllocation;
+ gtk_widget_get_allocation(widget, &childAllocation);
+ priv->children.set(widget, childAllocation);
+ }
gtk_widget_set_parent(widget, GTK_WIDGET(container));
}
@@ -183,11 +196,16 @@ static void webkitWebViewBaseContainerRemove(GtkContainer* container, GtkWidget*
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 (priv->inspectorView == widget) {
+ priv->inspectorView = 0;
+ priv->inspectorViewHeight = 0;
+ } else {
+ ASSERT(priv->children.contains(widget));
+ priv->children.remove(widget);
+ }
if (wasVisible && gtk_widget_get_visible(widgetContainer))
gtk_widget_queue_resize(widgetContainer);
}
@@ -201,6 +219,9 @@ static void webkitWebViewBaseContainerForall(GtkContainer* container, gboolean i
WebKitWebViewChildrenMap::const_iterator end = children.end();
for (WebKitWebViewChildrenMap::const_iterator current = children.begin(); current != end; ++current)
(*callback)(current->first, callbackData);
+
+ if (includeInternals && priv->inspectorView)
+ (*callback)(priv->inspectorView, callbackData);
}
void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* child, const IntRect& childRect)
@@ -282,9 +303,19 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase
{
gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase);
+ IntRect viewRect(allocation->x, allocation->y, allocation->width, allocation->height);
WebKitWebViewBasePrivate* priv = webViewBase->priv;
+ if (priv->inspectorView) {
+ GtkAllocation childAllocation = viewRect;
+ childAllocation.y = allocation->height - priv->inspectorViewHeight;
+ childAllocation.height = priv->inspectorViewHeight;
+ gtk_widget_size_allocate(priv->inspectorView, &childAllocation);
+
+ viewRect.setHeight(allocation->height - priv->inspectorViewHeight);
+ }
+
if (priv->pageProxy->drawingArea())
- priv->pageProxy->drawingArea()->setSize(IntSize(allocation->width, allocation->height), IntSize());
+ priv->pageProxy->drawingArea()->setSize(viewRect.size(), IntSize());
GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webViewBase));
if (widgetIsOnscreenToplevelWindow(toplevel))
@@ -404,7 +435,7 @@ static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventBut
return TRUE;
priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(buttonEvent),
priv->clickCounter.clickCountForGdkButtonEvent(widget, buttonEvent)));
- return FALSE;
+ return TRUE;
}
static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventButton* event)
@@ -415,7 +446,7 @@ static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventB
gtk_widget_grab_focus(widget);
priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */));
- return FALSE;
+ return TRUE;
}
static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll* event)
@@ -425,7 +456,7 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll*
priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(reinterpret_cast<GdkEvent*>(event)));
- return FALSE;
+ return TRUE;
}
static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event)
@@ -435,7 +466,7 @@ static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMo
priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */));
- return FALSE;
+ return TRUE;
}
static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, gboolean keyboardMode, GtkTooltip* tooltip)
@@ -718,3 +749,13 @@ void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase* webkitWebVie
{
webkitWebViewBase->priv->fullScreenClient.initialize(wkClient);
}
+
+void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase* webkitWebViewBase, unsigned height)
+{
+ if (!webkitWebViewBase->priv->inspectorView)
+ return;
+ if (webkitWebViewBase->priv->inspectorViewHeight == height)
+ return;
+ webkitWebViewBase->priv->inspectorViewHeight = height;
+ gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase));
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
index cd4c1a1b5..5e191971c 100644
--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h
@@ -45,5 +45,6 @@ void webkitWebViewBaseChildMoveResize(WebKitWebViewBase*, GtkWidget*, const WebC
void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*);
void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*);
void webkitWebViewBaseInitializeFullScreenClient(WebKitWebViewBase*, const WKFullScreenClientGtk*);
+void webkitWebViewBaseSetInspectorViewHeight(WebKitWebViewBase*, unsigned height);
#endif // WebKitWebViewBasePrivate_h
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
index 63db05f77..b6b9aa0b1 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml
@@ -32,6 +32,7 @@
<xi:include href="xml/WebKitFindController.xml"/>
<xi:include href="xml/WebKitCookieManager.xml"/>
<xi:include href="xml/WebKitPlugin.xml"/>
+ <xi:include href="xml/WebKitWebInspector.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 884177b8b..05bdeeb51 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt
@@ -91,6 +91,7 @@ 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_inspector
webkit_web_view_get_javascript_global_context
webkit_web_view_run_javascript
webkit_web_view_run_javascript_finish
@@ -258,6 +259,8 @@ webkit_settings_get_media_playback_requires_user_gesture
webkit_settings_set_media_playback_requires_user_gesture
webkit_settings_get_media_playback_allows_inline
webkit_settings_set_media_playback_allows_inline
+webkit_settings_get_draw_compositing_indicators
+webkit_settings_set_draw_compositing_indicators
<SUBSECTION Standard>
WebKitSettingsClass
@@ -636,3 +639,29 @@ webkit_plugin_get_type
webkit_mime_info_get_type
WebKitPluginPrivate
</SECTION>
+
+<SECTION>
+<FILE>WebKitWebInspector</FILE>
+WebKitWebInspector
+webkit_web_inspector_get_web_view
+webkit_web_inspector_get_inspected_uri
+webkit_web_inspector_is_attached
+webkit_web_inspector_attach
+webkit_web_inspector_detach
+webkit_web_inspector_show
+webkit_web_inspector_close
+webkit_web_inspector_get_attached_height
+
+<SUBSECTION Standard>
+WebKitWebInspectorClass
+WEBKIT_TYPE_WEB_INSPECTOR
+WEBKIT_WEB_INSPECTOR
+WEBKIT_IS_WEB_INSPECTOR
+WEBKIT_WEB_INSPECTOR_CLASS
+WEBKIT_IS_WEB_INSPECTOR_CLASS
+WEBKIT_WEB_INSPECTOR_GET_CLASS
+
+<SUBSECTION Private>
+webkit_web_inspector_get_type
+WebKitWebInspectorPrivate
+</SECTION>
diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
index cdf9edd73..92b6fb400 100644
--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types
@@ -17,3 +17,4 @@ webkit_web_resource_get_type
webkit_cookie_manager_get_type
webkit_plugin_get_type
webkit_mime_info_get_type
+webkit_web_inspector_get_type
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
index 870d68a5b..8fa0cd8d8 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am
@@ -4,6 +4,7 @@ TEST_PROGS += \
Programs/WebKit2APITests/TestBackForwardList \
Programs/WebKit2APITests/TestCookieManager \
Programs/WebKit2APITests/TestDownloads \
+ Programs/WebKit2APITests/TestInspector \
Programs/WebKit2APITests/TestLoaderClient \
Programs/WebKit2APITests/TestPrinting \
Programs/WebKit2APITests/TestResources \
@@ -151,4 +152,12 @@ Programs_WebKit2APITests_TestCookieManager_CPPFLAGS = $(webkit2_tests_cppflags)
Programs_WebKit2APITests_TestCookieManager_LDADD = $(webkit2_tests_ldadd)
Programs_WebKit2APITests_TestCookieManager_LDFLAGS = $(webkit2_tests_ldflags)
+Programs_WebKit2APITests_TestInspector_SOURCES = \
+ Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
+Programs_WebKit2APITests_TestInspector_CPPFLAGS = \
+ -DWEBKIT_INSPECTOR_PATH=\"${shell pwd}/${top_builddir}/resources/inspector\" \
+ $(webkit2_tests_cppflags)
+Programs_WebKit2APITests_TestInspector_LDADD = $(webkit2_tests_ldadd)
+Programs_WebKit2APITests_TestInspector_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
index 6d2ecf528..1ddfd82bf 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestCookieManager.cpp
@@ -74,7 +74,7 @@ public:
WebKitCookieAcceptPolicy getAcceptPolicy()
{
m_acceptPolicy = WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
- webkit_cookie_manager_get_accept_policy(m_cookieManager, getAcceptPolicyReadyCallback, this);
+ webkit_cookie_manager_get_accept_policy(m_cookieManager, 0, getAcceptPolicyReadyCallback, this);
g_main_loop_run(m_mainLoop);
return m_acceptPolicy;
@@ -100,7 +100,7 @@ public:
{
g_strfreev(m_domains);
m_domains = 0;
- webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, getDomainsReadyCallback, this);
+ webkit_cookie_manager_get_domains_with_cookies(m_cookieManager, 0, getDomainsReadyCallback, this);
g_main_loop_run(m_mainLoop);
return m_domains;
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
new file mode 100644
index 000000000..9b023f3ed
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestInspector.cpp
@@ -0,0 +1,357 @@
+/*
+ * 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 "WebViewTest.h"
+#include <wtf/gobject/GRefPtr.h>
+
+static const unsigned gMinimumAttachedInspectorHeight = 250;
+
+class InspectorTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(InspectorTest);
+
+ enum InspectorEvents {
+ OpenWindow,
+ BringToFront,
+ Closed,
+ Attach,
+ Detach
+ };
+
+ static gboolean openWindowCallback(WebKitWebInspector*, InspectorTest* test)
+ {
+ return test->openWindow();
+ }
+
+ static gboolean bringToFrontCallback(WebKitWebInspector*, InspectorTest* test)
+ {
+ return test->bringToFront();
+ }
+
+ static void closedCallback(WebKitWebInspector*, InspectorTest* test)
+ {
+ return test->closed();
+ }
+
+ static gboolean attachCallback(WebKitWebInspector*, InspectorTest* test)
+ {
+ return test->attach();
+ }
+
+ static gboolean detachCallback(WebKitWebInspector*, InspectorTest* test)
+ {
+ return test->detach();
+ }
+
+ static const unsigned gMinimumAttachedInspectorHeight = 250;
+
+ InspectorTest()
+ : WebViewTest()
+ , m_inspector(webkit_web_view_get_inspector(m_webView))
+ , m_quitOnBringToFront(false)
+ {
+ webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(m_webView), TRUE);
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_inspector));
+ g_signal_connect(m_inspector, "open-window", G_CALLBACK(openWindowCallback), this);
+ g_signal_connect(m_inspector, "bring-to-front", G_CALLBACK(bringToFrontCallback), this);
+ g_signal_connect(m_inspector, "closed", G_CALLBACK(closedCallback), this);
+ g_signal_connect(m_inspector, "attach", G_CALLBACK(attachCallback), this);
+ g_signal_connect(m_inspector, "detach", G_CALLBACK(detachCallback), this);
+ }
+
+ ~InspectorTest()
+ {
+ g_signal_handlers_disconnect_matched(m_inspector, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ }
+
+ virtual bool openWindow()
+ {
+ m_events.append(OpenWindow);
+ g_main_loop_quit(m_mainLoop);
+ return TRUE;
+ }
+
+ virtual bool bringToFront()
+ {
+ m_events.append(BringToFront);
+ if (m_quitOnBringToFront)
+ g_main_loop_quit(m_mainLoop);
+ return FALSE;
+ }
+
+ virtual void closed()
+ {
+ m_events.append(Closed);
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ virtual bool attach()
+ {
+ m_events.append(Attach);
+ return TRUE;
+ }
+
+ virtual bool detach()
+ {
+ m_events.append(Detach);
+ return TRUE;
+ }
+
+ void showAndWaitUntilFinished(bool quitOnBringToFront)
+ {
+ m_quitOnBringToFront = quitOnBringToFront;
+ webkit_web_inspector_show(m_inspector);
+ g_main_loop_run(m_mainLoop);
+ m_quitOnBringToFront = false;
+ }
+
+ void resizeViewAndAttach()
+ {
+ // Resize the view to make room for the inspector.
+ resizeView(300, (gMinimumAttachedInspectorHeight + 1) * 4 / 3);
+ webkit_web_inspector_attach(m_inspector);
+ }
+
+ static gboolean detachIdle(InspectorTest* test)
+ {
+ webkit_web_inspector_detach(test->m_inspector);
+ return FALSE;
+ }
+
+ void detachAndWaitUntilWindowOpened()
+ {
+ g_idle_add(reinterpret_cast<GSourceFunc>(detachIdle), this);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ void closeAndWaitUntilClosed()
+ {
+ webkit_web_inspector_close(m_inspector);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ WebKitWebInspector* m_inspector;
+ bool m_quitOnBringToFront;
+ Vector<InspectorEvents> m_events;
+};
+
+static void testInspectorDefault(InspectorTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
+ test->resizeView(200, 200);
+ test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0);
+ test->waitUntilLoadFinished();
+
+ test->showAndWaitUntilFinished(false);
+ // We don't add the view to a container, so consume the weak ref with GRefPtr.
+ GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(test->m_inspector);
+ g_assert(inspectorView.get());
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(inspectorView.get()));
+ g_assert(!webkit_web_inspector_is_attached(test->m_inspector));
+ g_assert_cmpuint(webkit_web_inspector_get_attached_height(test->m_inspector), ==, 0);
+ Vector<InspectorTest::InspectorEvents>& events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 2);
+ g_assert_cmpint(events[0], ==, InspectorTest::BringToFront);
+ g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow);
+ test->m_events.clear();
+
+ test->showAndWaitUntilFinished(true);
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 1);
+ g_assert_cmpint(events[0], ==, InspectorTest::BringToFront);
+ test->m_events.clear();
+
+ test->resizeViewAndAttach();
+ g_assert(webkit_web_inspector_is_attached(test->m_inspector));
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 1);
+ g_assert_cmpint(events[0], ==, InspectorTest::Attach);
+ test->m_events.clear();
+
+ test->detachAndWaitUntilWindowOpened();
+ g_assert(!webkit_web_inspector_is_attached(test->m_inspector));
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 2);
+ g_assert_cmpint(events[0], ==, InspectorTest::Detach);
+ g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow);
+ test->m_events.clear();
+
+ test->closeAndWaitUntilClosed();
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 1);
+ g_assert_cmpint(events[0], ==, InspectorTest::Closed);
+ test->m_events.clear();
+}
+
+class CustomInspectorTest: public InspectorTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(CustomInspectorTest);
+
+ CustomInspectorTest()
+ : InspectorTest()
+ , m_inspectorWindow(0)
+ {
+ }
+
+ ~CustomInspectorTest()
+ {
+ if (m_inspectorWindow)
+ gtk_widget_destroy(m_inspectorWindow);
+ }
+
+ bool openWindow()
+ {
+ g_assert(!m_inspectorWindow);
+ m_inspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ WebKitWebViewBase* inspectorView = webkit_web_inspector_get_web_view(m_inspector);
+ g_assert(inspectorView);
+ gtk_container_add(GTK_CONTAINER(m_inspectorWindow), GTK_WIDGET(inspectorView));
+ gtk_widget_show_all(m_inspectorWindow);
+
+ return InspectorTest::openWindow();
+ }
+
+ void closed()
+ {
+ if (m_inspectorWindow) {
+ gtk_widget_destroy(m_inspectorWindow);
+ m_inspectorWindow = 0;
+ }
+
+ return InspectorTest::closed();
+ }
+
+ bool attach()
+ {
+ GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(m_inspector);
+ if (m_inspectorWindow) {
+ gtk_container_remove(GTK_CONTAINER(m_inspectorWindow), GTK_WIDGET(inspectorView.get()));
+ gtk_widget_destroy(m_inspectorWindow);
+ m_inspectorWindow = 0;
+ }
+
+ GtkWidget* pane;
+ if (gtk_bin_get_child(GTK_BIN(m_parentWindow)) == GTK_WIDGET(m_webView)) {
+ GRefPtr<WebKitWebView> inspectedView = m_webView;
+ gtk_container_remove(GTK_CONTAINER(m_parentWindow), GTK_WIDGET(m_webView));
+ pane = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
+ gtk_paned_add1(GTK_PANED(pane), GTK_WIDGET(m_webView));
+ gtk_container_add(GTK_CONTAINER(m_parentWindow), pane);
+ gtk_widget_show_all(pane);
+ } else
+ pane = gtk_bin_get_child(GTK_BIN(m_parentWindow));
+ gtk_paned_add2(GTK_PANED(pane), GTK_WIDGET(inspectorView.get()));
+
+ return InspectorTest::attach();
+ }
+
+ bool detach()
+ {
+ GRefPtr<WebKitWebViewBase> inspectorView = webkit_web_inspector_get_web_view(m_inspector);
+ GtkWidget* pane = gtk_bin_get_child(GTK_BIN(m_parentWindow));
+ g_assert(GTK_IS_PANED(pane));
+ gtk_container_remove(GTK_CONTAINER(pane), GTK_WIDGET(inspectorView.get()));
+ return InspectorTest::detach();
+ }
+
+ void destroyWindowAndWaitUntilClosed()
+ {
+ g_assert(m_inspectorWindow);
+ gtk_widget_destroy(m_inspectorWindow);
+ m_inspectorWindow = 0;
+ g_main_loop_run(m_mainLoop);
+ }
+
+ GtkWidget* m_inspectorWindow;
+};
+
+static void testInspectorManualAttachDetach(CustomInspectorTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
+ test->resizeView(200, 200);
+ test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0);
+ test->waitUntilLoadFinished();
+
+ test->showAndWaitUntilFinished(false);
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webkit_web_inspector_get_web_view(test->m_inspector)));
+ g_assert(!webkit_web_inspector_is_attached(test->m_inspector));
+ Vector<InspectorTest::InspectorEvents>& events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 2);
+ g_assert_cmpint(events[0], ==, InspectorTest::BringToFront);
+ g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow);
+ test->m_events.clear();
+
+ test->resizeViewAndAttach();
+ g_assert(webkit_web_inspector_is_attached(test->m_inspector));
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 1);
+ g_assert_cmpint(events[0], ==, InspectorTest::Attach);
+ test->m_events.clear();
+
+ test->detachAndWaitUntilWindowOpened();
+ g_assert(!webkit_web_inspector_is_attached(test->m_inspector));
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 2);
+ g_assert_cmpint(events[0], ==, InspectorTest::Detach);
+ g_assert_cmpint(events[1], ==, InspectorTest::OpenWindow);
+ test->m_events.clear();
+
+ test->resizeViewAndAttach();
+ g_assert(webkit_web_inspector_is_attached(test->m_inspector));
+ test->m_events.clear();
+ test->closeAndWaitUntilClosed();
+ events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 2);
+ g_assert_cmpint(events[0], ==, InspectorTest::Detach);
+ g_assert_cmpint(events[1], ==, InspectorTest::Closed);
+ test->m_events.clear();
+}
+
+static void testInspectorCustomContainerDestroyed(CustomInspectorTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
+ test->resizeView(200, 200);
+ test->loadHtml("<html><body><p>WebKitGTK+ Inspector test</p></body></html>", 0);
+ test->waitUntilLoadFinished();
+
+ test->showAndWaitUntilFinished(false);
+ test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webkit_web_inspector_get_web_view(test->m_inspector)));
+ g_assert(!webkit_web_inspector_is_attached(test->m_inspector));
+
+ test->m_events.clear();
+ test->destroyWindowAndWaitUntilClosed();
+ Vector<InspectorTest::InspectorEvents>& events = test->m_events;
+ g_assert_cmpint(events.size(), ==, 1);
+ g_assert_cmpint(events[0], ==, InspectorTest::Closed);
+ test->m_events.clear();
+}
+
+void beforeAll()
+{
+ g_setenv("WEBKIT_INSPECTOR_PATH", WEBKIT_INSPECTOR_PATH, FALSE);
+ InspectorTest::add("WebKitWebInspector", "default", testInspectorDefault);
+ CustomInspectorTest::add("WebKitWebInspector", "manual-attach-detach", testInspectorManualAttachDetach);
+ CustomInspectorTest::add("WebKitWebInspector", "custom-container-destroyed", testInspectorCustomContainerDestroyed);
+}
+
+void afterAll()
+{
+}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
index e08cfb9c9..39841756d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestResources.cpp
@@ -150,7 +150,7 @@ public:
void checkResourceData(WebKitWebResource* resource)
{
m_resourceDataSize = 0;
- webkit_web_resource_get_data(resource, resourceGetDataCallback, this);
+ webkit_web_resource_get_data(resource, 0, resourceGetDataCallback, this);
g_main_loop_run(m_mainLoop);
const char* uri = webkit_web_resource_get_uri(resource);
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
index ad03444ae..4616d105f 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp
@@ -219,6 +219,11 @@ static void testWebKitSettings(Test*, gconstpointer)
webkit_settings_set_media_playback_allows_inline(settings, FALSE);
g_assert(!webkit_settings_get_media_playback_allows_inline(settings));
+ // By default, debug indicators are disabled.
+ g_assert(!webkit_settings_get_draw_compositing_indicators(settings));
+ webkit_settings_set_draw_compositing_indicators(settings, TRUE);
+ g_assert(webkit_settings_get_draw_compositing_indicators(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 d65e8a641..e4c60bebc 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp
@@ -675,7 +675,7 @@ public:
void requestFullScreenAndWaitUntilEnteredFullScreen()
{
m_event = None;
- webkit_web_view_run_javascript(m_webView, "document.documentElement.webkitRequestFullScreen();", 0, 0);
+ webkit_web_view_run_javascript(m_webView, "document.documentElement.webkitRequestFullScreen();", 0, 0, 0);
g_main_loop_run(m_mainLoop);
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
index 644584a3e..97ebe5b27 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebViewEditor.cpp
@@ -47,7 +47,7 @@ public:
bool canExecuteEditingCommand(const char* command)
{
m_canExecuteEditingCommand = false;
- webkit_web_view_can_execute_editing_command(m_webView, command, reinterpret_cast<GAsyncReadyCallback>(canExecuteEditingCommandReadyCallback), this);
+ webkit_web_view_can_execute_editing_command(m_webView, command, 0, reinterpret_cast<GAsyncReadyCallback>(canExecuteEditingCommandReadyCallback), this);
g_main_loop_run(m_mainLoop);
return m_canExecuteEditingCommand;
}
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
index 7a9e49bc6..e355f786d 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp
@@ -162,10 +162,10 @@ static gboolean parentWindowMapped(GtkWidget* widget, GdkEvent*, WebViewTest* te
return FALSE;
}
-void WebViewTest::showInWindowAndWaitUntilMapped()
+void WebViewTest::showInWindowAndWaitUntilMapped(GtkWindowType windowType)
{
g_assert(!m_parentWindow);
- m_parentWindow = gtk_window_new(GTK_WINDOW_POPUP);
+ m_parentWindow = gtk_window_new(windowType);
gtk_container_add(GTK_CONTAINER(m_parentWindow), GTK_WIDGET(m_webView));
gtk_widget_show(GTK_WIDGET(m_webView));
@@ -174,6 +174,17 @@ void WebViewTest::showInWindowAndWaitUntilMapped()
g_main_loop_run(m_mainLoop);
}
+void WebViewTest::resizeView(int width, int height)
+{
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
+ if (width != -1)
+ allocation.width = width;
+ if (height != -1)
+ allocation.height = height;
+ gtk_widget_size_allocate(GTK_WIDGET(m_webView), &allocation);
+}
+
void WebViewTest::mouseMoveTo(int x, int y, unsigned int mouseModifiers)
{
g_assert(m_parentWindow);
@@ -268,7 +279,7 @@ WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const cha
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);
+ webkit_web_view_run_javascript(m_webView, javascript, 0, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
g_main_loop_run(m_mainLoop);
return m_javascriptResult;
diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
index 92e123630..ff6a8c737 100644
--- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
+++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h
@@ -44,7 +44,8 @@ public:
void waitUntilLoadFinished();
void waitUntilTitleChangedTo(const char* expectedTitle);
void waitUntilTitleChanged();
- void showInWindowAndWaitUntilMapped();
+ void showInWindowAndWaitUntilMapped(GtkWindowType = GTK_WINDOW_POPUP);
+ void resizeView(int width, int height);
void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0);
void clickMouseButton(int x, int y, unsigned int button = 1, unsigned int mouseModifiers = 0);
diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
index 7699c4966..23dbd9903 100644
--- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h
+++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h
@@ -43,6 +43,7 @@
#include <webkit2/WebKitURIRequest.h>
#include <webkit2/WebKitURIResponse.h>
#include <webkit2/WebKitWebContext.h>
+#include <webkit2/WebKitWebInspector.h>
#include <webkit2/WebKitWebResource.h>
#include <webkit2/WebKitWebView.h>
#include <webkit2/WebKitWebViewBase.h>
diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm
index 8cd3027a3..f03b9a899 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKView.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm
@@ -1598,6 +1598,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
return resultRect;
}
+#if ENABLE(DRAG_SUPPORT)
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
{
NSPoint windowImageLoc = [[self window] convertScreenToBase:aPoint];
@@ -1699,7 +1700,7 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
NSArray *types = [pasteboard types];
if (![types containsObject:NSFilenamesPboardType])
return;
-
+
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
handles.allocate([files count]);
for (unsigned i = 0; i < [files count]; i++) {
@@ -1724,7 +1725,7 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
SandboxExtension::HandleArray sandboxExtensionForUpload;
createSandboxExtensionsForFileUpload([draggingInfo draggingPasteboard], sandboxExtensionForUpload);
-
+
_data->_page->performDrag(&dragData, [[draggingInfo draggingPasteboard] name], sandboxExtensionHandle, sandboxExtensionForUpload);
return YES;
@@ -1739,6 +1740,7 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb
return self;
return nil;
}
+#endif // ENABLE(DRAG_SUPPORT)
- (BOOL)_windowResizeMouseLocationIsInVisibleScrollerThumb:(NSPoint)loc
{
@@ -2511,8 +2513,20 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)_updateAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext
{
- [self _exitAcceleratedCompositingMode];
- [self _enterAcceleratedCompositingMode:layerTreeContext];
+ if (_data->_layerHostingView) {
+ // Wrap the call to setSublayers: in a CATransaction with actions disabled to
+ // keep CA from cross-fading between the two sublayer arrays.
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+
+ CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID);
+ [[_data->_layerHostingView.get() layer] setSublayers:[NSArray arrayWithObject:renderLayer]];
+
+ [CATransaction commit];
+ } else {
+ [self _exitAcceleratedCompositingMode];
+ [self _enterAcceleratedCompositingMode:layerTreeContext];
+ }
}
- (void)_setAccessibilityWebProcessToken:(NSData *)data
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
index e02ccc9b2..178e2dade 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
@@ -140,18 +140,41 @@ QTransform QQuickWebPage::transformFromItem() const
QTransform QQuickWebPage::transformToItem() const
{
- QPointF pos = d->viewportItem->pageItemPos();
- return QTransform(d->contentsScale, 0, 0, 0, d->contentsScale, 0, pos.x(), pos.y(), 1);
+ qreal xPos = x();
+ qreal yPos = y();
+
+ if (d->viewportItem->experimental()->flickableViewportEnabled()) {
+ // Flickable moves its contentItem so we need to take that position into
+ // account, as well as the potential displacement of the page on the
+ // contentItem because of additional QML items.
+ xPos += d->viewportItem->contentItem()->x();
+ yPos += d->viewportItem->contentItem()->y();
+ }
+
+ return QTransform(d->contentsScale, 0, 0, 0, d->contentsScale, 0, xPos, yPos, 1);
}
void QQuickWebPagePrivate::updateSize()
{
QSizeF scaledSize = contentsSize * contentsScale;
- q->setSize(scaledSize);
- viewportItem->updateContentsSize(scaledSize);
+
DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
if (drawingArea && drawingArea->layerTreeHostProxy())
- drawingArea->layerTreeHostProxy()->setContentsSize(WebCore::FloatSize(contentsSize.width(), contentsSize.height()));
+ drawingArea->layerTreeHostProxy()->setContentsSize(contentsSize);
+
+ q->setSize(scaledSize);
+
+ if (viewportItem->experimental()->flickableViewportEnabled()) {
+ // Make sure that the content is sized to the page if the user did not
+ // add other flickable items. If that is not the case, the user needs to
+ // disable the default content item size property on the WebView and
+ // bind the contentWidth and contentHeight accordingly, in accordance
+ // accordance with normal Flickable behaviour.
+ if (viewportItem->experimental()->useDefaultContentItemSize()) {
+ viewportItem->setContentWidth(scaledSize.width());
+ viewportItem->setContentHeight(scaledSize.height());
+ }
+ }
}
QQuickWebPagePrivate::~QQuickWebPagePrivate()
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
index 935842146..9d77171cc 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp
@@ -324,31 +324,33 @@ bool QQuickWebViewPrivate::transparentBackground() const
return webPageProxy->drawsTransparentBackground();
}
-QPointF QQuickWebViewPrivate::pageItemPos()
-{
- ASSERT(pageView);
- return pageView->pos();
-}
-
/*!
\qmlsignal WebView::loadingChanged(WebLoadRequest request)
*/
-void QQuickWebViewPrivate::provisionalLoadDidStart(const QUrl& url)
+void QQuickWebViewPrivate::provisionalLoadDidStart(const WTF::String& url)
{
Q_Q(QQuickWebView);
- QWebLoadRequest loadRequest(url, QQuickWebView::LoadStartedStatus);
+ q->emitUrlChangeIfNeeded();
+
+ QWebLoadRequest loadRequest(QString(url), QQuickWebView::LoadStartedStatus);
emit q->loadingChanged(&loadRequest);
}
+void QQuickWebViewPrivate::didReceiveServerRedirectForProvisionalLoad(const WTF::String&)
+{
+ Q_Q(QQuickWebView);
+
+ q->emitUrlChangeIfNeeded();
+}
+
void QQuickWebViewPrivate::loadDidCommit()
{
Q_Q(QQuickWebView);
ASSERT(q->loading());
emit q->navigationHistoryChanged();
- emit q->urlChanged();
emit q->titleChanged();
}
@@ -356,8 +358,8 @@ void QQuickWebViewPrivate::didSameDocumentNavigation()
{
Q_Q(QQuickWebView);
+ q->emitUrlChangeIfNeeded();
emit q->navigationHistoryChanged();
- emit q->urlChanged();
}
void QQuickWebViewPrivate::titleDidChange()
@@ -419,6 +421,7 @@ void QQuickWebViewPrivate::setNeedsDisplay()
void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURL)
{
Q_Q(QQuickWebView);
+
if (q->url() != pageURL)
return;
@@ -644,6 +647,9 @@ void QQuickWebViewPrivate::setIcon(const QUrl& iconURL)
if (m_iconURL == iconURL)
return;
+ if (!webPageProxy->mainFrame())
+ return;
+
String oldPageURL = QUrl::fromPercentEncoding(m_iconURL.encodedFragment());
String newPageURL = webPageProxy->mainFrame()->url();
@@ -798,34 +804,6 @@ void QQuickWebViewFlickablePrivate::initialize(WKContextRef contextRef, WKPageGr
webPageProxy->setUseFixedLayout(true);
}
-QPointF QQuickWebViewFlickablePrivate::pageItemPos()
-{
- Q_Q(QQuickWebView);
- // Flickable moves its contentItem so we need to take that position into account,
- // as well as the potential displacement of the page on the contentItem because
- // of additional QML items.
- qreal xPos = q->contentItem()->x() + pageView->x();
- qreal yPos = q->contentItem()->y() + pageView->y();
- return QPointF(xPos, yPos);
-}
-
-void QQuickWebViewFlickablePrivate::updateContentsSize(const QSizeF& size)
-{
- Q_Q(QQuickWebView);
-
- // Make sure that the contentItem is sized to the page
- // if the user did not add other flickable items in QML.
- // If the user adds items in QML he has to make sure to
- // disable the default content item size property on the WebView
- // and bind the contentWidth and contentHeight accordingly.
- // This is in accordance with normal QML Flickable behaviour.
- if (!m_useDefaultContentItemSize)
- return;
-
- q->setContentWidth(size.width());
- q->setContentHeight(size.height());
-}
-
void QQuickWebViewFlickablePrivate::onComponentComplete()
{
Q_Q(QQuickWebView);
@@ -835,7 +813,7 @@ void QQuickWebViewFlickablePrivate::onComponentComplete()
QObject::connect(interactionEngine.data(), SIGNAL(contentSuspendRequested()), q, SLOT(_q_suspend()));
QObject::connect(interactionEngine.data(), SIGNAL(contentResumeRequested()), q, SLOT(_q_resume()));
- QObject::connect(interactionEngine.data(), SIGNAL(contentViewportChanged(QPointF)), q, SLOT(_q_contentViewportChanged(QPointF)));
+ QObject::connect(interactionEngine.data(), SIGNAL(informVisibleContentChange(QPointF)), q, SLOT(_q_onInformVisibleContentChange(QPointF)));
_q_resume();
@@ -868,7 +846,7 @@ void QQuickWebViewFlickablePrivate::didChangeViewportProperties(const WebCore::V
// If the web app successively changes the viewport on purpose
// it wants to be in control and we should disable animations.
- interactionEngine->ensureContentWithinViewportBoundary(/*immediate*/ true);
+ interactionEngine->setItemRectVisible(interactionEngine->nearestValidBounds());
}
void QQuickWebViewFlickablePrivate::updateViewportSize()
@@ -887,10 +865,10 @@ void QQuickWebViewFlickablePrivate::updateViewportSize()
// it can resize the content accordingly.
webPageProxy->setViewportSize(viewportSize);
- _q_contentViewportChanged(QPointF());
+ _q_onInformVisibleContentChange(QPointF());
}
-void QQuickWebViewFlickablePrivate::_q_contentViewportChanged(const QPointF& trajectoryVector)
+void QQuickWebViewFlickablePrivate::_q_onInformVisibleContentChange(const QPointF& trajectoryVector)
{
Q_Q(QQuickWebView);
@@ -925,7 +903,7 @@ void QQuickWebViewFlickablePrivate::_q_resume()
pageIsSuspended = false;
webPageProxy->resumeActiveDOMObjectsAndAnimations();
- _q_contentViewportChanged(QPointF());
+ _q_onInformVisibleContentChange(QPointF());
}
void QQuickWebViewFlickablePrivate::pageDidRequestScroll(const QPoint& pos)
@@ -942,15 +920,26 @@ void QQuickWebViewFlickablePrivate::didChangeContentsSize(const QSize& newSize)
float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(attributes, viewportSize, newSize);
+ bool scaleCommitNotified = false;
+
if (!qFuzzyCompare(minimumScale, attributes.minimumScale)) {
interactionEngine->setCSSScaleBounds(minimumScale, attributes.maximumScale);
emit q->experimental()->test()->viewportChanged();
- if (!interactionEngine->hadUserInteraction() && !pageIsSuspended)
+ if (!interactionEngine->hadUserInteraction() && !pageIsSuspended) {
+ // Emits contentsScaleCommitted();
+ scaleCommitNotified = true;
interactionEngine->setCSSScale(minimumScale);
+ }
}
+
+ // Emit for testing purposes, so that it can be verified that
+ // we didn't do scale adjustment.
+ if (!scaleCommitNotified)
+ emit q->experimental()->test()->contentsScaleCommitted();
}
+
/*!
\qmlsignal WebView::onNavigationRequested(WebNavigationRequest request)
@@ -1452,6 +1441,19 @@ void QQuickWebView::stop()
void QQuickWebView::reload()
{
Q_D(QQuickWebView);
+
+ WebFrameProxy* mainFrame = d->webPageProxy->mainFrame();
+ if (mainFrame && !mainFrame->unreachableURL().isEmpty() && mainFrame->url() != blankURL()) {
+ // We are aware of the unreachable url on the UI process side, but since we haven't
+ // loaded alternative/subsitute data for it (an error page eg.) WebCore doesn't know
+ // about the unreachable url yet. If we just do a reload at this point WebCore will try to
+ // reload the currently committed url instead of the unrachable url. To work around this
+ // we override the reload here by doing a manual load.
+ d->webPageProxy->loadURL(mainFrame->unreachableURL());
+ // FIXME: We should make WebCore aware of the unreachable url regardless of substitute-loads
+ return;
+ }
+
const bool reloadFromOrigin = true;
d->webPageProxy->reload(reloadFromOrigin);
}
@@ -1459,10 +1461,11 @@ void QQuickWebView::reload()
QUrl QQuickWebView::url() const
{
Q_D(const QQuickWebView);
- RefPtr<WebFrameProxy> mainFrame = d->webPageProxy->mainFrame();
- if (!mainFrame)
- return QUrl();
- return QUrl(QString(mainFrame->url()));
+
+ // FIXME: Enable once we are sure this should not trigger
+ // Q_ASSERT(d->m_currentUrl == d->webPageProxy->activeURL());
+
+ return QUrl(d->m_currentUrl);
}
void QQuickWebView::setUrl(const QUrl& url)
@@ -1473,6 +1476,19 @@ void QQuickWebView::setUrl(const QUrl& url)
return;
d->webPageProxy->loadURL(url.toString());
+ emitUrlChangeIfNeeded();
+}
+
+// Make sure we don't emit urlChanged unless it actually changed
+void QQuickWebView::emitUrlChangeIfNeeded()
+{
+ Q_D(QQuickWebView);
+
+ WTF::String activeUrl = d->webPageProxy->activeURL();
+ if (activeUrl != d->m_currentUrl) {
+ d->m_currentUrl = activeUrl;
+ emit urlChanged();
+ }
}
QUrl QQuickWebView::icon() const
@@ -1708,6 +1724,7 @@ void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event)
{
Q_D(QQuickWebView);
+ forceActiveFocus();
// If a MouseButtonDblClick was received then we got a MouseButtonPress before
// handleMousePressEvent will take care of double clicks.
d->pageView->eventHandler()->handleMousePressEvent(event);
@@ -1819,24 +1836,19 @@ void QQuickWebView::handleFlickableMouseRelease(const QPointF& position, qint64
External objects such as stylesheets or images referenced in the HTML
document are located relative to \a baseUrl.
+ If an \a unreachableUrl is passed it is used as the url for the loaded
+ content. This is typically used to display error pages for a failed
+ load.
+
\sa WebView::url
*/
-void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl)
-{
- Q_D(QQuickWebView);
- d->webPageProxy->loadHTMLString(html, baseUrl.toString());
-}
-
-QPointF QQuickWebView::pageItemPos()
-{
- Q_D(QQuickWebView);
- return d->pageItemPos();
-}
-
-void QQuickWebView::updateContentsSize(const QSizeF& size)
+void QQuickWebView::loadHtml(const QString& html, const QUrl& baseUrl, const QUrl& unreachableUrl)
{
Q_D(QQuickWebView);
- d->updateContentsSize(size);
+ if (unreachableUrl.isValid())
+ d->webPageProxy->loadAlternateHTMLString(html, baseUrl.toString(), unreachableUrl.toString());
+ else
+ d->webPageProxy->loadHTMLString(html, baseUrl.toString());
}
qreal QQuickWebView::zoomFactor() const
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
index 773f735a9..f33c6e654 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h
@@ -141,10 +141,6 @@ public:
static void platformInitialize(); // Only needed by WTR.
- // Internal API used by WebPage.
- void updateContentsSize(const QSizeF&);
- QPointF pageItemPos();
-
// Private C++-only API.
qreal zoomFactor() const;
void setZoomFactor(qreal);
@@ -154,7 +150,7 @@ public:
void setAllowAnyHTTPSCertificateForLocalHost(bool allow);
public Q_SLOTS:
- void loadHtml(const QString& html, const QUrl& baseUrl = QUrl());
+ void loadHtml(const QString& html, const QUrl& baseUrl = QUrl(), const QUrl& unreachableUrl = QUrl());
void goBack();
void goForward();
@@ -207,9 +203,11 @@ private:
QQuickWebView(WKContextRef, WKPageGroupRef, QQuickItem* parent = 0);
WKPageRef pageRef() const;
+ void emitUrlChangeIfNeeded();
+
Q_PRIVATE_SLOT(d_func(), void _q_suspend());
Q_PRIVATE_SLOT(d_func(), void _q_resume());
- Q_PRIVATE_SLOT(d_func(), void _q_contentViewportChanged(const QPointF&));
+ Q_PRIVATE_SLOT(d_func(), void _q_onInformVisibleContentChange(const QPointF&));
Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged());
Q_PRIVATE_SLOT(d_func(), void _q_onUrlChanged());
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
index ebd06e3ea..572a7f226 100644
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h
@@ -74,10 +74,8 @@ public:
virtual void enableMouseEvents() { }
virtual void disableMouseEvents() { }
- virtual QPointF pageItemPos();
- virtual void updateContentsSize(const QSizeF&) { }
-
- virtual void provisionalLoadDidStart(const QUrl& url);
+ virtual void provisionalLoadDidStart(const WTF::String& url);
+ virtual void didReceiveServerRedirectForProvisionalLoad(const WTF::String& url);
virtual void loadDidCommit();
virtual void didSameDocumentNavigation();
virtual void titleDidChange();
@@ -97,7 +95,7 @@ public:
virtual void _q_suspend() { }
virtual void _q_resume() { }
- virtual void _q_contentViewportChanged(const QPointF& trajectory) { };
+ virtual void _q_onInformVisibleContentChange(const QPointF& trajectory) { };
virtual qreal zoomFactor() const { return 1; }
virtual void setZoomFactor(qreal) { }
@@ -201,6 +199,7 @@ protected:
bool m_allowAnyHTTPSCertificateForLocalHost;
QUrl m_iconURL;
int m_loadProgress;
+ WTF::String m_currentUrl;
};
class QQuickWebViewLegacyPrivate : public QQuickWebViewPrivate {
@@ -226,16 +225,13 @@ public:
virtual void onComponentComplete();
- virtual QPointF pageItemPos();
- virtual void updateContentsSize(const QSizeF&);
-
virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&);
virtual WebKit::QtViewportInteractionEngine* viewportInteractionEngine() { return interactionEngine.data(); }
virtual void updateViewportSize();
virtual void _q_suspend();
virtual void _q_resume();
- virtual void _q_contentViewportChanged(const QPointF& trajectory);
+ virtual void _q_onInformVisibleContentChange(const QPointF& trajectory);
virtual void pageDidRequestScroll(const QPoint& pos);
virtual void didChangeContentsSize(const QSize& newSize);
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp
index 8311528b5..529df01eb 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest.cpp
@@ -38,7 +38,20 @@ QWebKitTest::~QWebKitTest()
{
}
-bool QWebKitTest::touchDoubleTap(QObject* item, qreal x, qreal y, int delay)
+static QTouchEvent::TouchPoint touchPoint(qreal x, qreal y)
+{
+ QPointF localPos(x, y);
+
+ QTouchEvent::TouchPoint point;
+ point.setLastPos(localPos);
+ QRectF touchRect(0, 0, 40, 40);
+ touchRect.moveCenter(localPos);
+ point.setRect(touchRect);
+
+ return point;
+}
+
+bool QWebKitTest::touchTap(QObject* item, qreal x, qreal y, int delay)
{
if (!qobject_cast<QQuickWebView*>(item)) {
// FIXME: We only support the actual web view for now.
@@ -48,16 +61,23 @@ bool QWebKitTest::touchDoubleTap(QObject* item, qreal x, qreal y, int delay)
// FIXME: implement delay using QTest::qWait() or similar.
Q_UNUSED(delay);
+ m_webViewPrivate->pageView->eventHandler()->handleSingleTapEvent(touchPoint(x, y));
- QPointF localPos(x, y);
+ return true;
+}
- QTouchEvent::TouchPoint point;
- point.setLastPos(localPos);
- QRectF touchRect(0, 0, 40, 40);
- touchRect.moveCenter(localPos);
- point.setRect(touchRect);
+bool QWebKitTest::touchDoubleTap(QObject* item, qreal x, qreal y, int delay)
+{
+ if (!qobject_cast<QQuickWebView*>(item)) {
+ // FIXME: We only support the actual web view for now.
+ qWarning("Touch event \"DoubleTap\" not accepted by receiving item");
+ return false;
+ }
+
+ // FIXME: implement delay using QTest::qWait() or similar.
+ Q_UNUSED(delay);
- m_webViewPrivate->pageView->eventHandler()->handleDoubleTapEvent(point);
+ m_webViewPrivate->pageView->eventHandler()->handleDoubleTapEvent(touchPoint(x, y));
return true;
}
@@ -108,5 +128,5 @@ QVariant QWebKitTest::isScalable() const
QVariant QWebKitTest::layoutSize() const
{
- return QSizeF(m_webViewPrivate->attributes.layoutSize.width(), m_webViewPrivate->attributes.layoutSize.height());
+ return QSizeF(m_webViewPrivate->attributes.layoutSize);
}
diff --git a/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h
index f7c7180c1..613486409 100644
--- a/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h
+++ b/Source/WebKit2/UIProcess/API/qt/qwebkittest_p.h
@@ -53,6 +53,7 @@ signals:
void viewportChanged();
public slots:
+ bool touchTap(QObject* item, qreal x, qreal y, int delay = -1);
bool touchDoubleTap(QObject* item, qreal x, qreal y, int delay = -1);
public:
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp
index 0d0bb6902..3d2a95a6c 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/inspectorserver/tst_inspectorserver.cpp
@@ -30,8 +30,8 @@
#include <private/qwebpreferences_p.h>
#define INSPECTOR_SERVER_PORT "23654"
-static const QUrl s_inspectorServerHttpBaseUrl("http://localhost:"INSPECTOR_SERVER_PORT);
-static const QUrl s_inspectorServerWebSocketBaseUrl("ws://localhost:"INSPECTOR_SERVER_PORT);
+static const QUrl s_inspectorServerHttpBaseUrl("http://localhost:" INSPECTOR_SERVER_PORT);
+static const QUrl s_inspectorServerWebSocketBaseUrl("ws://localhost:" INSPECTOR_SERVER_PORT);
class tst_InspectorServer : public QObject {
Q_OBJECT
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp
index 39e6b54cf..6c0cb4b62 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp
+++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp
@@ -70,6 +70,7 @@ static QStringList expectedAPI = QStringList()
<< "QQuickWebView.iconChanged() --> void"
<< "QQuickWebView.linkHovered(QUrl,QString) --> void"
<< "QQuickWebView.navigationRequested(QWebNavigationRequest*) --> void"
+ << "QQuickWebView.loadHtml(QString,QUrl,QUrl) --> void"
<< "QQuickWebView.loadHtml(QString,QUrl) --> void"
<< "QQuickWebView.loadHtml(QString) --> void"
<< "QQuickWebView.goBack() --> void"
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml
index 18763bfef..d3d7786a3 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml
@@ -107,5 +107,13 @@ TestWebView {
tryCompare(webView, "selectorLoaded", true)
compare(webView.title, "No new selection was made")
}
+
+ function test_selectWithSize() {
+ webView.url = Qt.resolvedUrl("../common/selectwithsize.html")
+ verify(webView.waitForLoadSucceeded())
+ titleSpy.clear()
+
+ test_selectFirstThenAcceptDirectly()
+ }
}
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_doubleTapToZoom.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_doubleTapToZoom.qml
index 904f60feb..b2a860e73 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_doubleTapToZoom.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_doubleTapToZoom.qml
@@ -46,15 +46,6 @@ Item {
property variant test: webView.experimental.test
- // Delayed windowShown to workaround problems with Qt5 in debug mode.
- when: false
- Timer {
- running: parent.windowShown
- repeat: false
- interval: 1
- onTriggered: parent.when = true
- }
-
function init() {
resultSpy.clear()
scaleSpy.clear()
@@ -92,15 +83,15 @@ Item {
webView.url = webView.content
verify(webView.waitForLoadSucceeded())
- compare("480x720", documentSize())
+ compare(documentSize(), "480x720")
- compare(1.0, test.contentsScale)
+ compare(test.contentsScale, 1.0)
var rect = elementRect("target");
var newScale = webView.width / (rect.width + 2 * 10) // inflated by 10px
doubleTapAtPoint(rect.left + rect.height / 2, rect.top + rect.width / 2)
- compare(newScale, test.contentsScale)
+ compare(test.contentsScale, newScale)
}
}
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml
index a3083144d..720b4cd04 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_evaluateJavaScript.qml
@@ -10,8 +10,6 @@ Item {
property variant lastMessage
property variant lastResult
- signal resultReceived
-
experimental.preferences.navigatorQtObjectEnabled: true
experimental.onMessageReceived: {
lastMessage = message
@@ -27,7 +25,7 @@ Item {
SignalSpy {
id: resultSpy
target: webView
- signalName: "resultReceived"
+ signalName: "lastResultChanged"
}
TestCase {
@@ -59,7 +57,7 @@ Item {
}
function test_propertyObjectWithChild() {
- messageSpy.clear()
+ resultSpy.clear()
webView.url = "about:blank"
verify(webView.waitForLoadSucceeded())
@@ -75,7 +73,6 @@ Item {
function(result) {
webView.lastResult = result
- webView.resultReceived()
});
resultSpy.wait()
@@ -83,5 +80,111 @@ Item {
compare(JSON.stringify(webView.lastResult),
'{"child":{"level":2},"level":"1"}')
}
+
+ function test_booleanValue() {
+ resultSpy.clear()
+ webView.url = "about:blank"
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() { return true })()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ verify(typeof webView.lastResult === "boolean")
+ compare(webView.lastResult, true)
+ }
+
+ function test_stringValue() {
+ resultSpy.clear()
+ webView.url = "about:blank"
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() { return 'dongs' })()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ verify(typeof webView.lastResult === "string")
+ compare(webView.lastResult, "dongs")
+ }
+
+ function test_integerValue() {
+ resultSpy.clear()
+ webView.url = "about:blank"
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() { return 1337 })()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ verify(typeof webView.lastResult === "number")
+ compare(webView.lastResult, 1337)
+ }
+
+ function test_floatValue() {
+ resultSpy.clear()
+ webView.url = "about:blank"
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() { return 13.37 })()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ verify(typeof webView.lastResult === "number")
+ compare(webView.lastResult, 13.37)
+ }
+
+ function test_queryTitle() {
+ resultSpy.clear()
+ var testUrl = Qt.resolvedUrl("../common/evaluatejavascript.html")
+ webView.url = testUrl
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() {" +
+ " return document.title" +
+ "})()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ compare(webView.lastResult, "Evaluate JavaScript")
+ }
+
+ function test_queryById() {
+ resultSpy.clear()
+ var testUrl = Qt.resolvedUrl("../common/evaluatejavascript.html")
+ webView.url = testUrl
+ verify(webView.waitForLoadSucceeded())
+
+ webView.experimental.evaluateJavaScript(
+ "(function() {" +
+ " return document.getElementById('text').innerHTML" +
+ "})()",
+
+ function(result) {
+ webView.lastResult = result
+ })
+
+ resultSpy.wait()
+ compare(webView.lastResult, "Hello from the WebProcess :-)")
+ }
}
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml
index 20d538fbf..8210040e8 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml
@@ -35,7 +35,8 @@ TestWebView {
compare(spy.count, 0)
var url = Qt.resolvedUrl("../common/favicon.html")
webView.url = url
- spy.wait()
+ verify(webView.waitForLoadSucceeded())
+ expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133")
compare(spy.count, 1)
compare(favicon.width, 48)
compare(favicon.height, 48)
@@ -45,10 +46,12 @@ TestWebView {
compare(spy.count, 0)
var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!")
webView.url = url
- spy.wait()
+ verify(webView.waitForLoadSucceeded())
+ expectFail("", "https://bugs.webkit.org/show_bug.cgi?id=87133")
compare(spy.count, 1)
compare(favicon.width, 16)
compare(favicon.height, 16)
+
}
}
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_fitToView.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_fitToView.qml
new file mode 100644
index 000000000..febd948b8
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_fitToView.qml
@@ -0,0 +1,99 @@
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebKit 3.0
+import QtWebKit.experimental 1.0
+import Test 1.0
+import "../common"
+
+Item {
+ TestWebView {
+ id: webView
+ width: 480
+ height: 720
+
+ property variant result
+
+ experimental.test.onContentsScaleCommitted: scaleChanged()
+
+ property variant content: "data:text/html," +
+ "<head>" +
+ " <meta name='viewport' content='width=device-width'>" +
+ "</head>" +
+ "<body style='margin: 0px'>" +
+ " <div id='target' style='display:none; width:960px; height:1440px;'></div>" +
+ "</body>"
+
+ signal resultReceived
+ signal scaleChanged
+ }
+
+ SignalSpy {
+ id: resultSpy
+ target: webView
+ signalName: "resultReceived"
+ }
+
+ SignalSpy {
+ id: scaleSpy
+ target: webView
+ signalName: "scaleChanged"
+ }
+
+ TestCase {
+ name: "FitToView"
+
+ property variant test: webView.experimental.test
+
+ function init() {
+ resultSpy.clear()
+ scaleSpy.clear()
+ }
+
+ function run(signalSpy, script) {
+ signalSpy.clear();
+ var result;
+ webView.experimental.evaluateJavaScript(
+ script, function(value) { webView.resultReceived(); result = value });
+ signalSpy.wait();
+ return result;
+ }
+
+ function documentSize() {
+ return run(resultSpy, "document.width + 'x' + document.height");
+ }
+
+ function setDisplay(id, value) {
+ // When changing to/from 'none' to 'block', this will result in a
+ // contentsScaleCommitted scale, even if it results in the same
+ // scale, making it possible to check whether user interaction
+ // blocks fit-to-view or not.
+ run(scaleSpy, "document.getElementById('" + id + "').style.display = '" + value + "';");
+ }
+
+ function test_basic() {
+ webView.url = webView.content
+ verify(webView.waitForLoadSucceeded())
+
+ compare(documentSize(), "480x720")
+ compare(test.contentsScale, 1.0)
+
+ setDisplay("target", "block")
+ compare(documentSize(), "960x1440")
+ compare(test.contentsScale, 0.5)
+
+ // Add user interaction.
+ test.touchTap(webView, 10, 10)
+
+ // We are no longer within valid bounds after this change
+ // so we have to change our scale back to 1.0.
+ setDisplay("target", "none")
+ compare(documentSize(), "480x720")
+ compare(test.contentsScale, 1.0)
+
+ // We had user interaction, size should change but not scale.
+ setDisplay("target", "block")
+ compare(documentSize(), "960x1440")
+ compare(test.contentsScale, 1.0)
+ }
+ }
+}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml
index 7ab69bd15..f77c7f87a 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml
@@ -10,6 +10,8 @@ TestWebView {
property int numLoadStarted: 0
property int numLoadSucceeded: 0
+ focus: true
+
onLoadProgressChanged: {
if (watchProgress && webView.loadProgress != 100) {
watchProgress = false
@@ -27,6 +29,8 @@ TestWebView {
TestCase {
id: test
name: "WebViewLoadUrl"
+ when: windowShown
+
function test_loadIgnoreEmptyUrl() {
var url = Qt.resolvedUrl("../common/test1.html")
@@ -58,5 +62,63 @@ TestWebView {
verify(!watchProgress)
compare(webView.url, url)
}
+
+ function test_urlProperty() {
+ var url = Qt.resolvedUrl("../common/test1.html")
+
+ webView.url = url
+ compare(webView.url, url)
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, url)
+
+ var bogusSite = "http://www.somesitethatdoesnotexist.abc/"
+ webView.url = bogusSite
+ compare(webView.url, bogusSite)
+ verify(webView.waitForLoadFailed())
+ compare(webView.url, bogusSite)
+
+ webView.url = "about:blank" // Reset from previous test
+ verify(webView.waitForLoadSucceeded())
+
+ var handleLoadFailed = function(loadRequest) {
+ if (loadRequest.status == WebView.LoadFailedStatus) {
+ compare(webView.url, bogusSite)
+ compare(loadRequest.url, bogusSite)
+ webView.loadHtml("load failed", bogusSite, bogusSite)
+ }
+ }
+ webView.loadingChanged.connect(handleLoadFailed)
+ webView.url = bogusSite
+ compare(webView.url, bogusSite)
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, bogusSite)
+ webView.loadingChanged.disconnect(handleLoadFailed)
+
+ var dataUrl = "data:text/html,foo"
+ webView.url = dataUrl
+ compare(webView.url, dataUrl)
+
+ var redirectUrl = Qt.resolvedUrl("../common/redirect.html")
+ webView.url = redirectUrl
+ compare(webView.url, redirectUrl)
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, redirectUrl)
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, url)
+
+ var linkUrl = Qt.resolvedUrl("../common/link.html")
+ webView.url = linkUrl
+ compare(webView.url, linkUrl)
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, linkUrl)
+ webView.loadingChanged.connect(function(loadRequest) {
+ compare(webView.url, loadRequest.url)
+ compare(webView.url, url)
+ })
+ webView.forceActiveFocus()
+ keyPress(Qt.Key_Return) // Link is focused
+ verify(webView.waitForLoadSucceeded())
+ compare(webView.url, url)
+ }
}
}
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml
index 16ff35c52..71fa3eb9b 100644
--- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml
@@ -195,6 +195,10 @@ Item {
compare(webView2.title, "New Title")
}
+ function unquote(text) {
+ return text[0] === "'" ? text.slice(1, -1) : text
+ }
+
function test_standardFontFamilyChanged() {
var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-family")
webView.url = url
@@ -203,7 +207,7 @@ Item {
titleSpy.clear()
titleSpy.wait()
- compare(webView.title, defaultStandardFontFamily)
+ compare(unquote(webView.title), defaultStandardFontFamily)
webView.experimental.preferences.standardFontFamily = "foobar"
standardFontFamilySpy.wait()
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/evaluatejavascript.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/evaluatejavascript.html
new file mode 100644
index 000000000..023e9ab7f
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/evaluatejavascript.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>Evaluate JavaScript</title>
+ </head>
+ <body>
+ <div id="text">Hello from the WebProcess :-)</div>
+ </body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/link.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/link.html
new file mode 100644
index 000000000..e791b7de4
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/link.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<html>
+<body onload="document.links['foo'].focus();">
+<a name="foo" href="test1.html">Link</a>
+</body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/redirect.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/redirect.html
new file mode 100644
index 000000000..914e5e35a
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/redirect.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<html>
+<head>
+<meta http-equiv="refresh" content="2; url=test1.html"
+</head>
+<body>
+</body>
+</html>
diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/selectwithsize.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/selectwithsize.html
new file mode 100644
index 000000000..f514c46cc
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/selectwithsize.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>No new selection was made</title>
+<script>
+function updateTitle(selectElement) {
+ var index = selectElement.selectedIndex;
+ document.title = selectElement.options[index].value;
+}
+</script>
+</head>
+<body>
+<select size=2 onchange="updateTitle(this)">
+<option value="__open__" >Open</option>
+<option value="__closed__" >Closed</option>
+<option value="__all__" >All</option>
+</select>
+</html>
diff --git a/Source/WebKit2/UIProcess/WebBackForwardList.cpp b/Source/WebKit2/UIProcess/WebBackForwardList.cpp
index 5c567b550..9ffc9a2c9 100644
--- a/Source/WebKit2/UIProcess/WebBackForwardList.cpp
+++ b/Source/WebKit2/UIProcess/WebBackForwardList.cpp
@@ -39,7 +39,7 @@ WebBackForwardList::WebBackForwardList(WebPageProxy* page)
, m_closed(true)
, m_enabled(true)
{
- ASSERT(m_current == NoCurrentItemIndex || m_current < m_entries.size());
+ ASSERT(m_page);
}
WebBackForwardList::~WebBackForwardList()
@@ -61,40 +61,51 @@ void WebBackForwardList::addItem(WebBackForwardListItem* newItem)
{
ASSERT(m_current == NoCurrentItemIndex || m_current < m_entries.size());
- if (m_capacity == 0 || !m_enabled)
+ if (!m_capacity || !m_enabled || !newItem || !m_page)
return;
Vector<RefPtr<APIObject> > removedItems;
- // Toss anything in the forward list
if (m_current != NoCurrentItemIndex) {
+ // Toss everything in the forward list.
unsigned targetSize = m_current + 1;
removedItems.reserveCapacity(m_entries.size() - targetSize);
while (m_entries.size() > targetSize) {
- if (m_page)
- m_page->backForwardRemovedItem(m_entries.last()->itemID());
+ m_page->backForwardRemovedItem(m_entries.last()->itemID());
removedItems.append(m_entries.last().release());
m_entries.removeLast();
}
- }
- // Toss the first item if the list is getting too big, as long as we're not using it
- // (or even if we are, if we only want 1 entry).
- if (m_entries.size() == m_capacity && (m_current != 0 || m_capacity == 1)) {
- if (m_page)
+ // Toss the first item if the list is getting too big, as long as we're not using it
+ // (or even if we are, if we only want 1 entry).
+ if (m_entries.size() == m_capacity && (m_current || m_capacity == 1)) {
m_page->backForwardRemovedItem(m_entries[0]->itemID());
- removedItems.append(m_entries[0].release());
- m_entries.remove(0);
- m_current--;
+ removedItems.append(m_entries[0].release());
+ m_entries.remove(0);
+ m_current--;
+ }
+ } else {
+ // If we have no current item index, we should have no other entries before adding this new item.
+ size_t size = m_entries.size();
+ for (size_t i = 0; i < size; ++i) {
+ m_page->backForwardRemovedItem(m_entries[i]->itemID());
+ removedItems.append(m_entries[i].release());
+ }
+ m_entries.clear();
}
-
- m_entries.insert(m_current + 1, newItem);
- m_current++;
-
- if (m_page)
- m_page->didChangeBackForwardList(newItem, &removedItems);
-
- ASSERT(m_current == NoCurrentItemIndex || m_current < m_entries.size());
+
+ if (m_current == NoCurrentItemIndex)
+ m_current = 0;
+ else
+ m_current++;
+
+ // m_current never be pointing more than 1 past the end of the entries Vector.
+ // If it is, something has gone wrong and we should not try to insert the new item.
+ ASSERT(m_current <= m_entries.size());
+ if (m_current <= m_entries.size())
+ m_entries.insert(m_current, newItem);
+
+ m_page->didChangeBackForwardList(newItem, &removedItems);
}
void WebBackForwardList::goToItem(WebBackForwardListItem* item)
@@ -147,8 +158,11 @@ WebBackForwardListItem* WebBackForwardList::itemAtIndex(int index)
{
ASSERT(m_current == NoCurrentItemIndex || m_current < m_entries.size());
+ if (m_current == NoCurrentItemIndex)
+ return 0;
+
// Do range checks without doing math on index to avoid overflow.
- if (index < -static_cast<int>(m_current))
+ if (index < -backListCount())
return 0;
if (index > forwardListCount())
@@ -232,12 +246,17 @@ void WebBackForwardList::clear()
if (i != m_current)
removedItems.append(m_entries[i].release());
}
-
- m_entries.shrink(1);
- m_entries[0] = currentItem.release();
m_current = 0;
+ if (currentItem) {
+ m_entries.shrink(1);
+ m_entries[0] = currentItem.release();
+ } else {
+ m_entries.clear();
+ m_current = NoCurrentItemIndex;
+ }
+
if (m_page)
m_page->didChangeBackForwardList(0, &removedItems);
}
diff --git a/Source/WebKit2/UIProcess/WebContext.cpp b/Source/WebKit2/UIProcess/WebContext.cpp
index 6987405be..d2f18070e 100644
--- a/Source/WebKit2/UIProcess/WebContext.cpp
+++ b/Source/WebKit2/UIProcess/WebContext.cpp
@@ -612,20 +612,20 @@ void WebContext::addVisitedLinkHash(LinkHash linkHash)
m_visitedLinkProvider.addVisitedLink(linkHash);
}
-void WebContext::sendDidGetPlugins(uint64_t requestID, const Vector<PluginInfo>& pluginInfos)
+void WebContext::sendDidGetPlugins(uint64_t requestID, PassOwnPtr<Vector<PluginInfo> > pluginInfos)
{
ASSERT(isMainThread());
- Vector<PluginInfo> plugins(pluginInfos);
+ OwnPtr<Vector<PluginInfo> > plugins(pluginInfos);
#if PLATFORM(MAC)
// Add built-in PDF last, so that it's not used when a real plug-in is installed.
// NOTE: This has to be done on the main thread as it calls localizedString().
if (!omitPDFSupport())
- plugins.append(BuiltInPDFView::pluginInfo());
+ plugins->append(BuiltInPDFView::pluginInfo());
#endif
- process()->send(Messages::WebProcess::DidGetPlugins(requestID, plugins), 0);
+ process()->send(Messages::WebProcess::DidGetPlugins(requestID, *plugins), 0);
}
void WebContext::handleGetPlugins(uint64_t requestID, bool refresh)
@@ -633,13 +633,15 @@ void WebContext::handleGetPlugins(uint64_t requestID, bool refresh)
if (refresh)
m_pluginInfoStore.refresh();
- Vector<PluginInfo> pluginInfos;
+ OwnPtr<Vector<PluginInfo> > pluginInfos = adoptPtr(new Vector<PluginInfo>);
Vector<PluginModuleInfo> plugins = m_pluginInfoStore.plugins();
for (size_t i = 0; i < plugins.size(); ++i)
- pluginInfos.append(plugins[i].info);
+ pluginInfos->append(plugins[i].info);
- RunLoop::main()->dispatch(bind(&WebContext::sendDidGetPlugins, this, requestID, pluginInfos));
+ // NOTE: We have to pass the PluginInfo vector to the secondary thread via a pointer as otherwise
+ // we'd end up with a deref() race on all the WTF::Strings it contains.
+ RunLoop::main()->dispatch(bind(&WebContext::sendDidGetPlugins, this, requestID, pluginInfos.release()));
}
void WebContext::getPlugins(CoreIPC::Connection*, uint64_t requestID, bool refresh)
@@ -653,11 +655,11 @@ void WebContext::getPluginPath(const String& mimeType, const String& urlString,
String newMimeType = mimeType.lower();
+ blocked = false;
PluginModuleInfo plugin = pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), urlString));
if (!plugin.path)
return;
- blocked = false;
if (pluginInfoStore().shouldBlockPlugin(plugin)) {
blocked = true;
return;
diff --git a/Source/WebKit2/UIProcess/WebContext.h b/Source/WebKit2/UIProcess/WebContext.h
index fa4567ff6..9a708c26e 100644
--- a/Source/WebKit2/UIProcess/WebContext.h
+++ b/Source/WebKit2/UIProcess/WebContext.h
@@ -262,7 +262,7 @@ private:
String platformDefaultLocalStorageDirectory() const;
void handleGetPlugins(uint64_t requestID, bool refresh);
- void sendDidGetPlugins(uint64_t requestID, const Vector<WebCore::PluginInfo>&);
+ void sendDidGetPlugins(uint64_t requestID, PassOwnPtr<Vector<WebCore::PluginInfo> >);
ProcessModel m_processModel;
diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.h b/Source/WebKit2/UIProcess/WebInspectorProxy.h
index 961467284..02cf52cbc 100644
--- a/Source/WebKit2/UIProcess/WebInspectorProxy.h
+++ b/Source/WebKit2/UIProcess/WebInspectorProxy.h
@@ -48,6 +48,10 @@ OBJC_CLASS WKWebInspectorWKView;
#include <WebCore/WindowMessageListener.h>
#endif
+#if PLATFORM(GTK)
+#include "WebInspectorClientGtk.h"
+#endif
+
namespace WebKit {
class WebFrameProxy;
@@ -89,8 +93,11 @@ public:
void createInspectorWindow();
void updateInspectorWindowTitle() const;
void inspectedViewFrameDidChange();
-#elif PLATFORM(GTK)
- void windowDestroyed();
+#endif
+
+#if PLATFORM(GTK)
+ GtkWidget* inspectorView() const { return m_inspectorView; };
+ void initializeInspectorClientGtk(const WKInspectorClientGtk*);
#endif
void showConsole();
@@ -176,6 +183,10 @@ private:
virtual void windowReceivedMessage(HWND, UINT message, WPARAM, LPARAM);
#endif
+#if PLATFORM(GTK)
+ void createInspectorWindow();
+#endif
+
static const unsigned minimumWindowWidth = 500;
static const unsigned minimumWindowHeight = 400;
@@ -202,6 +213,7 @@ private:
HWND m_inspectorWindow;
RefPtr<WebView> m_inspectorView;
#elif PLATFORM(GTK)
+ WebInspectorClientGtk m_client;
GtkWidget* m_inspectorView;
GtkWidget* m_inspectorWindow;
#endif
diff --git a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp
index fa301a2aa..c6c0fadf8 100644
--- a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp
+++ b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp
@@ -460,6 +460,8 @@ void WebLayerTreeRenderer::setActive(bool active)
// and cannot be applied to the newly created instance.
m_renderQueue.clear();
m_isActive = active;
+ if (m_isActive)
+ renderNextFrame();
}
} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp
index e11daf16e..930e79598 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp
@@ -891,6 +891,7 @@ void WebPageProxy::setViewportSize(const IntSize& size)
}
#endif
+#if ENABLE(DRAG_SUPPORT)
void WebPageProxy::dragEntered(DragData* dragData, const String& dragStorageName)
{
SandboxExtension::Handle sandboxExtensionHandle;
@@ -957,6 +958,7 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo
return;
process()->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
}
+#endif // ENABLE(DRAG_SUPPORT)
void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
{
@@ -3461,6 +3463,7 @@ WebPageCreationParameters WebPageProxy::creationParameters() const
#if PLATFORM(MAC)
parameters.isSmartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled;
+ parameters.layerHostingMode = m_layerHostingMode;
#endif
#if PLATFORM(WIN)
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h
index dc9994f1a..72d469590 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.h
+++ b/Source/WebKit2/UIProcess/WebPageProxy.h
@@ -58,8 +58,6 @@
#include "WebPopupMenuProxy.h"
#include "WebResourceLoadClient.h"
#include "WebUIClient.h"
-#include <WebCore/DragActions.h>
-#include <WebCore/DragSession.h>
#include <WebCore/HitTestResult.h>
#include <WebCore/Page.h>
#include <WebCore/PlatformScreen.h>
@@ -73,6 +71,12 @@
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
+
+#if ENABLE(DRAG_SUPPORT)
+#include <WebCore/DragActions.h>
+#include <WebCore/DragSession.h>
+#endif
+
#if PLATFORM(EFL)
#include <Evas.h>
#endif
@@ -514,6 +518,7 @@ public:
void backForwardRemovedItem(uint64_t itemID);
+#if ENABLE(DRAG_SUPPORT)
// Drag and drop support.
void dragEntered(WebCore::DragData*, const String& dragStorageName = String());
void dragUpdated(WebCore::DragData*, const String& dragStorageName = String());
@@ -533,6 +538,8 @@ public:
#if PLATFORM(QT) || PLATFORM(GTK)
void startDrag(const WebCore::DragData&, const ShareableBitmap::Handle& dragImage);
#endif
+#endif
+
void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
@@ -570,8 +577,10 @@ public:
const String& urlAtProcessExit() const { return m_urlAtProcessExit; }
WebFrameProxy::LoadState loadStateAtProcessExit() const { return m_loadStateAtProcessExit; }
+#if ENABLE(DRAG_SUPPORT)
WebCore::DragSession dragSession() const { return m_currentDragSession; }
void resetDragOperation() { m_currentDragSession = WebCore::DragSession(); }
+#endif
void preferencesDidChange();
@@ -1056,7 +1065,10 @@ private:
unsigned m_pendingLearnOrIgnoreWordMessageCount;
bool m_mainFrameHasCustomRepresentation;
+
+#if ENABLE(DRAG_SUPPORT)
WebCore::DragSession m_currentDragSession;
+#endif
String m_pendingAPIRequestURL;
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in
index faec555e1..8541cfb7c 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in
+++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in
@@ -230,6 +230,7 @@ messages -> WebPageProxy {
IgnoreWord(WTF::String word);
# Drag and drop messages
+#if ENABLE(DRAG_SUPPORT)
DidPerformDragControllerAction(WebCore::DragSession dragSession)
#if PLATFORM(MAC)
SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, bool linkDrag)
@@ -241,6 +242,7 @@ messages -> WebPageProxy {
#if PLATFORM(QT) || PLATFORM(GTK)
StartDrag(WebCore::DragData dragData, WebKit::ShareableBitmap::Handle dragImage)
#endif
+#endif
#if PLATFORM(MAC)
# Dictionary support.
diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in
index 93961da44..cd24c741c 100644
--- a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in
+++ b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in
@@ -32,7 +32,7 @@ messages -> WebProcessProxy {
PluginSyncMessageSendTimedOut(WTF::String pluginPath)
#endif
-#if PLATFORM(MAC)
+#if USE(SECURITY_FRAMEWORK)
SecItemRequest(uint64_t requestID, WebKit::SecItemRequestData request) DispatchOnConnectionQueue
SecKeychainItemRequest(uint64_t requestID, WebKit::SecKeychainItemRequestData request) DispatchOnConnectionQueue
#endif
diff --git a/Source/WebKit2/UIProcess/cf/WebBackForwardListCF.cpp b/Source/WebKit2/UIProcess/cf/WebBackForwardListCF.cpp
index 72c3617af..f5ec6a312 100644
--- a/Source/WebKit2/UIProcess/cf/WebBackForwardListCF.cpp
+++ b/Source/WebKit2/UIProcess/cf/WebBackForwardListCF.cpp
@@ -58,10 +58,14 @@ CFDictionaryRef WebBackForwardList::createCFDictionaryRepresentation(WebPageProx
RetainPtr<CFMutableArrayRef> entries(AdoptCF, CFArrayCreateMutable(0, m_entries.size(), &kCFTypeArrayCallBacks));
// We may need to update the current index to account for entries that are filtered by the callback.
- int currentIndex = m_current;
+ CFIndex currentIndex = m_current;
for (size_t i = 0; i < m_entries.size(); ++i) {
- RefPtr<WebURL> webURL = WebURL::create(m_entries[i]->url());
+ // If we somehow ended up with a null entry then we should consider the data invalid and not save session history at all.
+ ASSERT(m_entries[i]);
+ if (!m_entries[i])
+ return 0;
+
if (filter && !filter(toAPI(m_page), WKPageGetSessionHistoryURLValueType(), toURLRef(m_entries[i]->originalURL().impl()), context)) {
if (i <= static_cast<size_t>(m_current))
currentIndex--;
@@ -82,9 +86,18 @@ CFDictionaryRef WebBackForwardList::createCFDictionaryRepresentation(WebPageProx
RetainPtr<CFDictionaryRef> entryDictionary(AdoptCF, CFDictionaryCreate(0, keys, values, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
CFArrayAppendValue(entries.get(), entryDictionary.get());
}
+
+ // If all items before and including the current item were filtered then currentIndex will be -1.
+ // Assuming we didn't start out with NoCurrentItemIndex, we should store "current" to point at the first item.
+ if (currentIndex == -1 && m_current != NoCurrentItemIndex && CFArrayGetCount(entries.get()))
+ currentIndex = 0;
- ASSERT(currentIndex < CFArrayGetCount(entries.get()) && currentIndex >= static_cast<int>(NoCurrentItemIndex));
- RetainPtr<CFNumberRef> currentIndexNumber(AdoptCF, CFNumberCreate(0, kCFNumberIntType, &currentIndex));
+ // FIXME: We're relying on currentIndex == -1 to mean the exact same thing as NoCurrentItemIndex (UINT_MAX) in unsigned form.
+ // That seems implicit and fragile and we should find a better way of representing the NoCurrentItemIndex case.
+ if (m_current == NoCurrentItemIndex || !CFArrayGetCount(entries.get()))
+ currentIndex = -1;
+
+ RetainPtr<CFNumberRef> currentIndexNumber(AdoptCF, CFNumberCreate(0, kCFNumberCFIndexType, &currentIndex));
const void* keys[2] = { SessionHistoryCurrentIndexKey(), SessionHistoryEntriesKey() };
const void* values[2] = { currentIndexNumber.get(), entries.get() };
@@ -100,11 +113,16 @@ bool WebBackForwardList::restoreFromCFDictionaryRepresentation(CFDictionaryRef d
return false;
}
- CFIndex currentIndex;
- if (!CFNumberGetValue(cfIndex, kCFNumberCFIndexType, &currentIndex)) {
+ CFIndex currentCFIndex;
+ if (!CFNumberGetValue(cfIndex, kCFNumberCFIndexType, &currentCFIndex)) {
LOG(SessionState, "WebBackForwardList dictionary representation does not have a valid integer current index");
return false;
}
+
+ if (currentCFIndex < -1) {
+ LOG(SessionState, "WebBackForwardList dictionary representation contains a negative current index that is bogus (%ld)", currentCFIndex);
+ return false;
+ }
CFArrayRef cfEntries = (CFArrayRef)CFDictionaryGetValue(dictionary, SessionHistoryEntriesKey());
if (!cfEntries || CFGetTypeID(cfEntries) != CFArrayGetTypeID()) {
@@ -113,12 +131,16 @@ bool WebBackForwardList::restoreFromCFDictionaryRepresentation(CFDictionaryRef d
}
CFIndex size = CFArrayGetCount(cfEntries);
- if (currentIndex != static_cast<CFIndex>(NoCurrentItemIndex) && currentIndex >= size) {
- LOG(SessionState, "WebBackForwardList dictionary representation contains an invalid current index (%ld) for the number of entries (%ld)", currentIndex, size);
+ if (currentCFIndex < -1 || currentCFIndex >= size ) {
+ LOG(SessionState, "WebBackForwardList dictionary representation contains an invalid current index (%ld) for the number of entries (%ld)", currentCFIndex, size);
return false;
}
- if (currentIndex == static_cast<CFIndex>(NoCurrentItemIndex) && size) {
+ // FIXME: We're relying on currentIndex == -1 to mean the exact same thing as NoCurrentItemIndex (UINT_MAX) in unsigned form.
+ // That seems implicit and fragile and we should find a better way of representing the NoCurrentItemIndex case.
+ uint32_t currentIndex = currentCFIndex == -1 ? NoCurrentItemIndex : static_cast<uint32_t>(currentCFIndex);
+
+ if (currentIndex == NoCurrentItemIndex && size) {
LOG(SessionState, "WebBackForwardList dictionary representation says there is no current item index, but there is a list of %ld entries - this is bogus", size);
return false;
}
diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp
new file mode 100644
index 000000000..448f42378
--- /dev/null
+++ b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebInspectorClientGtk.h"
+
+#include "WKAPICast.h"
+#include "WKSharedAPICast.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+bool WebInspectorClientGtk::openWindow(WebInspectorProxy* inspector)
+{
+ if (!m_client.openWindow)
+ return false;
+ return m_client.openWindow(toAPI(inspector), m_client.clientInfo);
+}
+
+void WebInspectorClientGtk::didClose(WebInspectorProxy* inspector)
+{
+ if (!m_client.didClose)
+ return;
+ m_client.didClose(toAPI(inspector), m_client.clientInfo);
+}
+
+bool WebInspectorClientGtk::bringToFront(WebInspectorProxy* inspector)
+{
+ if (!m_client.bringToFront)
+ return false;
+ return m_client.bringToFront(toAPI(inspector), m_client.clientInfo);
+}
+
+void WebInspectorClientGtk::inspectedURLChanged(WebInspectorProxy* inspector, const String& url)
+{
+ if (!m_client.inspectedURLChanged)
+ return;
+ m_client.inspectedURLChanged(toAPI(inspector), toAPI(url.impl()), m_client.clientInfo);
+}
+
+bool WebInspectorClientGtk::attach(WebInspectorProxy* inspector)
+{
+ if (!m_client.attach)
+ return false;
+ return m_client.attach(toAPI(inspector), m_client.clientInfo);
+}
+
+bool WebInspectorClientGtk::detach(WebInspectorProxy* inspector)
+{
+ if (!m_client.detach)
+ return false;
+ return m_client.detach(toAPI(inspector), m_client.clientInfo);
+}
+
+void WebInspectorClientGtk::didChangeAttachedHeight(WebInspectorProxy* inspector, unsigned height)
+{
+ if (!m_client.didChangeAttachedHeight)
+ return;
+ m_client.didChangeAttachedHeight(toAPI(inspector), height, m_client.clientInfo);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h
new file mode 100644
index 000000000..89d0f73d9
--- /dev/null
+++ b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebInspectorClientGtk_h
+#define WebInspectorClientGtk_h
+
+#include "APIClient.h"
+#include "WKInspectorClientGtk.h"
+
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+class APIObject;
+class WebInspectorProxy;
+
+class WebInspectorClientGtk : public APIClient<WKInspectorClientGtk, kWKInspectorClientGtkCurrentVersion> {
+public:
+ bool openWindow(WebInspectorProxy*);
+ void didClose(WebInspectorProxy*);
+ bool bringToFront(WebInspectorProxy*);
+ void inspectedURLChanged(WebInspectorProxy*, const String& url);
+ bool attach(WebInspectorProxy*);
+ bool detach(WebInspectorProxy*);
+ void didChangeAttachedHeight(WebInspectorProxy*, unsigned height);
+};
+
+} // namespace WebKit
+
+#endif // WebInspectorClientGtk_h
diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp
index 3aaab77e2..425d799ac 100644
--- a/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp
+++ b/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
* Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved.
+ * Copyright (C) 2012 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,9 +32,8 @@
#include "WebKitWebViewBasePrivate.h"
#include "WebProcessProxy.h"
-
#include <WebCore/FileSystem.h>
-#include <WebCore/NotImplemented.h>
+#include <WebCore/GtkUtilities.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <wtf/gobject/GOwnPtr.h>
@@ -54,24 +54,18 @@ static const char* inspectorFilesBasePath()
return inspectorFilesPath;
}
-static gboolean inspectorWindowDestroyed(GtkWidget* window, GdkEvent*, gpointer userData)
+static void inspectorViewDestroyed(GtkWidget*, gpointer userData)
{
WebInspectorProxy* inspectorProxy = static_cast<WebInspectorProxy*>(userData);
// Inform WebProcess about webinspector closure. Not doing so,
// results in failure of subsequent invocation of webinspector.
inspectorProxy->close();
- inspectorProxy->windowDestroyed();
-
- return FALSE;
}
-void WebInspectorProxy::windowDestroyed()
+void WebInspectorProxy::initializeInspectorClientGtk(const WKInspectorClientGtk* inspectorClient)
{
- ASSERT(m_inspectorView);
- ASSERT(m_inspectorWindow);
- m_inspectorView = 0;
- m_inspectorWindow = 0;
+ m_client.initialize(inspectorClient);
}
WebPageProxy* WebInspectorProxy::platformCreateInspectorPage()
@@ -79,45 +73,82 @@ WebPageProxy* WebInspectorProxy::platformCreateInspectorPage()
ASSERT(m_page);
ASSERT(!m_inspectorView);
m_inspectorView = GTK_WIDGET(webkitWebViewBaseCreate(page()->process()->context(), inspectorPageGroup()));
+ g_object_add_weak_pointer(G_OBJECT(m_inspectorView), reinterpret_cast<void**>(&m_inspectorView));
return webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_inspectorView));
}
-void WebInspectorProxy::platformOpen()
+void WebInspectorProxy::createInspectorWindow()
{
+ if (m_client.openWindow(this))
+ return;
+
ASSERT(!m_inspectorWindow);
m_inspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget* inspectedViewParent = gtk_widget_get_toplevel(m_page->viewWidget());
+ if (WebCore::widgetIsOnscreenToplevelWindow(inspectedViewParent))
+ gtk_window_set_transient_for(GTK_WINDOW(m_inspectorWindow), GTK_WINDOW(inspectedViewParent));
+
gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), _("Web Inspector"));
gtk_window_set_default_size(GTK_WINDOW(m_inspectorWindow), initialWindowWidth, initialWindowHeight);
- g_signal_connect(m_inspectorWindow, "delete-event", G_CALLBACK(inspectorWindowDestroyed), this);
gtk_container_add(GTK_CONTAINER(m_inspectorWindow), m_inspectorView);
gtk_widget_show(m_inspectorView);
- gtk_widget_show(m_inspectorWindow);
+
+ g_object_add_weak_pointer(G_OBJECT(m_inspectorWindow), reinterpret_cast<void**>(&m_inspectorWindow));
+ gtk_window_present(GTK_WINDOW(m_inspectorWindow));
+}
+
+void WebInspectorProxy::platformOpen()
+{
+ ASSERT(!m_inspectorWindow);
+ ASSERT(m_inspectorView);
+
+ if (m_isAttached)
+ platformAttach();
+ else
+ createInspectorWindow();
+ g_signal_connect(m_inspectorView, "destroy", G_CALLBACK(inspectorViewDestroyed), this);
}
void WebInspectorProxy::platformDidClose()
{
+ if (m_inspectorView)
+ g_signal_handlers_disconnect_by_func(m_inspectorView, reinterpret_cast<void*>(inspectorViewDestroyed), this);
+
+ m_client.didClose(this);
+
if (m_inspectorWindow) {
gtk_widget_destroy(m_inspectorWindow);
m_inspectorWindow = 0;
- m_inspectorView = 0;
}
+ m_inspectorView = 0;
}
void WebInspectorProxy::platformBringToFront()
{
- notImplemented();
+ if (m_client.bringToFront(this))
+ return;
+
+ GtkWidget* parent = gtk_widget_get_toplevel(m_inspectorView);
+ if (WebCore::widgetIsOnscreenToplevelWindow(parent))
+ gtk_window_present(GTK_WINDOW(parent));
}
bool WebInspectorProxy::platformIsFront()
{
- notImplemented();
+ GtkWidget* parent = gtk_widget_get_toplevel(m_inspectorView);
+ if (WebCore::widgetIsOnscreenToplevelWindow(parent))
+ return m_isVisible && gtk_window_is_active(GTK_WINDOW(parent));
return false;
}
void WebInspectorProxy::platformInspectedURLChanged(const String& url)
{
+ m_client.inspectedURLChanged(this, url);
+
+ if (!m_inspectorWindow)
+ return;
GOwnPtr<gchar> title(g_strdup_printf("%s - %s", _("Web Inspector"), url.utf8().data()));
gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), title.get());
}
@@ -137,23 +168,49 @@ String WebInspectorProxy::inspectorBaseURL() const
unsigned WebInspectorProxy::platformInspectedWindowHeight()
{
- notImplemented();
- return 0;
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(m_page->viewWidget(), &allocation);
+ return allocation.height;
}
void WebInspectorProxy::platformAttach()
{
- notImplemented();
+ GRefPtr<GtkWidget> inspectorView = m_inspectorView;
+ if (m_inspectorWindow) {
+ gtk_container_remove(GTK_CONTAINER(m_inspectorWindow), m_inspectorView);
+ gtk_widget_destroy(m_inspectorWindow);
+ m_inspectorWindow = 0;
+ }
+
+ if (m_client.attach(this))
+ return;
+
+ gtk_container_add(GTK_CONTAINER(m_page->viewWidget()), m_inspectorView);
+ gtk_widget_show(m_inspectorView);
}
void WebInspectorProxy::platformDetach()
{
- notImplemented();
+ if (!m_page->isValid())
+ return;
+
+ GRefPtr<GtkWidget> inspectorView = m_inspectorView;
+ if (!m_client.detach(this))
+ gtk_container_remove(GTK_CONTAINER(m_page->viewWidget()), m_inspectorView);
+
+ if (!m_isVisible)
+ return;
+
+ createInspectorWindow();
}
-void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned)
+void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned height)
{
- notImplemented();
+ if (!m_isAttached)
+ return;
+
+ m_client.didChangeAttachedHeight(this, height);
+ webkitWebViewBaseSetInspectorViewHeight(WEBKIT_WEB_VIEW_BASE(m_page->viewWidget()), height);
}
} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm
index 40f2c2ae7..3afd2ab47 100644
--- a/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm
+++ b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm
@@ -105,9 +105,8 @@ void BackingStore::resetScrolledRect()
CGContextScaleCTM(context.get(), m_deviceScaleFactor, m_deviceScaleFactor);
- CGContextTranslateCTM(context.get(), -m_scrolledRect.location().x(), -m_scrolledRect.location().y());
- CGContextTranslateCTM(context.get(), 0, m_scrolledRect.size().height());
CGContextScaleCTM(context.get(), 1, -1);
+ CGContextTranslateCTM(context.get(), -m_scrolledRect.x(), -m_scrolledRect.maxY());
paint(context.get(), m_scrolledRect);
IntRect sourceRect(IntPoint(), m_scrolledRect.size());
diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm
index 9b3c11422..649176215 100644
--- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm
+++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm
@@ -382,6 +382,7 @@ static void completeFinishExitFullScreenAnimationAfterRepaint(WKErrorRef, void*)
- (void)completeFinishExitFullScreenAnimationAfterRepaint
{
[[_webView window] setAutodisplay:YES];
+ [[_webView window] displayIfNeeded];
NSEnableScreenUpdates();
}
diff --git a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm
index c21f16a6d..a4ae7eac7 100644
--- a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm
+++ b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm
@@ -42,9 +42,11 @@
#import <WebKitSystemInterface.h>
#import <wtf/text/StringConcatenate.h>
+#if USE(APPKIT)
@interface NSApplication (Details)
- (void)speakString:(NSString *)string;
@end
+#endif
#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
@@ -121,6 +123,8 @@ String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent
return makeString("Mozilla/5.0 (Macintosh; " PROCESSOR " Mac OS X ", osVersion, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko) ", applicationNameForUserAgent);
}
+#if USE(APPKIT)
+
void WebPageProxy::getIsSpeaking(bool& isSpeaking)
{
isSpeaking = [NSApp isSpeaking];
@@ -140,6 +144,8 @@ void WebPageProxy::searchWithSpotlight(const String& string)
{
[[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:nsStringFromWebCoreString(string)];
}
+
+#endif // USE(APPKIT)
CGContextRef WebPageProxy::containingWindowGraphicsContext()
{
@@ -294,6 +300,7 @@ bool WebPageProxy::readSelectionFromPasteboard(const String& pasteboardName)
return result;
}
+#if ENABLE(DRAG_SUPPORT)
void WebPageProxy::setDragImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& dragImageHandle, bool isLinkDrag)
{
RefPtr<ShareableBitmap> dragImage = ShareableBitmap::create(dragImageHandle);
@@ -316,6 +323,7 @@ void WebPageProxy::setPromisedData(const String& pasteboardName, const SharedMem
}
m_pageClient->setPromisedData(pasteboardName, imageBuffer, filename, extension, title, url, visibleURL, archiveBuffer);
}
+#endif
void WebPageProxy::performDictionaryLookupAtLocation(const WebCore::FloatPoint& point)
{
@@ -356,7 +364,7 @@ void WebPageProxy::capitalizeWord()
}
void WebPageProxy::setSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled)
-{
+{
if (m_isSmartInsertDeleteEnabled == isSmartInsertDeleteEnabled)
return;
diff --git a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h
index ad22e0a81..ab73cca0c 100644
--- a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h
+++ b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h
@@ -26,6 +26,8 @@
#ifndef WebPopupMenuProxyMac_h
#define WebPopupMenuProxyMac_h
+#if USE(APPKIT)
+
#include "WebPopupMenuProxy.h"
#include <wtf/RetainPtr.h>
@@ -58,4 +60,6 @@ private:
} // namespace WebKit
+#endif // USE(APPKIT)
+
#endif // WebPopupMenuProxyMac_h
diff --git a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm
index c5c715437..b76978107 100644
--- a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm
+++ b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm
@@ -26,6 +26,8 @@
#import "config.h"
#import "WebPopupMenuProxyMac.h"
+#if USE(APPKIT)
+
#import "NativeWebMouseEvent.h"
#import "PageClientImpl.h"
#import "PlatformPopupMenuData.h"
@@ -176,3 +178,5 @@ void WebPopupMenuProxyMac::hidePopupMenu()
}
} // namespace WebKit
+
+#endif // USE(APPKIT)
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
index eb3c5a8d2..d3d5efef2 100644
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
@@ -85,7 +85,7 @@ public:
}
// Make sure that tiles all around the viewport will be requested.
- emit engine->contentViewportChanged(QPointF());
+ emit engine->informVisibleContentChange(QPointF());
}
private:
@@ -98,22 +98,22 @@ static inline bool fuzzyCompare(qreal a, qreal b, qreal epsilon)
return qAbs(a - b) < epsilon;
}
-inline qreal QtViewportInteractionEngine::cssScaleFromItem(qreal itemScale)
+inline qreal QtViewportInteractionEngine::cssScaleFromItem(qreal itemScale) const
{
return itemScale / m_devicePixelRatio;
}
-inline qreal QtViewportInteractionEngine::itemScaleFromCSS(qreal cssScale)
+inline qreal QtViewportInteractionEngine::itemScaleFromCSS(qreal cssScale) const
{
return cssScale * m_devicePixelRatio;
}
-inline qreal QtViewportInteractionEngine::itemCoordFromCSS(qreal value)
+inline qreal QtViewportInteractionEngine::itemCoordFromCSS(qreal value) const
{
return value * m_devicePixelRatio;
}
-inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect)
+inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect) const
{
QRectF itemRect;
@@ -152,12 +152,12 @@ QtViewportInteractionEngine::~QtViewportInteractionEngine()
{
}
-qreal QtViewportInteractionEngine::innerBoundedCSSScale(qreal cssScale)
+qreal QtViewportInteractionEngine::innerBoundedCSSScale(qreal cssScale) const
{
return qBound(m_minimumScale, cssScale, m_maximumScale);
}
-qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale)
+qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale) const
{
if (m_allowsUserScaling) {
// Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
@@ -173,8 +173,6 @@ void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect)
if (itemRect.isEmpty())
return;
- ViewportUpdateDeferrer guard(this);
-
qreal itemScale = m_viewport->width() / itemRect.width();
m_content->setContentsScale(itemScale);
@@ -186,27 +184,41 @@ void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect)
m_viewport->setContentPos(newPosition);
}
-bool QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect)
+// Ease out overshoot of 1.25 combined with ease in correction of 0.25. Both quadratic to have physical motion.
+static qreal physicalOvershoot(qreal t)
+{
+ return (-t * (t - 2)) * 1.25 - (t * t) * 0.25;
+}
+
+void QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect)
{
+ ASSERT(m_scaleAnimation->state() == QAbstractAnimation::Stopped);
+
+ ASSERT(!scrollAnimationActive());
+ if (scrollAnimationActive())
+ return;
+
QRectF currentItemRectVisible = m_viewport->mapRectToWebContent(m_viewport->boundingRect());
if (itemRect == currentItemRectVisible)
- return false;
+ return;
// FIXME: Investigate why that animation doesn't run when we are unfocused.
if (!m_viewport->isVisible() || !m_viewport->hasFocus()) {
// Apply the end result immediately when we are non-visible.
setItemRectVisible(itemRect);
- return true;
+ return;
}
+ QEasingCurve easingCurve;
+ easingCurve.setCustomType(physicalOvershoot);
+
m_scaleAnimation->setDuration(kScaleAnimationDurationMillis);
- m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic);
+ m_scaleAnimation->setEasingCurve(easingCurve);
m_scaleAnimation->setStartValue(currentItemRectVisible);
m_scaleAnimation->setEndValue(itemRect);
m_scaleAnimation->start();
- return true;
}
void QtViewportInteractionEngine::flickableMoveStarted()
@@ -234,7 +246,7 @@ void QtViewportInteractionEngine::flickableMovingPositionUpdate()
{
QPointF newPosition = m_viewport->contentPos();
- emit contentViewportChanged(m_lastScrollPosition - newPosition);
+ emit informVisibleContentChange(m_lastScrollPosition - newPosition);
m_lastScrollPosition = newPosition;
}
@@ -244,11 +256,11 @@ void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation:
switch (newState) {
case QAbstractAnimation::Running:
m_viewport->cancelFlick();
- if (!m_scaleUpdateDeferrer)
- m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent));
+ ASSERT(!m_animationUpdateDeferrer);
+ m_animationUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent));
break;
case QAbstractAnimation::Stopped:
- m_scaleUpdateDeferrer.clear();
+ m_animationUpdateDeferrer.clear();
break;
default:
break;
@@ -275,10 +287,15 @@ void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition
QRectF endVisibleContentRect(endPosition / endItemScale, m_viewport->boundingRect().size() / endItemScale);
setItemRectVisible(endVisibleContentRect);
+
+ // Make sure that tiles all around the viewport will be requested.
+ emit informVisibleContentChange(QPointF());
}
void QtViewportInteractionEngine::touchBegin()
{
+ m_hadUserInteraction = true;
+
// Prevents resuming the page between the user's flicks of the page while the animation is running.
if (scrollAnimationActive())
m_touchUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent));
@@ -302,6 +319,9 @@ QRectF QtViewportInteractionEngine::computePosRangeForItemAtScale(qreal itemScal
void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea)
{
+ // This can only happen as a result of a user interaction.
+ ASSERT(m_hadUserInteraction);
+
QRectF endArea = itemRectFromCSS(targetArea);
qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(2.0));
@@ -336,14 +356,15 @@ void QtViewportInteractionEngine::focusEditableArea(const QRectF& caretArea, con
void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea)
{
+ // This can only happen as a result of a user interaction.
+ ASSERT(m_hadUserInteraction);
+
if (!targetArea.isValid())
return;
- if (scrollAnimationActive() || scaleAnimationActive())
+ if (m_suspendCount)
return;
- m_hadUserInteraction = true;
-
const int margin = 10; // We want at least a little bit of margin.
QRectF endArea = itemRectFromCSS(targetArea.adjusted(-margin, -margin, margin, margin));
@@ -417,11 +438,8 @@ void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoi
animateItemRectVisible(endVisibleContentRect);
}
-bool QtViewportInteractionEngine::ensureContentWithinViewportBoundary(bool immediate)
+QRectF QtViewportInteractionEngine::nearestValidBounds() const
{
- if (scrollAnimationActive() || scaleAnimationActive())
- return false;
-
qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale()));
const QRectF viewportRect = m_viewport->boundingRect();
@@ -434,11 +452,7 @@ bool QtViewportInteractionEngine::ensureContentWithinViewportBoundary(bool immed
QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale);
- if (immediate) {
- setItemRectVisible(endVisibleContentRect);
- return true;
- }
- return !animateItemRectVisible(endVisibleContentRect);
+ return endVisibleContentRect;
}
void QtViewportInteractionEngine::reset()
@@ -475,7 +489,7 @@ void QtViewportInteractionEngine::setCSSScale(qreal scale)
m_content->setContentsScale(itemScaleFromCSS(newScale));
}
-qreal QtViewportInteractionEngine::currentCSSScale()
+qreal QtViewportInteractionEngine::currentCSSScale() const
{
return cssScaleFromItem(m_content->contentsScale());
}
@@ -492,7 +506,9 @@ bool QtViewportInteractionEngine::panGestureActive() const
void QtViewportInteractionEngine::panGestureStarted(const QPointF& position, qint64 eventTimestampMillis)
{
- m_hadUserInteraction = true;
+ // This can only happen as a result of a user interaction.
+ ASSERT(m_hadUserInteraction);
+
m_viewport->handleFlickableMousePress(position, eventTimestampMillis);
m_lastPinchCenterInViewportCoordinates = position;
}
@@ -528,7 +544,8 @@ bool QtViewportInteractionEngine::scaleAnimationActive() const
void QtViewportInteractionEngine::cancelScrollAnimation()
{
- ViewportUpdateDeferrer guard(this);
+ if (!scrollAnimationActive())
+ return;
// If the pan gesture recognizer receives a touch begin event
// during an ongoing kinetic scroll animation of a previous
@@ -536,7 +553,7 @@ void QtViewportInteractionEngine::cancelScrollAnimation()
// immediately positioned back to valid boundaries.
m_viewport->cancelFlick();
- ensureContentWithinViewportBoundary(/*immediate*/ true);
+ setItemRectVisible(nearestValidBounds());
}
void QtViewportInteractionEngine::interruptScaleAnimation()
@@ -552,10 +569,12 @@ bool QtViewportInteractionEngine::pinchGestureActive() const
void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates)
{
+ // This can only happen as a result of a user interaction.
+ ASSERT(m_hadUserInteraction);
+
if (!m_allowsUserScaling)
return;
- m_hadUserInteraction = true;
m_scaleStack.clear();
m_zoomOutScale = 0.0;
@@ -565,7 +584,7 @@ void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenter
m_pinchStartScale = m_content->contentsScale();
// Reset the tiling look-ahead vector so that tiles all around the viewport will be requested on pinch-end.
- emit contentViewportChanged(QPointF());
+ emit informVisibleContentChange(QPointF());
}
void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor)
@@ -598,9 +617,9 @@ void QtViewportInteractionEngine::pinchGestureEnded()
return;
m_pinchStartScale = -1;
- // Clear the update deferrer now if we're in our final position and there won't be any animation to clear it later.
- if (ensureContentWithinViewportBoundary())
- m_scaleUpdateDeferrer.clear();
+
+ animateItemRectVisible(nearestValidBounds());
+ m_scaleUpdateDeferrer.clear(); // Clear after starting potential animation, which takes over deferring.
}
void QtViewportInteractionEngine::pinchGestureCancelled()
@@ -609,14 +628,18 @@ void QtViewportInteractionEngine::pinchGestureCancelled()
m_scaleUpdateDeferrer.clear();
}
+/*
+ * This is called for all changes of item scale, width or height.
+ * This is called when interacting, ie. during for instance pinch-zooming.
+ *
+ * FIXME: This is currently called twice if you concurrently change width and height.
+ */
void QtViewportInteractionEngine::itemSizeChanged()
{
- // FIXME: This needs to be done smarter. What happens if it resizes when we were interacting?
if (m_suspendCount)
return;
- ViewportUpdateDeferrer guard(this);
- ensureContentWithinViewportBoundary(true);
+ setItemRectVisible(nearestValidBounds());
}
void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale)
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
index accfc6ad7..ba540d548 100644
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
@@ -55,15 +55,15 @@ public:
void setCSSScaleBounds(qreal minimum, qreal maximum);
void setCSSScale(qreal);
- qreal currentCSSScale();
-
- bool ensureContentWithinViewportBoundary(bool immediate = false);
+ qreal currentCSSScale() const;
void setAllowsUserScaling(bool allow) { m_allowsUserScaling = allow; }
void setContentToDevicePixelRatio(qreal ratio) {m_devicePixelRatio = ratio; }
void setItemRectVisible(const QRectF&);
- bool animateItemRectVisible(const QRectF&);
+ void animateItemRectVisible(const QRectF&);
+
+ QRectF nearestValidBounds() const;
void pagePositionRequest(const QPoint& pos);
void touchBegin();
@@ -96,9 +96,8 @@ Q_SIGNALS:
void contentSuspendRequested();
void contentResumeRequested();
- void contentViewportChanged(const QPointF& trajectory = QPointF());
+ void informVisibleContentChange(const QPointF& trajectory = QPointF());
- void viewportTrajectoryVectorChanged(const QPointF&);
void visibleContentRectAndScaleChanged();
private Q_SLOTS:
@@ -120,13 +119,13 @@ private:
QQuickWebView* const m_viewport;
QQuickWebPage* const m_content;
- qreal cssScaleFromItem(qreal);
- qreal itemScaleFromCSS(qreal);
- qreal itemCoordFromCSS(qreal);
- QRectF itemRectFromCSS(const QRectF&);
+ qreal cssScaleFromItem(qreal) const;
+ qreal itemScaleFromCSS(qreal) const;
+ qreal itemCoordFromCSS(qreal) const;
+ QRectF itemRectFromCSS(const QRectF&) const;
- qreal innerBoundedCSSScale(qreal);
- qreal outerBoundedCSSScale(qreal);
+ qreal innerBoundedCSSScale(qreal) const;
+ qreal outerBoundedCSSScale(qreal) const;
bool m_allowsUserScaling;
qreal m_minimumScale;
@@ -144,6 +143,7 @@ private:
OwnPtr<ViewportUpdateDeferrer> m_scaleUpdateDeferrer;
OwnPtr<ViewportUpdateDeferrer> m_scrollUpdateDeferrer;
OwnPtr<ViewportUpdateDeferrer> m_touchUpdateDeferrer;
+ OwnPtr<ViewportUpdateDeferrer> m_animationUpdateDeferrer;
bool m_hadUserInteraction;
diff --git a/Source/WebKit2/UIProcess/qt/QtWebError.cpp b/Source/WebKit2/UIProcess/qt/QtWebError.cpp
index 9ea2925a9..75884f440 100644
--- a/Source/WebKit2/UIProcess/qt/QtWebError.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtWebError.cpp
@@ -55,10 +55,9 @@ int QtWebError::errorCode() const
return WKErrorGetErrorCode(error.get());
}
-QUrl QtWebError::url() const
+QString QtWebError::url() const
{
- WKRetainPtr<WKURLRef> failingURL = adoptWK(WKErrorCopyFailingURL(error.get()));
- return WKURLCopyQUrl(failingURL.get());
+ return toImpl(error.get())->failingURL();
}
QString QtWebError::description() const
diff --git a/Source/WebKit2/UIProcess/qt/QtWebError.h b/Source/WebKit2/UIProcess/qt/QtWebError.h
index 8f954054e..c2b922603 100644
--- a/Source/WebKit2/UIProcess/qt/QtWebError.h
+++ b/Source/WebKit2/UIProcess/qt/QtWebError.h
@@ -43,7 +43,7 @@ public:
};
Type type() const;
- QUrl url() const;
+ QString url() const;
int errorCode() const;
QString description() const;
bool isCancellation() const;
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
index c7a69cd28..578faa2c9 100644
--- a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp
@@ -36,6 +36,7 @@ QtWebPageLoadClient::QtWebPageLoadClient(WKPageRef pageRef, QQuickWebView* webVi
loadClient.version = kWKPageLoaderClientCurrentVersion;
loadClient.clientInfo = this;
loadClient.didStartProvisionalLoadForFrame = didStartProvisionalLoadForFrame;
+ loadClient.didReceiveServerRedirectForProvisionalLoadForFrame = didReceiveServerRedirectForProvisionalLoadForFrame;
loadClient.didFailProvisionalLoadWithErrorForFrame = didFailProvisionalLoadWithErrorForFrame;
loadClient.didCommitLoadForFrame = didCommitLoadForFrame;
loadClient.didFinishLoadForFrame = didFinishLoadForFrame;
@@ -49,11 +50,16 @@ QtWebPageLoadClient::QtWebPageLoadClient(WKPageRef pageRef, QQuickWebView* webVi
WKPageSetPageLoaderClient(pageRef, &loadClient);
}
-void QtWebPageLoadClient::didStartProvisionalLoad(const QUrl& url)
+void QtWebPageLoadClient::didStartProvisionalLoad(const WTF::String& url)
{
m_webView->d_func()->provisionalLoadDidStart(url);
}
+void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoad(const WTF::String& url)
+{
+ m_webView->d_func()->didReceiveServerRedirectForProvisionalLoad(url);
+}
+
void QtWebPageLoadClient::didCommitLoad()
{
m_webView->d_func()->loadDidCommit();
@@ -84,16 +90,29 @@ void QtWebPageLoadClient::dispatchLoadSucceeded()
m_webView->d_func()->loadDidSucceed();
}
-void QtWebPageLoadClient::dispatchLoadFailed(const QtWebError& error)
+void QtWebPageLoadClient::dispatchLoadFailed(WebFrameProxy* frame, const QtWebError& error)
{
int errorCode = error.errorCode();
if (error.isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad) {
+ // The active url might have changed
+ m_webView->emitUrlChangeIfNeeded();
+
// Make sure that LoadStartedStatus has a counterpart when e.g. requesting a download.
dispatchLoadSucceeded();
+
return;
}
+ // We set the unreachable url unconditionally so that the current
+ // active url of the webview when the loadingChanged signal is
+ // emitted reflects the failed url, not the previously committed
+ // url. This also ensures that if the user does not do a loadHtml
+ // with an error page and and unreachable url as a reponse to the
+ // failed load, we can still detect the failed url for reloads.
+ frame->setUnreachableURL(error.url());
+ m_webView->emitUrlChangeIfNeeded();
+
m_webView->d_func()->loadDidFail(error);
}
@@ -107,16 +126,23 @@ void QtWebPageLoadClient::didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef
{
if (!WKFrameIsMainFrame(frame))
return;
- QString urlStr(toImpl(frame)->provisionalURL());
- QUrl qUrl = urlStr;
- toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoad(qUrl);
+ toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoad(toImpl(frame)->provisionalURL());
+}
+
+void QtWebPageLoadClient::didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
+{
+ if (!WKFrameIsMainFrame(frame))
+ return;
+
+ WebFrameProxy* wkframe = toImpl(frame);
+ toQtWebPageLoadClient(clientInfo)->didReceiveServerRedirectForProvisionalLoad(wkframe->provisionalURL());
}
void QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo)
{
if (!WKFrameIsMainFrame(frame))
return;
- toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
+ toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(toImpl(frame), error);
}
void QtWebPageLoadClient::didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo)
@@ -137,7 +163,7 @@ void QtWebPageLoadClient::didFailLoadWithErrorForFrame(WKPageRef, WKFrameRef fra
{
if (!WKFrameIsMainFrame(frame))
return;
- toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(error);
+ toQtWebPageLoadClient(clientInfo)->dispatchLoadFailed(toImpl(frame), error);
}
void QtWebPageLoadClient::didSameDocumentNavigationForFrame(WKPageRef, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void* clientInfo)
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h
index 179eb8ed2..68eac0f98 100644
--- a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h
@@ -22,7 +22,9 @@
#define QtWebPageLoadClient_h
#include <QtGlobal>
+#include <WebFrameProxy.h>
#include <WKPage.h>
+#include <wtf/text/WTFString.h>
QT_BEGIN_NAMESPACE
class QUrl;
@@ -39,7 +41,8 @@ public:
QtWebPageLoadClient(WKPageRef, QQuickWebView*);
private:
- void didStartProvisionalLoad(const QUrl&);
+ void didStartProvisionalLoad(const WTF::String&);
+ void didReceiveServerRedirectForProvisionalLoad(const WTF::String&);
void didCommitLoad();
void didSameDocumentNavigation();
void didReceiveTitle();
@@ -47,11 +50,12 @@ private:
void didChangeBackForwardList();
void dispatchLoadSucceeded();
- void dispatchLoadFailed(const QtWebError&);
+ void dispatchLoadFailed(WebFrameProxy*, const QtWebError&);
// WKPageLoadClient callbacks.
static void didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
+ static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
static void didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef, WKErrorRef, WKTypeRef userData, const void* clientInfo);
static void didCommitLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
static void didFinishLoadForFrame(WKPageRef, WKFrameRef, WKTypeRef userData, const void* clientInfo);
diff --git a/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
index 648394b6f..2f92098ca 100644
--- a/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
+++ b/Source/WebKit2/UIProcess/qt/WebPopupMenuProxyQt.cpp
@@ -186,12 +186,15 @@ void PopupMenuItemModel::select(int index)
if (!item.enabled)
return;
- Item& oldItem = m_items[oldIndex];
- oldItem.selected = false;
item.selected = true;
m_selectedModelIndex = index;
- emit dataChanged(this->index(oldIndex), this->index(oldIndex));
+ if (oldIndex != -1) {
+ Item& oldItem = m_items[oldIndex];
+ oldItem.selected = false;
+ emit dataChanged(this->index(oldIndex), this->index(oldIndex));
+ }
+
emit dataChanged(this->index(index), this->index(index));
}