1/* 2 * Copyright (C) 2009 Martin Robinson 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2,1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20#include <errno.h> 21#include <unistd.h> 22#include <string.h> 23#include <glib/gstdio.h> 24#include <webkit/webkit.h> 25 26#if GTK_CHECK_VERSION(2, 14, 0) 27 28typedef struct { 29 char* page; 30 gboolean shouldBeHandled; 31} TestInfo; 32 33typedef struct { 34 GtkWidget* window; 35 WebKitWebView* webView; 36 GMainLoop* loop; 37 TestInfo* info; 38} KeyEventFixture; 39 40TestInfo* 41test_info_new(const char* page, gboolean shouldBeHandled) 42{ 43 TestInfo* info; 44 45 info = g_slice_new(TestInfo); 46 info->page = g_strdup(page); 47 info->shouldBeHandled = shouldBeHandled; 48 49 return info; 50} 51 52void 53test_info_destroy(TestInfo* info) 54{ 55 g_free(info->page); 56 g_slice_free(TestInfo, info); 57} 58 59static void key_event_fixture_setup(KeyEventFixture* fixture, gconstpointer data) 60{ 61 fixture->loop = g_main_loop_new(NULL, TRUE); 62 63 fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 64 fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 65 66 gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView)); 67} 68 69static void key_event_fixture_teardown(KeyEventFixture* fixture, gconstpointer data) 70{ 71 gtk_widget_destroy(fixture->window); 72 g_main_loop_unref(fixture->loop); 73 test_info_destroy(fixture->info); 74} 75 76static gboolean key_press_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data) 77{ 78 KeyEventFixture* fixture = (KeyEventFixture*)data; 79 gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key); 80 g_assert_cmpint(handled, ==, fixture->info->shouldBeHandled); 81 82 return FALSE; 83} 84 85 86static gboolean key_release_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data) 87{ 88 // WebCore never seems to mark keyup events as handled. 89 KeyEventFixture* fixture = (KeyEventFixture*)data; 90 gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key); 91 g_assert(!handled); 92 93 g_main_loop_quit(fixture->loop); 94 95 return FALSE; 96} 97 98static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data) 99{ 100 KeyEventFixture* fixture = (KeyEventFixture*)data; 101 WebKitLoadStatus status = webkit_web_view_get_load_status(webView); 102 if (status == WEBKIT_LOAD_FINISHED) { 103 gtk_test_widget_send_key(GTK_WIDGET(fixture->webView), 104 gdk_unicode_to_keyval('a'), 0); 105 } 106 107} 108 109gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data) 110{ 111 gtk_widget_grab_focus(widget); 112 KeyEventFixture* fixture = (KeyEventFixture*)data; 113 114 g_signal_connect(fixture->webView, "key-press-event", 115 G_CALLBACK(key_press_event_cb), fixture); 116 g_signal_connect(fixture->webView, "key-release-event", 117 G_CALLBACK(key_release_event_cb), fixture); 118 119 g_signal_connect(fixture->webView, "notify::load-status", 120 G_CALLBACK(load_status_cb), fixture); 121 122 webkit_web_view_load_string(fixture->webView, fixture->info->page, 123 "text/html", "utf-8", "file://"); 124 125 return FALSE; 126} 127 128static void test_keypress(KeyEventFixture* fixture, gconstpointer data) 129{ 130 fixture->info = (TestInfo*)data; 131 132 g_signal_connect(fixture->window, "map-event", 133 G_CALLBACK(map_event_cb), fixture); 134 135 gtk_widget_show(fixture->window); 136 gtk_widget_show(GTK_WIDGET(fixture->webView)); 137 gtk_window_present(GTK_WINDOW(fixture->window)); 138 139 g_main_loop_run(fixture->loop); 140 141} 142 143int main(int argc, char** argv) 144{ 145 g_thread_init(NULL); 146 gtk_test_init(&argc, &argv, NULL); 147 148 g_test_bug_base("https://bugs.webkit.org/"); 149 150 g_test_add("/webkit/keyevent/textfield", KeyEventFixture, 151 test_info_new("<html><body><input id=\"in\" type=\"text\">" 152 "<script>document.getElementById('in').focus();" 153 "</script></body></html>", TRUE), 154 key_event_fixture_setup, 155 test_keypress, 156 key_event_fixture_teardown); 157 158 g_test_add("/webkit/keyevent/buttons", KeyEventFixture, 159 test_info_new("<html><body><input id=\"in\" type=\"button\">" 160 "<script>document.getElementById('in').focus();" 161 "</script></body></html>", FALSE), 162 key_event_fixture_setup, 163 test_keypress, 164 key_event_fixture_teardown); 165 166 g_test_add("/webkit/keyevent/link", KeyEventFixture, 167 test_info_new("<html><body><a href=\"http://www.gnome.org\" id=\"in\">" 168 "LINKY MCLINKERSON</a><script>" 169 "document.getElementById('in').focus();</script>" 170 "</body></html>", FALSE), 171 key_event_fixture_setup, 172 test_keypress, 173 key_event_fixture_teardown); 174 175 return g_test_run(); 176} 177 178#else 179 180int main(int argc, char** argv) 181{ 182 g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); 183 return 0; 184} 185 186#endif 187