diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk')
29 files changed, 1270 insertions, 70 deletions
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> |