summaryrefslogtreecommitdiffstats
path: root/Tools/DumpRenderTree/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/DumpRenderTree/gtk')
-rw-r--r--Tools/DumpRenderTree/gtk/AccessibilityCallbacks.cpp196
-rw-r--r--Tools/DumpRenderTree/gtk/AccessibilityCallbacks.h35
-rw-r--r--Tools/DumpRenderTree/gtk/AccessibilityControllerGtk.cpp18
-rw-r--r--Tools/DumpRenderTree/gtk/DumpRenderTree.cpp19
-rw-r--r--Tools/DumpRenderTree/gtk/EventSender.cpp47
-rw-r--r--Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp64
-rw-r--r--Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp9
-rw-r--r--Tools/DumpRenderTree/gtk/TextInputController.cpp177
-rw-r--r--Tools/DumpRenderTree/gtk/TextInputController.h37
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(&paramValues[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(&paramValues[1]),
+ g_value_get_boolean(&paramValues[2])));
+ } else if (!g_strcmp0(signal_query.signal_name, "focus-event")) {
+ signalName.set(g_strdup_printf("focus-event = %d",
+ g_value_get_boolean(&paramValues[1])));
+ } else if (!g_strcmp0(signal_query.signal_name, "children-changed")) {
+ signalName.set(g_strdup_printf("children-changed = %d",
+ g_value_get_uint(&paramValues[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(&paramValues[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