1 /* 2 * Copyright (C) 2009 Igalia S.L. 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 <glib/gstdio.h> 23 #include <webkit/webkit.h> 24 25 #if GTK_CHECK_VERSION(2, 14, 0) 26 27 typedef struct { 28 char* data; 29 guint flag; 30 } TestInfo; 31 32 static GMainLoop* loop; 33 34 typedef struct { 35 WebKitWebView* webView; 36 TestInfo* info; 37 } HitTestResultFixture; 38 39 TestInfo* 40 test_info_new(const char* data, guint flag) 41 { 42 TestInfo* info; 43 44 info = g_slice_new(TestInfo); 45 info->data = g_strdup(data); 46 info->flag = flag; 47 48 return info; 49 } 50 51 void 52 test_info_destroy(TestInfo* info) 53 { 54 g_free(info->data); 55 g_slice_free(TestInfo, info); 56 } 57 58 static void hit_test_result_fixture_setup(HitTestResultFixture* fixture, gconstpointer data) 59 { 60 fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 61 g_object_ref_sink(fixture->webView); 62 loop = g_main_loop_new(NULL, TRUE); 63 fixture->info = (TestInfo*)data; 64 } 65 66 static void hit_test_result_fixture_teardown(HitTestResultFixture* fixture, gconstpointer data) 67 { 68 g_object_unref(fixture->webView); 69 g_main_loop_unref(loop); 70 test_info_destroy(fixture->info); 71 } 72 73 static void 74 load_status_cb(WebKitWebView* webView, 75 GParamSpec* spec, 76 gpointer data) 77 { 78 WebKitLoadStatus status = webkit_web_view_get_load_status(webView); 79 TestInfo* info = (TestInfo*)data; 80 81 if (status == WEBKIT_LOAD_FINISHED) { 82 WebKitHitTestResult* result; 83 guint context; 84 GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS); 85 WebKitDOMNode* node; 86 87 /* Close enough to 0,0 */ 88 event->button.x = 5; 89 event->button.y = 5; 90 91 result = webkit_web_view_get_hit_test_result(webView, (GdkEventButton*) event); 92 gdk_event_free(event); 93 g_assert(result); 94 95 g_object_get(result, "context", &context, NULL); 96 g_assert(context & info->flag); 97 98 g_object_get(result, "inner-node", &node, NULL); 99 g_assert(node); 100 g_assert(WEBKIT_DOM_IS_NODE(node)); 101 /* We can only test these node types at the moment. In the 102 * input case there seems to be an extra layer with a DIV on 103 * top of the input, which gets assigned to the inner-node. 104 * tag */ 105 if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT) 106 g_assert(WEBKIT_DOM_IS_HTML_HTML_ELEMENT(node)); 107 else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) 108 g_assert(WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT(node)); 109 else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) { 110 /* The hit test will give us the inner text node, we want 111 * the A tag */ 112 WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node); 113 g_assert(WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT(parent)); 114 } 115 116 g_object_unref(result); 117 g_main_loop_quit(loop); 118 } 119 } 120 121 static void 122 test_webkit_hit_test_result(HitTestResultFixture* fixture, gconstpointer data) 123 { 124 TestInfo* info = (TestInfo*)data; 125 GtkAllocation allocation = { 0, 0, 50, 50 }; 126 127 webkit_web_view_load_string(fixture->webView, 128 info->data, 129 "text/html", 130 "utf-8", 131 "file://"); 132 gtk_widget_size_allocate(GTK_WIDGET(fixture->webView), &allocation); 133 g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_cb), info); 134 g_main_loop_run(loop); 135 } 136 137 int main(int argc, char** argv) 138 { 139 g_thread_init(NULL); 140 gtk_test_init(&argc, &argv, NULL); 141 142 g_test_bug_base("https://bugs.webkit.org/"); 143 144 g_test_add("/webkit/hittestresult/document", HitTestResultFixture, 145 test_info_new("<html><body><h1>WebKitGTK+!</h1></body></html>", 146 WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT), 147 hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); 148 /* We hardcode all elements to be at 0,0 so that we know where to 149 * generate the button events */ 150 g_test_add("/webkit/hittestresult/image", HitTestResultFixture, 151 test_info_new("<html><body><img style='position:absolute; left:0; top:0'src='0xdeadbeef' width=50 height=50></img></body></html>", 152 WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE), 153 hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); 154 g_test_add("/webkit/hittestresult/editable", HitTestResultFixture, 155 test_info_new("<html><body><input style='position:absolute; left:0; top:0' size='35'></input>></body></html>", 156 WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE), 157 hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); 158 g_test_add("/webkit/hittestresult/link", HitTestResultFixture, 159 test_info_new("<html><body><a style='position:absolute; left:0; top:0' href='http://www.example.com'>HELLO WORLD</a></body></html>", 160 WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK), 161 hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown); 162 163 return g_test_run (); 164 } 165 166 #else 167 168 int main(int argc, char** argv) 169 { 170 g_critical("You will need at least GTK+ 2.14.0 to run the unit tests."); 171 return 0; 172 } 173 174 #endif 175