diff options
Diffstat (limited to 'Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp')
-rw-r--r-- | Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp | 163 |
1 files changed, 129 insertions, 34 deletions
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp index 757532f7a..372cfea7c 100644 --- a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp +++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp @@ -22,17 +22,21 @@ #include <JavaScriptCore/JSContextRef.h> #include <JavaScriptCore/JSRetainPtr.h> #include <gio/gio.h> +#include <gst/gst.h> #include <stdlib.h> #include <string.h> #include <webkit2/webkit-web-extension.h> #include <wtf/Deque.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/ProcessID.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> +#define WEBKIT_DOM_USE_UNSTABLE_API +#include <webkitdom/WebKitDOMWebKitNamespace.h> +#include <webkitdom/WebKitDOMUserMessageHandlersNamespace.h> +#include <webkitdom/WebKitDOMUserMessageHandler.h> + static const char introspectionXML[] = "<node>" " <interface name='org.webkit.gtk.WebExtensionTest'>" @@ -46,12 +50,11 @@ static const char introspectionXML[] = " <arg type='t' name='pageID' direction='in'/>" " <arg type='s' name='script' direction='in'/>" " </method>" - " <method name='GetInitializationUserData'>" - " <arg type='s' name='userData' direction='out'/>" - " </method>" " <method name='GetProcessIdentifier'>" " <arg type='u' name='identifier' direction='out'/>" " </method>" + " <method name='RemoveAVPluginsFromGSTRegistry'>" + " </method>" " <signal name='DocumentLoaded'/>" " <signal name='URIChanged'>" " <arg type='s' name='uri' direction='out'/>" @@ -59,8 +62,6 @@ static const char introspectionXML[] = " </interface>" "</node>"; -static GRefPtr<GVariant> initializationUserData; - typedef enum { DocumentLoadedSignal, @@ -83,7 +84,7 @@ struct DelayedSignal { CString uri; }; -Deque<OwnPtr<DelayedSignal>> delayedSignalsQueue; +Deque<DelayedSignal> delayedSignalsQueue; static void emitDocumentLoaded(GDBusConnection* connection) { @@ -98,13 +99,24 @@ static void emitDocumentLoaded(GDBusConnection* connection) g_assert(ok); } -static void documentLoadedCallback(WebKitWebPage*, WebKitWebExtension* extension) +static void documentLoadedCallback(WebKitWebPage* webPage, WebKitWebExtension* extension) { + // FIXME: Too much code just to send a message, we need convenient custom API for this. + WebKitDOMDocument* document = webkit_web_page_get_dom_document(webPage); + GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(document)); + if (WebKitDOMWebKitNamespace* webkit = webkit_dom_dom_window_get_webkit_namespace(window.get())) { + WebKitDOMUserMessageHandlersNamespace* messageHandlers = webkit_dom_webkit_namespace_get_message_handlers(webkit); + if (WebKitDOMUserMessageHandler* handler = webkit_dom_user_message_handlers_namespace_get_handler(messageHandlers, "dom")) + webkit_dom_user_message_handler_post_message(handler, "DocumentLoaded", nullptr); + } + + webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "dom-convenience", "DocumentLoaded"); + gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection"); if (data) emitDocumentLoaded(G_DBUS_CONNECTION(data)); else - delayedSignalsQueue.append(adoptPtr(new DelayedSignal(DocumentLoadedSignal))); + delayedSignalsQueue.append(DelayedSignal(DocumentLoadedSignal)); } static void emitURIChanged(GDBusConnection* connection, const char* uri) @@ -126,11 +138,12 @@ static void uriChangedCallback(WebKitWebPage* webPage, GParamSpec* pspec, WebKit if (data) emitURIChanged(G_DBUS_CONNECTION(data), webkit_web_page_get_uri(webPage)); else - delayedSignalsQueue.append(adoptPtr(new DelayedSignal(URIChangedSignal, webkit_web_page_get_uri(webPage)))); + delayedSignalsQueue.append(DelayedSignal(URIChangedSignal, webkit_web_page_get_uri(webPage))); } static gboolean sendRequestCallback(WebKitWebPage*, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, gpointer) { + gboolean returnValue = FALSE; const char* requestURI = webkit_uri_request_get_uri(request); g_assert(requestURI); @@ -153,17 +166,93 @@ static gboolean sendRequestCallback(WebKitWebPage*, WebKitURIRequest* request, W SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request); g_assert(headers); soup_message_headers_append(headers, "DNT", "1"); + } else if (g_str_has_suffix(requestURI, "/http-get-method")) { + g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "GET"); + g_assert(webkit_uri_request_get_http_method(request) == SOUP_METHOD_GET); + } else if (g_str_has_suffix(requestURI, "/http-post-method")) { + g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "POST"); + g_assert(webkit_uri_request_get_http_method(request) == SOUP_METHOD_POST); + returnValue = TRUE; } else if (g_str_has_suffix(requestURI, "/cancel-this.js")) + returnValue = TRUE; + + return returnValue; +} + +static GVariant* serializeContextMenu(WebKitContextMenu* menu) +{ + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + GList* items = webkit_context_menu_get_items(menu); + for (GList* it = items; it; it = g_list_next(it)) + g_variant_builder_add(&builder, "u", webkit_context_menu_item_get_stock_action(WEBKIT_CONTEXT_MENU_ITEM(it->data))); + return g_variant_builder_end(&builder); +} + +static GVariant* serializeNode(WebKitDOMNode* node) +{ + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(&builder, "{sv}", "Name", g_variant_new_take_string(webkit_dom_node_get_node_name(node))); + g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_uint32(webkit_dom_node_get_node_type(node))); + g_variant_builder_add(&builder, "{sv}", "Contents", g_variant_new_take_string(webkit_dom_node_get_text_content(node))); + WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); + g_variant_builder_add(&builder, "{sv}", "Parent", parent ? g_variant_new_take_string(webkit_dom_node_get_node_name(parent)) : g_variant_new_string("ROOT")); + return g_variant_builder_end(&builder); +} + +static gboolean contextMenuCallback(WebKitWebPage* page, WebKitContextMenu* menu, WebKitWebHitTestResult* hitTestResult, gpointer) +{ + const char* pageURI = webkit_web_page_get_uri(page); + if (!g_strcmp0(pageURI, "ContextMenuTestDefault")) { + webkit_context_menu_set_user_data(menu, serializeContextMenu(menu)); + return FALSE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestCustom")) { + // Remove Back and Forward, and add Inspector action. + webkit_context_menu_remove(menu, webkit_context_menu_first(menu)); + webkit_context_menu_remove(menu, webkit_context_menu_first(menu)); + webkit_context_menu_append(menu, webkit_context_menu_item_new_separator()); + webkit_context_menu_append(menu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT)); + webkit_context_menu_set_user_data(menu, serializeContextMenu(menu)); + return TRUE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestClear")) { + webkit_context_menu_remove_all(menu); + return TRUE; + } + + if (!g_strcmp0(pageURI, "ContextMenuTestNode")) { + WebKitDOMNode* node = webkit_web_hit_test_result_get_node(hitTestResult); + g_assert(WEBKIT_DOM_IS_NODE(node)); + webkit_context_menu_set_user_data(menu, serializeNode(node)); return TRUE; + } return FALSE; } +static void consoleMessageSentCallback(WebKitWebPage* webPage, WebKitConsoleMessage* consoleMessage) +{ + g_assert(consoleMessage); + GRefPtr<GVariant> variant = g_variant_new("(uusus)", webkit_console_message_get_source(consoleMessage), + webkit_console_message_get_level(consoleMessage), webkit_console_message_get_text(consoleMessage), + webkit_console_message_get_line(consoleMessage), webkit_console_message_get_source_id(consoleMessage)); + GUniquePtr<char> messageString(g_variant_print(variant.get(), FALSE)); + GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(webkit_web_page_get_dom_document(webPage))); + g_assert(WEBKIT_DOM_IS_DOM_WINDOW(window.get())); + webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "console", messageString.get()); +} + static void pageCreatedCallback(WebKitWebExtension* extension, WebKitWebPage* webPage, gpointer) { g_signal_connect(webPage, "document-loaded", G_CALLBACK(documentLoadedCallback), extension); g_signal_connect(webPage, "notify::uri", G_CALLBACK(uriChangedCallback), extension); - g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), 0); + g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), nullptr); + g_signal_connect(webPage, "context-menu", G_CALLBACK(contextMenuCallback), nullptr); + g_signal_connect(webPage, "console-message-sent", G_CALLBACK(consoleMessageSentCallback), nullptr); } static JSValueRef echoCallback(JSContextRef jsContext, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) @@ -233,14 +322,20 @@ static void methodCallCallback(GDBusConnection* connection, const char* sender, g_dbus_method_invocation_return_value(invocation, 0); } else if (!g_strcmp0(methodName, "AbortProcess")) { abort(); - } else if (!g_strcmp0(methodName, "GetInitializationUserData")) { - g_assert(initializationUserData); - g_assert(g_variant_is_of_type(initializationUserData.get(), G_VARIANT_TYPE_STRING)); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", - g_variant_get_string(initializationUserData.get(), nullptr))); } else if (!g_strcmp0(methodName, "GetProcessIdentifier")) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", static_cast<guint32>(getCurrentProcessID()))); + } else if (!g_strcmp0(methodName, "RemoveAVPluginsFromGSTRegistry")) { + gst_init(nullptr, nullptr); + static const char* avPlugins[] = { "libav", "omx", "vaapi", nullptr }; + GstRegistry* registry = gst_registry_get(); + for (unsigned i = 0; avPlugins[i]; ++i) { + if (GstPlugin* plugin = gst_registry_find_plugin(registry, avPlugins[i])) { + gst_registry_remove_plugin(registry, plugin); + gst_object_unref(plugin); + } + } + g_dbus_method_invocation_return_value(invocation, nullptr); } } @@ -268,38 +363,38 @@ static void busAcquiredCallback(GDBusConnection* connection, const char* name, g g_object_set_data(G_OBJECT(userData), "dbus-connection", connection); while (delayedSignalsQueue.size()) { - OwnPtr<DelayedSignal> delayedSignal = delayedSignalsQueue.takeFirst(); - switch (delayedSignal->type) { + DelayedSignal delayedSignal = delayedSignalsQueue.takeFirst(); + switch (delayedSignal.type) { case DocumentLoadedSignal: emitDocumentLoaded(connection); break; case URIChangedSignal: - emitURIChanged(connection, delayedSignal->uri.data()); + emitURIChanged(connection, delayedSignal.uri.data()); break; } } } -static GUniquePtr<char> makeBusName(GVariant* userData) +static void registerGResource(void) { - // When the web extension is used by TestMultiprocess, an uint32 - // identifier is passed as user data. It uniquely identifies - // the web process, and the UI side expects it added as suffix to - // the bus name. - if (userData && g_variant_is_of_type(userData, G_VARIANT_TYPE_UINT32)) - return GUniquePtr<char>(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", g_variant_get_uint32(userData))); - - return GUniquePtr<char>(g_strdup("org.webkit.gtk.WebExtensionTest")); + GUniquePtr<char> resourcesPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", "resources", "webkit2gtk-tests-resources.gresource", nullptr)); + GResource* resource = g_resource_load(resourcesPath.get(), nullptr); + g_assert(resource); + + g_resources_register(resource); + g_resource_unref(resource); } extern "C" void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* extension, GVariant* userData) { - initializationUserData = userData; - g_signal_connect(extension, "page-created", G_CALLBACK(pageCreatedCallback), extension); g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectCleared), 0); - GUniquePtr<char> busName(makeBusName(userData)); + registerGResource(); + + g_assert(userData); + g_assert(g_variant_is_of_type(userData, G_VARIANT_TYPE_UINT32)); + GUniquePtr<char> busName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", g_variant_get_uint32(userData))); g_bus_own_name( G_BUS_TYPE_SESSION, busName.get(), |