diff options
Diffstat (limited to 'Tools/DumpRenderTree/gtk')
-rw-r--r-- | Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp | 196 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h | 35 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp | 18 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/DumpRenderTree.cpp | 19 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/EventSender.cpp | 47 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp | 64 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp | 9 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/TextInputController.cpp | 177 | ||||
-rw-r--r-- | Tools/DumpRenderTree/gtk/TextInputController.h | 37 |
9 files changed, 565 insertions, 37 deletions
diff --git a/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp new file mode 100644 index 0000000..be66513 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AccessibilityCallbacks.h" + +#include "AccessibilityController.h" +#include "DumpRenderTree.h" +#include "GOwnPtr.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +static guint stateChangeListenerId = 0; +static guint focusEventListenerId = 0; +static guint activeDescendantChangedListenerId = 0; +static guint childrenChangedListenerId = 0; +static guint propertyChangedListenerId = 0; +static guint visibleDataChangedListenerId = 0; + +static guint loadCompleteListenerId = 0; +static guint loadStoppedListenerId = 0; +static guint reloadListenerId = 0; + +static void printAccessibilityEvent(AtkObject* accessible, const gchar* signalName) +{ + // Sanity check. + if (!accessible || !ATK_IS_OBJECT(accessible) || !signalName) + return; + + const gchar* objectName = atk_object_get_name(accessible); + guint objectRole = atk_object_get_role(accessible); + + // Try to always provide a name to be logged for the object. + if (!objectName || *objectName == '\0') + objectName = "(No name)"; + + printf("Accessibility object emitted \"%s\" / Name: \"%s\" / Role: %d\n", + signalName, objectName, objectRole); +} + +static gboolean axObjectEventListener(GSignalInvocationHint *signalHint, + guint numParamValues, + const GValue *paramValues, + gpointer data) +{ + // At least we should receive the instance emitting the signal. + if (numParamValues < 1) + return TRUE; + + AtkObject* accessible = ATK_OBJECT(g_value_get_object(¶mValues[0])); + if (!accessible || !ATK_IS_OBJECT(accessible)) + return TRUE; + + GSignalQuery signal_query; + GOwnPtr<gchar> signalName; + + g_signal_query(signalHint->signal_id, &signal_query); + + if (!g_strcmp0(signal_query.signal_name, "state-change")) { + signalName.set(g_strdup_printf("state-change:%s = %d", + g_value_get_string(¶mValues[1]), + g_value_get_boolean(¶mValues[2]))); + } else if (!g_strcmp0(signal_query.signal_name, "focus-event")) { + signalName.set(g_strdup_printf("focus-event = %d", + g_value_get_boolean(¶mValues[1]))); + } else if (!g_strcmp0(signal_query.signal_name, "children-changed")) { + signalName.set(g_strdup_printf("children-changed = %d", + g_value_get_uint(¶mValues[1]))); + } else + signalName.set(g_strdup(signal_query.signal_name)); + + printAccessibilityEvent(accessible, signalName.get()); + + return TRUE; +} + +static gboolean axDocumentEventListener(GSignalInvocationHint *signalHint, + guint numParamValues, + const GValue *paramValues, + gpointer data) +{ + // At least we should receive the instance emitting the signal. + if (numParamValues < 1) + return TRUE; + + AtkObject* accessible = ATK_OBJECT(g_value_get_object(¶mValues[0])); + if (!accessible || !ATK_IS_DOCUMENT(accessible)) + return TRUE; + + GSignalQuery signal_query; + g_signal_query(signalHint->signal_id, &signal_query); + + printAccessibilityEvent(accessible, signal_query.signal_name); + + return TRUE; +} + +void connectAccessibilityCallbacks() +{ + // Ensure no callbacks are connected before. + disconnectAccessibilityCallbacks(); + + // Ensure that accessibility is initialized for the WebView by querying for + // the root accessible object, which will create the full hierarchy. + DumpRenderTreeSupportGtk::getRootAccessibleElement(mainFrame); + + // Add global listeners for AtkObject's signals. + stateChangeListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:state-change"); + focusEventListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:focus-event"); + activeDescendantChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:active-descendant-changed"); + childrenChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:children-changed"); + propertyChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:property-change"); + visibleDataChangedListenerId = atk_add_global_event_listener(axObjectEventListener, "Gtk:AtkObject:visible-data-changed"); + + // Ensure the Atk interface types are registered, otherwise + // the AtkDocument signal handlers below won't get registered. + GObject* dummyAxObject = G_OBJECT(g_object_new(ATK_TYPE_OBJECT, 0)); + AtkObject* dummyNoOpAxObject = atk_no_op_object_new(dummyAxObject); + g_object_unref(G_OBJECT(dummyNoOpAxObject)); + g_object_unref(dummyAxObject); + + // Add global listeners for AtkDocument's signals. + loadCompleteListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:load-complete"); + loadStoppedListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:load-stopped"); + reloadListenerId = atk_add_global_event_listener(axDocumentEventListener, "Gtk:AtkDocument:reload"); +} + +void disconnectAccessibilityCallbacks() +{ + // AtkObject signals. + if (stateChangeListenerId) { + atk_remove_global_event_listener(stateChangeListenerId); + stateChangeListenerId = 0; + } + if (focusEventListenerId) { + atk_remove_global_event_listener(focusEventListenerId); + focusEventListenerId = 0; + } + if (activeDescendantChangedListenerId) { + atk_remove_global_event_listener(activeDescendantChangedListenerId); + activeDescendantChangedListenerId = 0; + } + if (childrenChangedListenerId) { + atk_remove_global_event_listener(childrenChangedListenerId); + childrenChangedListenerId = 0; + } + if (propertyChangedListenerId) { + atk_remove_global_event_listener(propertyChangedListenerId); + propertyChangedListenerId = 0; + } + if (visibleDataChangedListenerId) { + atk_remove_global_event_listener(visibleDataChangedListenerId); + visibleDataChangedListenerId = 0; + } + + // AtkDocument signals. + if (loadCompleteListenerId) { + atk_remove_global_event_listener(loadCompleteListenerId); + loadCompleteListenerId = 0; + } + if (loadStoppedListenerId) { + atk_remove_global_event_listener(loadStoppedListenerId); + loadStoppedListenerId = 0; + } + if (reloadListenerId) { + atk_remove_global_event_listener(reloadListenerId); + reloadListenerId = 0; + } +} + diff --git a/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h new file mode 100644 index 0000000..7225757 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AccessibilityCallbacks_h +#define AccessibilityCallbacks_h + +void connectAccessibilityCallbacks(); +void disconnectAccessibilityCallbacks(); + +#endif diff --git a/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp index c572633..da70efc 100644 --- a/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "AccessibilityController.h" +#include "AccessibilityCallbacks.h" #include "AccessibilityUIElement.h" #include "DumpRenderTree.h" #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" @@ -35,6 +36,8 @@ #include <gtk/gtk.h> #include <webkit/webkit.h> +static bool loggingAccessibilityEvents = false; + AccessibilityController::AccessibilityController() { } @@ -79,6 +82,21 @@ void AccessibilityController::setLogValueChangeEvents(bool) { } +void AccessibilityController::setLogAccessibilityEvents(bool logAccessibilityEvents) +{ + if (logAccessibilityEvents == loggingAccessibilityEvents) + return; + + if (!logAccessibilityEvents) { + disconnectAccessibilityCallbacks(); + loggingAccessibilityEvents = false; + return; + } + + connectAccessibilityCallbacks(); + loggingAccessibilityEvents = true; +} + void AccessibilityController::addNotificationListener(PlatformUIElement, JSObjectRef) { } diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp index ff90d81..ff3327f 100644 --- a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -39,6 +39,7 @@ #include "GOwnPtr.h" #include "LayoutTestController.h" #include "PixelDumpSupport.h" +#include "TextInputController.h" #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include "WorkQueue.h" #include "WorkQueueItem.h" @@ -419,6 +420,7 @@ static void resetDefaultsToConsistentValues() "enable-fullscreen", TRUE, NULL); webkit_web_view_set_settings(webView, settings); + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); DumpRenderTreeSupportGtk::clearMainFrameName(mainFrame); @@ -432,7 +434,6 @@ static void resetDefaultsToConsistentValues() WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView); webkit_web_back_forward_list_clear(list); -#ifdef HAVE_LIBSOUP_2_29_90 SoupSession* session = webkit_get_default_session(); SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); @@ -440,11 +441,14 @@ static void resetDefaultsToConsistentValues() // HTTP. Should we initialize it earlier, perhaps? if (jar) g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, NULL); -#endif setlocale(LC_ALL, ""); DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true); + DumpRenderTreeSupportGtk::setIconDatabaseEnabled(false); + + if (axController) + axController->resetToConsistentState(); } static bool useLongRunningServerMode(int argc, char *argv[]) @@ -738,6 +742,11 @@ static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void dump(); } +static gboolean webViewLoadError(WebKitWebView*, WebKitWebFrame*, gchar*, gpointer, gpointer) +{ + return TRUE; // Return true here to disable the default error page. +} + static void webViewDocumentLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*) { if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) { @@ -781,6 +790,11 @@ static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* fram JSValueRef eventSender = makeEventSender(context, !webkit_web_frame_get_parent(frame)); JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); JSStringRelease(eventSenderStr); + + JSStringRef textInputControllerStr = JSStringCreateWithUTF8CString("textInputController"); + JSValueRef textInputController = makeTextInputController(context); + JSObjectSetProperty(context, windowObject, textInputControllerStr, textInputController, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); + JSStringRelease(textInputControllerStr); } static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) @@ -999,6 +1013,7 @@ static WebKitWebView* createWebView() g_object_connect(G_OBJECT(view), "signal::load-started", webViewLoadStarted, 0, "signal::load-finished", webViewLoadFinished, 0, + "signal::load-error", webViewLoadError, 0, "signal::window-object-cleared", webViewWindowObjectCleared, 0, "signal::console-message", webViewConsoleMessage, 0, "signal::script-alert", webViewScriptAlert, 0, diff --git a/Tools/DumpRenderTree/gtk/EventSender.cpp b/Tools/DumpRenderTree/gtk/EventSender.cpp index 923a4ba..10e129c 100644 --- a/Tools/DumpRenderTree/gtk/EventSender.cpp +++ b/Tools/DumpRenderTree/gtk/EventSender.cpp @@ -240,33 +240,42 @@ static void updateClickCount(int button) clickCount++; } +static guint gdkModifierFromJSValue(JSContextRef context, const JSValueRef value) +{ + JSStringRef string = JSValueToStringCopy(context, value, 0); + guint gdkModifier = 0; + if (JSStringIsEqualToUTF8CString(string, "ctrlKey") + || JSStringIsEqualToUTF8CString(string, "addSelectionKey")) + gdkModifier = GDK_CONTROL_MASK; + else if (JSStringIsEqualToUTF8CString(string, "shiftKey") + || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey")) + gdkModifier = GDK_SHIFT_MASK; + else if (JSStringIsEqualToUTF8CString(string, "altKey")) + gdkModifier = GDK_MOD1_MASK; + + // Currently the metaKey as defined in WebCore/platform/gtk/MouseEventGtk.cpp + // is GDK_MOD2_MASK. This code must be kept in sync with that file. + else if (JSStringIsEqualToUTF8CString(string, "metaKey")) + gdkModifier = GDK_MOD2_MASK; + + JSStringRelease(string); + return gdkModifier; +} + static guint gdkModifersFromJSValue(JSContextRef context, const JSValueRef modifiers) { + // The value may either be a string with a single modifier or an array of modifiers. + if (JSValueIsString(context, modifiers)) + return gdkModifierFromJSValue(context, modifiers); + JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0); if (!modifiersArray) return 0; guint gdkModifiers = 0; int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, JSStringCreateWithUTF8CString("length"), 0), 0); - for (int i = 0; i < modifiersCount; ++i) { - JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); - JSStringRef string = JSValueToStringCopy(context, value, 0); - if (JSStringIsEqualToUTF8CString(string, "ctrlKey") - || JSStringIsEqualToUTF8CString(string, "addSelectionKey")) - gdkModifiers |= GDK_CONTROL_MASK; - else if (JSStringIsEqualToUTF8CString(string, "shiftKey") - || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey")) - gdkModifiers |= GDK_SHIFT_MASK; - else if (JSStringIsEqualToUTF8CString(string, "altKey")) - gdkModifiers |= GDK_MOD1_MASK; - - // Currently the metaKey as defined in WebCore/platform/gtk/MouseEventGtk.cpp - // is GDK_MOD2_MASK. This code must be kept in sync with that file. - else if (JSStringIsEqualToUTF8CString(string, "metaKey")) - gdkModifiers |= GDK_MOD2_MASK; - - JSStringRelease(string); - } + for (int i = 0; i < modifiersCount; ++i) + gdkModifiers |= gdkModifierFromJSValue(context, JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0)); return gdkModifiers; } diff --git a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index 1527811..56d75f7 100644 --- a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -3,7 +3,7 @@ * Copyright (C) 2007 Eric Seidel <eric@webkit.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2009 Jan Michael Alonzo <jmalonzo@gmail.com> - * Copyright (C) 2009 Collabora Ltd. + * Copyright (C) 2009,2011 Collabora Ltd. * Copyright (C) 2010 Joone Hur <joone@kldp.org> * * Redistribution and use in source and binary forms, with or without @@ -230,7 +230,6 @@ void LayoutTestController::setAcceptsEditing(bool acceptsEditing) void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) { -#ifdef HAVE_LIBSOUP_2_29_90 SoupSession* session = webkit_get_default_session(); SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR)); @@ -251,7 +250,6 @@ void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, policy, NULL); -#endif } void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) @@ -492,9 +490,9 @@ void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double c // See https://bugs.webkit.org/show_bug.cgi?id=39485. } -void LayoutTestController::setIconDatabaseEnabled(bool flag) +void LayoutTestController::setIconDatabaseEnabled(bool enabled) { - // FIXME: implement + DumpRenderTreeSupportGtk::setIconDatabaseEnabled(enabled); } void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) @@ -546,10 +544,42 @@ void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) g_free(cValue); } -bool LayoutTestController::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */) +bool LayoutTestController::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray) { - // FIXME: Implement - return false; + WebKitFindOptions findOptions = 0; + WebKitWebView* webView = webkit_web_frame_get_web_view(mainFrame); + ASSERT(webView); + + JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); + JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); + if (!JSValueIsNumber(context, lengthValue)) + return false; + + GOwnPtr<gchar> targetString(JSStringCopyUTF8CString(target)); + + size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); + for (size_t i = 0; i < length; ++i) { + JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); + if (!JSValueIsString(context, value)) + continue; + + JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0)); + + if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) + findOptions |= WebKit::WebFindOptionsCaseInsensitive; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) + findOptions |= WebKit::WebFindOptionsAtWordStarts; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) + findOptions |= WebKit::WebFindOptionsTreatMedialCapitalAsWordStart; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) + findOptions |= WebKit::WebFindOptionsBackwards; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) + findOptions |= WebKit::WebFindOptionsWrapAround; + else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) + findOptions |= WebKit::WebFindOptionsStartInSelection; + } + + return DumpRenderTreeSupportGtk::findString(webView, targetString.get(), findOptions); } bool LayoutTestController::isCommandEnabled(JSStringRef name) @@ -565,10 +595,20 @@ bool LayoutTestController::isCommandEnabled(JSStringRef name) void LayoutTestController::setCacheModel(int cacheModel) { - if (!cacheModel) // WebCacheModelDocumentViewer - webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); - else - webkit_set_cache_model(WEBKIT_CACHE_MODEL_WEB_BROWSER); + // These constants are derived from the Mac cache model enum in Source/WebKit/mac/WebView/WebPreferences.h. + switch (cacheModel) { + case 0: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); + break; + case 1: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); + break; + case 3: + webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER); + break; + default: + ASSERT_NOT_REACHED(); + } } void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) diff --git a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp index 32bc600..1e591bb 100644 --- a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp +++ b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp @@ -37,13 +37,14 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) { WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + GtkWidget* viewContainer = gtk_widget_get_parent(GTK_WIDGET(view)); gint width, height; #ifdef GTK_API_VERSION_2 - GdkPixmap* pixmap = gtk_widget_get_snapshot(GTK_WIDGET(view), 0); + GdkPixmap* pixmap = gtk_widget_get_snapshot(viewContainer, 0); gdk_pixmap_get_size(pixmap, &width, &height); #else - width = gtk_widget_get_allocated_width(GTK_WIDGET(view)); - height = gtk_widget_get_allocated_height(GTK_WIDGET(view)); + width = gtk_widget_get_allocated_width(viewContainer); + height = gtk_widget_get_allocated_height(viewContainer); #endif cairo_surface_t* imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); @@ -53,7 +54,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) cairo_paint(context); g_object_unref(pixmap); #else - gtk_widget_draw(GTK_WIDGET(view), context); + gtk_widget_draw(viewContainer, context); #endif return BitmapContext::createByAdoptingBitmapAndContext(0, context); diff --git a/Tools/DumpRenderTree/gtk/TextInputController.cpp b/Tools/DumpRenderTree/gtk/TextInputController.cpp new file mode 100644 index 0000000..7243fdc --- /dev/null +++ b/Tools/DumpRenderTree/gtk/TextInputController.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TextInputController.h" + +#include "DumpRenderTree.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" +#include <GOwnPtrGtk.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRef.h> +#include <cstring> + +static JSValueRef setMarkedTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 3) + return JSValueMakeUndefined(context); + + JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); + GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); + JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); + JSStringRelease(string); + + int start = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + int end = static_cast<int>(JSValueToNumber(context, arguments[2], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + DumpRenderTreeSupportGtk::setComposition(view, stringBuffer.get(), start, end); + + return JSValueMakeUndefined(context); +} + +static JSValueRef insertTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSStringRef string = JSValueToStringCopy(context, arguments[0], exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + size_t bufferSize = JSStringGetMaximumUTF8CStringSize(string); + GOwnPtr<gchar> stringBuffer(static_cast<gchar*>(g_malloc(bufferSize))); + JSStringGetUTF8CString(string, stringBuffer.get(), bufferSize); + JSStringRelease(string); + + DumpRenderTreeSupportGtk::confirmComposition(view, stringBuffer.get()); + + return JSValueMakeUndefined(context); +} + +static JSValueRef unmarkTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + DumpRenderTreeSupportGtk::confirmComposition(view, 0); + return JSValueMakeUndefined(context); +} + +static JSValueRef firstRectForCharacterRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + int location = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + int length = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + GdkRectangle rect; + if (!DumpRenderTreeSupportGtk::firstRectForCharacterRange(view, location, length, &rect)) + return JSValueMakeUndefined(context); + + JSValueRef arrayValues[4]; + arrayValues[0] = JSValueMakeNumber(context, rect.x); + arrayValues[1] = JSValueMakeNumber(context, rect.y); + arrayValues[2] = JSValueMakeNumber(context, rect.width); + arrayValues[3] = JSValueMakeNumber(context, rect.height); + JSObjectRef arrayObject = JSObjectMakeArray(context, 4, arrayValues, exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + return arrayObject; +} + +static JSValueRef selectedRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); + if (!view) + return JSValueMakeUndefined(context); + + int start, end; + if (!DumpRenderTreeSupportGtk::selectedRange(view, &start, &end)) + return JSValueMakeUndefined(context); + + JSValueRef arrayValues[2]; + arrayValues[0] = JSValueMakeNumber(context, start); + arrayValues[1] = JSValueMakeNumber(context, end); + JSObjectRef arrayObject = JSObjectMakeArray(context, 2, arrayValues, exception); + g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); + + return arrayObject; +} + +static JSStaticFunction staticFunctions[] = { + { "setMarkedText", setMarkedTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "insertText", insertTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "unmarkText", unmarkTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "firstRectForCharacterRange", firstRectForCharacterRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "selectedRange", selectedRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } +}; + +static JSClassRef getClass(JSContextRef context) +{ + static JSClassRef textInputControllerClass = 0; + + if (!textInputControllerClass) { + JSClassDefinition classDefinition = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + classDefinition.staticFunctions = staticFunctions; + + textInputControllerClass = JSClassCreate(&classDefinition); + } + + return textInputControllerClass; +} + +JSObjectRef makeTextInputController(JSContextRef context) +{ + return JSObjectMake(context, getClass(context), 0); +} diff --git a/Tools/DumpRenderTree/gtk/TextInputController.h b/Tools/DumpRenderTree/gtk/TextInputController.h new file mode 100644 index 0000000..53793f6 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/TextInputController.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TextInputController_h +#define TextInputController_h + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; + +JSObjectRef makeTextInputController(JSContextRef); + +#endif |