diff options
Diffstat (limited to 'WebKitTools/DumpRenderTree/gtk')
8 files changed, 799 insertions, 76 deletions
diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp new file mode 100644 index 0000000..ab92e1d --- /dev/null +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2009 Jan Michael Alonzo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AccessibilityController.h" + +#include "AccessibilityUIElement.h" +#include "DumpRenderTree.h" + +#include <atk/atk.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +extern "C" { +extern AtkObject* webkit_web_frame_get_focused_accessible_element(WebKitWebFrame*); +} + +AccessibilityController::AccessibilityController() +{ +} + +AccessibilityController::~AccessibilityController() +{ +} + +AccessibilityUIElement AccessibilityController::focusedElement() +{ + AtkObject* accessible = webkit_web_frame_get_focused_accessible_element(mainFrame); + if (!accessible) + return 0; + + return AccessibilityUIElement(accessible); +} + +AccessibilityUIElement AccessibilityController::rootElement() +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + AtkObject* axObject = gtk_widget_get_accessible(GTK_WIDGET(view)); + return AccessibilityUIElement(axObject); +} diff --git a/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp new file mode 100644 index 0000000..be1bbed --- /dev/null +++ b/WebKitTools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * Copyright (C) 2009 Jan Michael Alonzo + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AccessibilityUIElement.h" + +#include <JavaScriptCore/JSStringRef.h> +#include <wtf/Assertions.h> + +#include <atk/atk.h> +#include <gtk/gtk.h> + + +AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) + : m_element(element) +{ +} + +AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) + : m_element(other.m_element) +{ +} + +AccessibilityUIElement::~AccessibilityUIElement() +{ +} + +void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements) +{ + // FIXME: implement +} + +void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&) +{ + // FIXME: implement +} + +void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children) +{ + int count = childrenCount(); + for (int i = 0; i < count; i++) { + AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); + children.append(AccessibilityUIElement(child)); + } +} + +void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length) +{ + for (unsigned i = location; i < length; i++) { + AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i); + elementVector.append(AccessibilityUIElement(child)); + } +} + +int AccessibilityUIElement::childrenCount() +{ + if (!m_element) + return 0; + + ASSERT(ATK_IS_OBJECT(m_element)); + + return atk_object_get_n_accessible_children(ATK_OBJECT(m_element)); +} + +AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) +{ + // FIXME: implement + return 0; +} + +AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) +{ + Vector<AccessibilityUIElement> children; + getChildrenWithRange(children, index, 1); + + if (children.size() == 1) + return children.at(0); + + return 0; +} + +JSStringRef AccessibilityUIElement::allAttributes() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +AccessibilityUIElement AccessibilityUIElement::titleUIElement() +{ + // FIXME: implement + return 0; +} + +AccessibilityUIElement AccessibilityUIElement::parentElement() +{ + ASSERT(m_element); + AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element)); + + return parent ? AccessibilityUIElement(parent) : 0; +} + +JSStringRef AccessibilityUIElement::attributesOfChildren() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::parameterizedAttributeNames() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::role() +{ + AtkRole role = atk_object_get_role(ATK_OBJECT(m_element)); + + if (!role) + return JSStringCreateWithCharacters(0, 0); + + return JSStringCreateWithUTF8CString(atk_role_get_name(role)); +} + +JSStringRef AccessibilityUIElement::title() +{ + const gchar* name = atk_object_get_name(ATK_OBJECT(m_element)); + + if (!name) + return JSStringCreateWithCharacters(0, 0); + + return JSStringCreateWithUTF8CString(name); +} + +JSStringRef AccessibilityUIElement::description() +{ + const gchar* description = atk_object_get_description(ATK_OBJECT(m_element)); + + if (!description) + return JSStringCreateWithCharacters(0, 0); + + return JSStringCreateWithUTF8CString(description); +} + +JSStringRef AccessibilityUIElement::language() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +double AccessibilityUIElement::x() +{ + int x, y; + + atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); + + return x; +} + +double AccessibilityUIElement::y() +{ + int x, y; + + atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN); + + return y; +} + +double AccessibilityUIElement::width() +{ + int width, height; + + atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); + + return width; +} + +double AccessibilityUIElement::height() +{ + int width, height; + + atk_component_get_size(ATK_COMPONENT(m_element), &width, &height); + + return height; +} + +double AccessibilityUIElement::clickPointX() +{ + return 0.f; +} + +double AccessibilityUIElement::clickPointY() +{ + return 0.f; +} + + +double AccessibilityUIElement::intValue() +{ + GValue value = { 0, { { 0 } } }; + + if (!ATK_IS_VALUE(m_element)) + return 0.0f; + + atk_value_get_current_value(ATK_VALUE(m_element), &value); + + if (G_VALUE_HOLDS_DOUBLE(&value)) + return g_value_get_double(&value); + else if (G_VALUE_HOLDS_INT(&value)) + return static_cast<double>(g_value_get_int(&value)); + else + return 0.0f; +} + +double AccessibilityUIElement::minValue() +{ + GValue value = { 0, { { 0 } } }; + + if (!ATK_IS_VALUE(m_element)) + return 0.0f; + + atk_value_get_minimum_value(ATK_VALUE(m_element), &value); + + if (G_VALUE_HOLDS_DOUBLE(&value)) + return g_value_get_double(&value); + else if (G_VALUE_HOLDS_INT(&value)) + return static_cast<double>(g_value_get_int(&value)); + else + return 0.0f; +} + +double AccessibilityUIElement::maxValue() +{ + GValue value = { 0, { { 0 } } }; + + if (!ATK_IS_VALUE(m_element)) + return 0.0f; + + atk_value_get_maximum_value(ATK_VALUE(m_element), &value); + + if (G_VALUE_HOLDS_DOUBLE(&value)) + return g_value_get_double(&value); + else if (G_VALUE_HOLDS_INT(&value)) + return static_cast<double>(g_value_get_int(&value)); + else + return 0.0f; +} + +JSStringRef AccessibilityUIElement::valueDescription() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::isEnabled() +{ + // FIXME: implement + return false; +} + + +int AccessibilityUIElement::insertionPointLineNumber() +{ + // FIXME: implement + return 0; +} + +bool AccessibilityUIElement::isActionSupported(JSStringRef action) +{ + // FIXME: implement + return false; +} + +bool AccessibilityUIElement::isRequired() const +{ + // FIXME: implement + return false; +} + +JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfRowHeaders() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfColumns() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfRows() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfVisibleCells() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::attributesOfHeader() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +int AccessibilityUIElement::indexInTable() +{ + // FIXME: implement + return 0; +} + +JSStringRef AccessibilityUIElement::rowIndexRange() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +JSStringRef AccessibilityUIElement::columnIndexRange() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +int AccessibilityUIElement::lineForIndex(int) +{ + // FIXME: implement + return 0; +} + +JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) +{ + // FIXME: implement + return 0; +} + +JSStringRef AccessibilityUIElement::selectedTextRange() +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) +{ + // FIXME: implement +} + +JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute) +{ + // FIXME: implement + return JSStringCreateWithCharacters(0, 0); +} + +bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) +{ + // FIXME: implement + return false; +} + +void AccessibilityUIElement::increment() +{ + // FIXME: implement +} + +void AccessibilityUIElement::decrement() +{ + // FIXME: implement +} diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp index d7f220b..ac82dd8 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -31,6 +31,8 @@ #include "config.h" #include "DumpRenderTree.h" +#include "AccessibilityController.h" +#include "GCController.h" #include "LayoutTestController.h" #include "WorkQueue.h" #include "WorkQueueItem.h" @@ -58,6 +60,8 @@ extern gchar* webkit_web_frame_get_inner_text(WebKitWebFrame* frame); extern gchar* webkit_web_frame_dump_render_tree(WebKitWebFrame* frame); extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory); extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame); +extern void webkit_web_frame_clear_main_frame_name(WebKitWebFrame* frame); +extern void webkit_web_view_set_group_name(WebKitWebView* view, const gchar* groupName); } volatile bool done; @@ -65,11 +69,18 @@ static bool printSeparators; static int dumpPixels; static int dumpTree = 1; +AccessibilityController* axController = 0; LayoutTestController* gLayoutTestController = 0; +static GCController* gcController = 0; static WebKitWebView* webView; +static GtkWidget* container; WebKitWebFrame* mainFrame = 0; WebKitWebFrame* topLoadingFrame = 0; guint waitToDumpWatchdog = 0; +bool waitForPolicy = false; + +// This is a list of opened webviews +GSList* webViewList = 0; // current b/f item at the end of the previous test static WebKitWebHistoryItem* prevTestBFItem = NULL; @@ -130,7 +141,7 @@ static gchar* dumpFramesAsText(WebKitWebFrame* frame) if (gLayoutTestController->dumpChildFramesAsText()) { GSList* children = webkit_web_frame_get_children(frame); for (GSList* child = children; child; child = g_slist_next(child)) - appendString(result, dumpFramesAsText((WebKitWebFrame*)children->data)); + appendString(result, dumpFramesAsText(static_cast<WebKitWebFrame* >(child->data))); g_slist_free(children); } @@ -154,9 +165,27 @@ static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current } for (int i = start; i < indent; i++) putchar(' '); - printf("%s", webkit_web_history_item_get_uri(item)); + + // normalize file URLs. + const gchar* uri = webkit_web_history_item_get_uri(item); + gchar* uriScheme = g_uri_parse_scheme(uri); + if (g_strcmp0(uriScheme, "file") == 0) { + gchar* pos = g_strstr_len(uri, -1, "/LayoutTests/"); + if (!pos) + return; + + GString* result = g_string_sized_new(strlen(uri)); + result = g_string_append(result, "(file test):"); + result = g_string_append(result, pos + strlen("/LayoutTests/")); + printf("%s", result->str); + g_string_free(result, TRUE); + } else + printf("%s", uri); + + g_free(uriScheme); + const gchar* target = webkit_web_history_item_get_target(item); - if (target && g_utf8_strlen(target, 0) > 0) + if (target && strlen(target) > 0) printf(" (in frame \"%s\")", target); if (webkit_web_history_item_is_target_item(item)) printf(" **nav target**"); @@ -212,12 +241,25 @@ static void dumpBackForwardListForWebView(WebKitWebView* view) printf("===============================================\n"); } +static void dumpBackForwardListForAllWebViews() +{ + // Dump the back forward list of the main WebView first + dumpBackForwardListForWebView(webView); + + // The view list is prepended. Reverse the list so we get the order right. + GSList* viewList = g_slist_reverse(webViewList); + for (unsigned i = 0; i < g_slist_length(viewList); ++i) + dumpBackForwardListForWebView(WEBKIT_WEB_VIEW(g_slist_nth_data(viewList, i))); +} + static void invalidateAnyPreviousWaitToDumpWatchdog() { if (waitToDumpWatchdog) { g_source_remove(waitToDumpWatchdog); waitToDumpWatchdog = 0; } + + waitForPolicy = false; } static void resetWebViewToConsistentStateBeforeTesting() @@ -226,8 +268,16 @@ static void resetWebViewToConsistentStateBeforeTesting() g_object_set(G_OBJECT(settings), "enable-private-browsing", FALSE, "enable-developer-extras", FALSE, + "enable-spell-checking", TRUE, + "enable-html5-database", TRUE, + "enable-html5-local-storage", TRUE, + "enable-xss-auditor", FALSE, + "javascript-can-open-windows-automatically", TRUE, + "enable-offline-web-application-cache", TRUE, NULL); + webkit_web_frame_clear_main_frame_name(mainFrame); + WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView); g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL); } @@ -241,10 +291,15 @@ void dump() char* result = 0; gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame); - dumpAsText = g_ascii_strcasecmp(responseMimeType, "text/plain"); + dumpAsText = g_str_equal(responseMimeType, "text/plain"); g_free(responseMimeType); - gLayoutTestController->setDumpAsText(dumpAsText); + // Test can request controller to be dumped as text even + // while test's response mime type is not text/plain. + // Overriding this behavior with dumpAsText being false is a bad idea. + if (dumpAsText) + gLayoutTestController->setDumpAsText(dumpAsText); + if (gLayoutTestController->dumpAsText()) result = dumpFramesAsText(mainFrame); else @@ -267,11 +322,8 @@ void dump() if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive()) dumpFrameScrollPosition(mainFrame); - if (gLayoutTestController->dumpBackForwardList()) { - // FIXME: multiple windows support - dumpBackForwardListForWebView(webView); - - } + if (gLayoutTestController->dumpBackForwardList()) + dumpBackForwardListForAllWebViews(); } if (printSeparators) { @@ -312,6 +364,11 @@ static void setDefaultsToConsistentStateValuesForTesting() "default-monospace-font-size", 13, "minimum-font-size", 1, NULL); + + /* Disable the default auth dialog for testing */ + SoupSession* session = webkit_get_default_session(); + soup_session_remove_feature_by_type(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG); + #if PLATFORM(X11) webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR); #endif @@ -352,7 +409,7 @@ static void runTest(const string& testPathOrURL) GtkAllocation size; size.width = isSVGW3CTest ? 480 : maxViewWidth; size.height = isSVGW3CTest ? 360 : maxViewHeight; - gtk_widget_size_allocate(GTK_WIDGET(webView), &size); + gtk_widget_size_allocate(container, &size); if (prevTestBFItem) g_object_unref(prevTestBFItem); @@ -370,6 +427,17 @@ static void runTest(const string& testPathOrURL) while (!done) g_main_context_iteration(NULL, TRUE); + + // Also check if we still have opened webViews and free them. + if (gLayoutTestController->closeRemainingWindowsWhenComplete() || webViewList) { + while (webViewList) { + g_object_unref(WEBKIT_WEB_VIEW(webViewList->data)); + webViewList = g_slist_next(webViewList); + } + g_slist_free(webViewList); + webViewList = 0; + } + // A blank load seems to be necessary to reset state after certain tests. webkit_web_view_open(webView, "about:blank"); @@ -387,16 +455,8 @@ void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*) static gboolean processWork(void* data) { - // quit doing work once a load is in progress - while (WorkQueue::shared()->count() > 0 && !topLoadingFrame) { - WorkQueueItem* item = WorkQueue::shared()->dequeue(); - ASSERT(item); - item->invoke(); - delete item; - } - - // if we didn't start a new load, then we finished all the commands, so we're ready to dump state - if (!topLoadingFrame && !gLayoutTestController->waitToDump()) + // if we finish all the commands, we're ready to dump state + if (WorkQueue::shared()->processWork() && !gLayoutTestController->waitToDump()) dump(); return FALSE; @@ -421,10 +481,17 @@ static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data) { JSValueRef exception = 0; - assert(gLayoutTestController); + ASSERT(gLayoutTestController); gLayoutTestController->makeWindowObject(context, windowObject, &exception); - assert(!exception); + ASSERT(!exception); + + gcController->makeWindowObject(context, windowObject, &exception); + ASSERT(!exception); + + axController->makeWindowObject(context, windowObject, &exception); + ASSERT(!exception); + } static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) @@ -460,6 +527,115 @@ static void webViewTitleChanged(WebKitWebView* view, WebKitWebFrame* frame, cons printf("TITLE CHANGED: %s\n", title ? title : ""); } +static bool webViewNavigationPolicyDecisionRequested(WebKitWebView* view, WebKitWebFrame* frame, + WebKitNetworkRequest* request, + WebKitWebNavigationAction* navAction, + WebKitWebPolicyDecision* policyDecision) +{ + // Use the default handler if we're not waiting for policy, + // i.e., LayoutTestController::waitForPolicyDelegate + if (!waitForPolicy) + return FALSE; + + gchar* typeDescription; + WebKitWebNavigationReason reason; + g_object_get(G_OBJECT(navAction), "reason", &reason, NULL); + + switch(reason) { + case WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED: + typeDescription = g_strdup("link clicked"); + break; + case WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED: + typeDescription = g_strdup("form submitted"); + break; + case WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD: + typeDescription = g_strdup("back/forward"); + break; + case WEBKIT_WEB_NAVIGATION_REASON_RELOAD: + typeDescription = g_strdup("reload"); + break; + case WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED: + typeDescription = g_strdup("form resubmitted"); + break; + case WEBKIT_WEB_NAVIGATION_REASON_OTHER: + typeDescription = g_strdup("other"); + break; + default: + typeDescription = g_strdup("illegal value"); + } + + printf("Policy delegate: attempt to load %s with navigation type '%s'\n", webkit_network_request_get_uri(request), typeDescription); + g_free(typeDescription); + + webkit_web_policy_decision_ignore(policyDecision); + gLayoutTestController->notifyDone(); + + return TRUE; +} + +static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* message, gpointer data) +{ + // Are we doing anything wrong? One test that does not call + // dumpStatusCallbacks gets true here + if (gLayoutTestController->dumpStatusCallbacks()) { + if (message && strcmp(message, "")) + printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message); + } +} + +static gboolean webViewClose(WebKitWebView* view) +{ + ASSERT(view); + + webViewList = g_slist_remove(webViewList, view); + g_object_unref(view); + + return TRUE; +} + + +static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*); + +static WebKitWebView* createWebView() +{ + WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + + // From bug 11756: Use a frame group name for all WebViews created by + // DumpRenderTree to allow testing of cross-page frame lookup. + webkit_web_view_set_group_name(view, "org.webkit.gtk.DumpRenderTree"); + + g_object_connect(G_OBJECT(view), + "signal::load-started", webViewLoadStarted, 0, + "signal::load-finished", webViewLoadFinished, 0, + "signal::window-object-cleared", webViewWindowObjectCleared, 0, + "signal::console-message", webViewConsoleMessage, 0, + "signal::script-alert", webViewScriptAlert, 0, + "signal::script-prompt", webViewScriptPrompt, 0, + "signal::script-confirm", webViewScriptConfirm, 0, + "signal::title-changed", webViewTitleChanged, 0, + "signal::navigation-policy-decision-requested", webViewNavigationPolicyDecisionRequested, 0, + "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0, + "signal::create-web-view", webViewCreate, 0, + "signal::close-web-view", webViewClose, 0, + NULL); + + return view; +} + +static WebKitWebView* webViewCreate(WebKitWebView* view, WebKitWebFrame* frame) +{ + if (!gLayoutTestController->canOpenWindows()) + return 0; + + // Make sure that waitUntilDone has been called. + ASSERT(gLayoutTestController->waitToDump()); + + WebKitWebView* newWebView = createWebView(); + g_object_ref_sink(G_OBJECT(newWebView)); + webViewList = g_slist_prepend(webViewList, newWebView); + return newWebView; +} + int main(int argc, char* argv[]) { g_thread_init(NULL); @@ -482,26 +658,22 @@ int main(int argc, char* argv[]) } GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); - GtkContainer* container = GTK_CONTAINER(gtk_fixed_new()); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(container)); + container = GTK_WIDGET(gtk_scrolled_window_new(NULL, NULL)); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(window), container); gtk_widget_realize(window); - webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); - gtk_container_add(container, GTK_WIDGET(webView)); + webView = createWebView(); + gtk_container_add(GTK_CONTAINER(container), GTK_WIDGET(webView)); gtk_widget_realize(GTK_WIDGET(webView)); + gtk_widget_show_all(container); mainFrame = webkit_web_view_get_main_frame(webView); - g_signal_connect(G_OBJECT(webView), "load-started", G_CALLBACK(webViewLoadStarted), 0); - g_signal_connect(G_OBJECT(webView), "load-finished", G_CALLBACK(webViewLoadFinished), 0); - g_signal_connect(G_OBJECT(webView), "window-object-cleared", G_CALLBACK(webViewWindowObjectCleared), 0); - g_signal_connect(G_OBJECT(webView), "console-message", G_CALLBACK(webViewConsoleMessage), 0); - g_signal_connect(G_OBJECT(webView), "script-alert", G_CALLBACK(webViewScriptAlert), 0); - g_signal_connect(G_OBJECT(webView), "script-prompt", G_CALLBACK(webViewScriptPrompt), 0); - g_signal_connect(G_OBJECT(webView), "script-confirm", G_CALLBACK(webViewScriptConfirm), 0); - g_signal_connect(G_OBJECT(webView), "title-changed", G_CALLBACK(webViewTitleChanged), 0); - setDefaultsToConsistentStateValuesForTesting(); + gcController = new GCController(); + axController = new AccessibilityController(); + if (argc == optind+1 && strcmp(argv[optind], "-") == 0) { char filenameBuffer[2048]; printSeparators = true; @@ -521,5 +693,13 @@ int main(int argc, char* argv[]) runTest(argv[i]); } + delete gcController; + gcController = 0; + + delete axController; + axController = 0; + + g_object_unref(webView); + return 0; } diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h index 1d2f179..7a5a4cf 100644 --- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h +++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTreeGtk.h @@ -32,9 +32,13 @@ #include <webkit/webkitdefines.h> #include <JavaScriptCore/JSBase.h> +#include <glib.h> + extern WebKitWebFrame* mainFrame; extern WebKitWebFrame* topLoadingFrame; extern guint waitToDumpWatchdog; +extern bool waitForPolicy; +extern GSList* webViewList; gchar* JSStringCopyUTF8CString(JSStringRef jsString); diff --git a/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp index 35f1685..87eb413 100644 --- a/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/GCControllerGtk.cpp @@ -29,15 +29,26 @@ #include "config.h" #include "GCController.h" +#include <glib.h> +#include <webkit/webkit.h> + +extern "C" { +extern void webkit_gc_collect_javascript_objects(); +extern void webkit_gc_collect_javascript_objects_on_alternate_thread(gboolean waitUntilDone); +extern gsize webkit_gc_count_javascript_objects(); +} + void GCController::collect() const { + webkit_gc_collect_javascript_objects(); } void GCController::collectOnAlternateThread(bool waitUntilDone) const { + webkit_gc_collect_javascript_objects_on_alternate_thread(waitUntilDone); } size_t GCController::getJSObjectCount() const { - return 0; + return webkit_gc_count_javascript_objects(); } diff --git a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 5c2bae7..009cb97 100644 --- a/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2007 Apple Inc. All rights reserved. * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2009 Jan Michael Alonzo <jmalonzo@gmail.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,12 +40,14 @@ #include <stdio.h> #include <glib.h> +#include <libsoup/soup.h> #include <webkit/webkit.h> extern "C" { bool webkit_web_frame_pause_animation(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element); bool webkit_web_frame_pause_transition(WebKitWebFrame* frame, const gchar* name, double time, const gchar* element); unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame); +void webkit_application_cache_set_maximum_size(unsigned long long size); } LayoutTestController::~LayoutTestController() @@ -86,6 +89,11 @@ JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name) return 0; } +void LayoutTestController::dispatchPendingLoadRequests() +{ + // FIXME: Implement for testing fix for 6727495 +} + void LayoutTestController::display() { displayWebView(); @@ -107,6 +115,7 @@ void LayoutTestController::notifyDone() if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) dump(); m_waitToDump = false; + waitForPolicy = false; } JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url) @@ -115,30 +124,26 @@ JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSSt return JSStringRetain(url); // Do nothing on Unix. } -void LayoutTestController::queueBackNavigation(int howFarBack) +void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target) { - WorkQueue::shared()->queue(new BackItem(howFarBack)); -} + gchar* relativeURL = JSStringCopyUTF8CString(url); + SoupURI* baseURI = soup_uri_new(webkit_web_frame_get_uri(mainFrame)); -void LayoutTestController::queueForwardNavigation(int howFarForward) -{ - WorkQueue::shared()->queue(new ForwardItem(howFarForward)); -} + SoupURI* absoluteURI = soup_uri_new_with_base(baseURI, relativeURL); + soup_uri_free(baseURI); + g_free(relativeURL); -void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target) -{ - // FIXME: We need to resolve relative URLs here - WorkQueue::shared()->queue(new LoadItem(url, target)); -} + gchar* absoluteCString; + if (absoluteURI) { + absoluteCString = soup_uri_to_string(absoluteURI, FALSE); + soup_uri_free(absoluteURI); + } else + absoluteCString = JSStringCopyUTF8CString(url); -void LayoutTestController::queueReload() -{ - WorkQueue::shared()->queue(new ReloadItem); -} + JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString(absoluteCString)); + g_free(absoluteCString); -void LayoutTestController::queueScript(JSStringRef script) -{ - WorkQueue::shared()->queue(new ScriptItem(script)); + WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target)); } void LayoutTestController::setAcceptsEditing(bool acceptsEditing) @@ -152,6 +157,12 @@ void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permis // FIXME: implement } +void LayoutTestController::waitForPolicyDelegate() +{ + waitForPolicy = true; + setWaitToDump(true); +} + void LayoutTestController::setMainFrameIsFirstResponder(bool flag) { // FIXME: implement @@ -221,8 +232,8 @@ void LayoutTestController::setWaitToDump(bool waitUntilDone) int LayoutTestController::windowCount() { - // FIXME: implement - return 1; + // +1 -> including the main view + return g_slist_length(webViewList) + 1; } void LayoutTestController::setPrivateBrowsingEnabled(bool flag) @@ -234,11 +245,26 @@ void LayoutTestController::setPrivateBrowsingEnabled(bool flag) g_object_set(G_OBJECT(settings), "enable-private-browsing", flag, NULL); } +void LayoutTestController::setXSSAuditorEnabled(bool flag) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + ASSERT(view); + + WebKitWebSettings* settings = webkit_web_view_get_settings(view); + g_object_set(G_OBJECT(settings), "enable-xss-auditor", flag, NULL); +} + void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) { // FIXME: implement } +void LayoutTestController::disableImageLoading() +{ + // FIXME: Implement for testing fix for https://bugs.webkit.org/show_bug.cgi?id=27896 + // Also need to make sure image loading is re-enabled for each new test. +} + void LayoutTestController::setIconDatabaseEnabled(bool flag) { // FIXME: implement @@ -261,9 +287,14 @@ void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) // FIXME: implement } -void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled) +void LayoutTestController::setPopupBlockingEnabled(bool flag) { - // FIXME: implement + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + ASSERT(view); + + WebKitWebSettings* settings = webkit_web_view_get_settings(view); + g_object_set(G_OBJECT(settings), "javascript-can-open-windows-automatically", !flag, NULL); + } bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id) @@ -277,6 +308,11 @@ void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) // FIXME: implement } +void LayoutTestController::setCacheModel(int) +{ + // FIXME: implement +} + bool LayoutTestController::isCommandEnabled(JSStringRef /*name*/) { // FIXME: implement @@ -305,7 +341,7 @@ void LayoutTestController::setDatabaseQuota(unsigned long long quota) void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) { - // FIXME: implement + webkit_application_cache_set_maximum_size(size); } bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId) diff --git a/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp b/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp index 9d85476..b7d14eb 100644 --- a/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp +++ b/WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2008 Zan Dobersek <zandobersek@gmail.com> + * Copyright (C) 2009 Holger Hans Peter Freyther * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +32,7 @@ #include "npruntime.h" #include "npfunctions.h" +#include <stdarg.h> #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -67,6 +69,13 @@ webkit_test_plugin_new_instance(NPMIMEType mimetype, obj->returnErrorFromNewStream = TRUE; else if (strcasecmp(argn[i], "logfirstsetwindow") == 0) obj->logSetWindow = TRUE; + else if (strcasecmp(argn[i], "testnpruntime") == 0) + testNPRuntime(instance); + else if (strcasecmp(argn[i], "logSrc") == 0) { + for (int i = 0; i < argc; i++) + if (strcasecmp(argn[i], "src") == 0) + pluginLog(instance, "src: %s", argv[i]); + } } instance->pdata = obj; @@ -90,7 +99,7 @@ webkit_test_plugin_destroy_instance(NPP instance, NPSavedData **save) free(obj->onURLNotify); if (obj->logDestroy) - printf("PLUGIN: NPP_Destroy\n"); + pluginLog(instance, "NPP_Destroy"); browser->releaseobject(&obj->header); } @@ -105,7 +114,7 @@ webkit_test_plugin_set_window(NPP instance, NPWindow *window) if (obj) { if (obj->logSetWindow) { - printf("PLUGIN: NPP_SetWindow: %d %d\n", (int)window->width, (int)window->height); + pluginLog(instance, "NPP_SetWindow: %d %d", (int)window->width, (int)window->height); obj->logSetWindow = false; } } @@ -195,7 +204,7 @@ webkit_test_plugin_handle_event(NPP instance, void* event) return 0; XEvent* evt = static_cast<XEvent*>(event); - fprintf(stderr, "PLUGIN: event %d\n", evt->type); + pluginLog(instance, "event %d", evt->type); return 0; } @@ -218,10 +227,10 @@ webkit_test_plugin_get_value(NPP instance, NPPVariable variable, void *value) switch (variable) { case NPPVpluginNameString: - *((char **)value) = "WebKit Test PlugIn"; + *((char **)value) = const_cast<char*>("WebKit Test PlugIn"); break; case NPPVpluginDescriptionString: - *((char **)value) = "Simple Netscape plug-in that handles test content for WebKit"; + *((char **)value) = const_cast<char*>("Simple Netscape plug-in that handles test content for WebKit"); break; case NPPVpluginNeedsXEmbed: *((NPBool *)value) = TRUE; @@ -257,7 +266,7 @@ webkit_test_plugin_set_value(NPP instance, NPNVariable variable, void *value) char * NP_GetMIMEDescription(void) { - return "application/x-webkit-test-netscape:testnetscape:test netscape content"; + return const_cast<char*>("application/x-webkit-test-netscape:testnetscape:test netscape content"); } NPError @@ -269,8 +278,6 @@ NP_Initialize (NPNetscapeFuncs *aMozillaVTable, NPPluginFuncs *aPluginVTable) if ((aMozillaVTable->version >> 8) > NP_VERSION_MAJOR) return NPERR_INCOMPATIBLE_VERSION_ERROR; - if (aMozillaVTable->size < sizeof (NPNetscapeFuncs)) - return NPERR_INVALID_FUNCTABLE_ERROR; if (aPluginVTable->size < sizeof (NPPluginFuncs)) return NPERR_INVALID_FUNCTABLE_ERROR; diff --git a/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp index 2e81ca8..e0e0ffb 100644 --- a/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp +++ b/WebKitTools/DumpRenderTree/gtk/WorkQueueItemGtk.cpp @@ -36,9 +36,9 @@ gchar* JSStringCopyUTF8CString(JSStringRef jsString) return utf8; } -void LoadItem::invoke() const +bool LoadItem::invoke() const { - gchar* targetString = JSStringCopyUTF8CString(target()); + gchar* targetString = JSStringCopyUTF8CString(m_target.get()); WebKitWebFrame* targetFrame; if (!strlen(targetString)) @@ -47,27 +47,31 @@ void LoadItem::invoke() const targetFrame = webkit_web_frame_find_frame(mainFrame, targetString); g_free(targetString); - gchar* urlString = JSStringCopyUTF8CString(url()); + gchar* urlString = JSStringCopyUTF8CString(m_url.get()); WebKitNetworkRequest* request = webkit_network_request_new(urlString); g_free(urlString); webkit_web_frame_load_request(targetFrame, request); g_object_unref(request); + + return true; } -void ReloadItem::invoke() const +bool ReloadItem::invoke() const { webkit_web_frame_reload(mainFrame); + return true; } -void ScriptItem::invoke() const +bool ScriptItem::invoke() const { WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); - gchar* scriptString = JSStringCopyUTF8CString(script()); + gchar* scriptString = JSStringCopyUTF8CString(m_script.get()); webkit_web_view_execute_script(webView, scriptString); g_free(scriptString); + return true; } -void BackForwardItem::invoke() const +bool BackForwardItem::invoke() const { WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); if (m_howFar == 1) @@ -79,4 +83,5 @@ void BackForwardItem::invoke() const WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(webBackForwardList, m_howFar); webkit_web_view_go_to_back_forward_item(webView, item); } + return true; } |