|
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 Library General Public |
|
6 * License as published by the Free Software Foundation; either |
|
7 * version 2 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.h> |
|
23 #include <glib/gstdio.h> |
|
24 #include <gtk/gtk.h> |
|
25 #include <webkit/webkit.h> |
|
26 |
|
27 #if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0) |
|
28 |
|
29 static const char* contents = "<html><body><p>This is a test. This is the second sentence. And this the third.</p></body></html>"; |
|
30 |
|
31 static const char* contentsWithNewlines = "<html><body><p>This is a test. \n\nThis\n is the second sentence. And this the third.</p></body></html>"; |
|
32 |
|
33 static const char* contentsInTextarea = "<html><body><textarea cols='80'>This is a test. This is the second sentence. And this the third.</textarea></body></html>"; |
|
34 |
|
35 static const char* contentsInTextInput = "<html><body><input type='text' size='80' value='This is a test. This is the second sentence. And this the third.'/></body></html>"; |
|
36 |
|
37 static const char* contentsInParagraphAndBodySimple = "<html><body><p>This is a test.</p>Hello world.</body></html>"; |
|
38 |
|
39 static const char* contentsInParagraphAndBodyModerate = "<html><body><p>This is a test.</p>Hello world.<br /><font color='#00cc00'>This sentence is green.</font><br />This one is not.</body></html>"; |
|
40 |
|
41 static const char* contentsInTable = "<html><body><table><tr><td>foo</td><td>bar</td></tr></table></body></html>"; |
|
42 |
|
43 static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo</th><th>bar</th><th colspan='2'>baz</th></tr><tr><th>qux</th><td>1</td><td>2</td><td>3</td></tr><tr><th rowspan='2'>quux</th><td>4</td><td>5</td><td>6</td></tr><tr><td>6</td><td>7</td><td>8</td></tr><tr><th>corge</th><td>9</td><td>10</td><td>11</td></tr></table><table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table></body></html>"; |
|
44 |
|
45 static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; |
|
46 |
|
47 static gboolean bail_out(GMainLoop* loop) |
|
48 { |
|
49 if (g_main_loop_is_running(loop)) |
|
50 g_main_loop_quit(loop); |
|
51 |
|
52 return FALSE; |
|
53 } |
|
54 |
|
55 typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*); |
|
56 |
|
57 static void test_get_text_function(AtkText* text_obj, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* text_result, gint start_offset_result, gint end_offset_result) |
|
58 { |
|
59 gint start_offset, end_offset; |
|
60 char* text; |
|
61 |
|
62 text = fn(text_obj, offset, boundary, &start_offset, &end_offset); |
|
63 g_assert_cmpstr(text, ==, text_result); |
|
64 g_assert_cmpint(start_offset, ==, start_offset_result); |
|
65 g_assert_cmpint(end_offset, ==, end_offset_result); |
|
66 g_free(text); |
|
67 } |
|
68 |
|
69 static void run_get_text_tests(AtkText* text_obj) |
|
70 { |
|
71 char* text = atk_text_get_text(text_obj, 0, -1); |
|
72 g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third."); |
|
73 g_free(text); |
|
74 |
|
75 /* ATK_TEXT_BOUNDARY_CHAR */ |
|
76 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR, |
|
77 0, "T", 0, 1); |
|
78 |
|
79 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR, |
|
80 0, "h", 1, 2); |
|
81 |
|
82 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, |
|
83 0, "", 0, 0); |
|
84 |
|
85 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR, |
|
86 1, "T", 0, 1); |
|
87 |
|
88 /* ATK_TEXT_BOUNDARY_WORD_START */ |
|
89 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
90 0, "This ", 0, 5); |
|
91 |
|
92 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
93 4, "This ", 0, 5); |
|
94 |
|
95 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
96 10, "test. ", 10, 16); |
|
97 |
|
98 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
99 58, "third.", 58, 64); |
|
100 |
|
101 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
102 5, "This ", 0, 5); |
|
103 |
|
104 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
105 7, "This ", 0, 5); |
|
106 |
|
107 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
108 0, "is ", 5, 8); |
|
109 |
|
110 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
111 4, "is ", 5, 8); |
|
112 |
|
113 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START, |
|
114 3, "is ", 5, 8); |
|
115 |
|
116 /* ATK_TEXT_BOUNDARY_WORD_END */ |
|
117 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
118 0, "This", 0, 4); |
|
119 |
|
120 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
121 4, " is", 4, 7); |
|
122 |
|
123 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
124 5, " is", 4, 7); |
|
125 |
|
126 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
127 9, " test", 9, 14); |
|
128 |
|
129 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
130 5, "This", 0, 4); |
|
131 |
|
132 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
133 4, "This", 0, 4); |
|
134 |
|
135 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
136 7, " is", 4, 7); |
|
137 |
|
138 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
139 5, " a", 7, 9); |
|
140 |
|
141 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
142 4, " a", 7, 9); |
|
143 |
|
144 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END, |
|
145 58, " third", 57, 63); |
|
146 |
|
147 /* ATK_TEXT_BOUNDARY_SENTENCE_START */ |
|
148 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
149 0, "This is a test. ", 0, 16); |
|
150 |
|
151 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
152 15, "This is a test. ", 0, 16); |
|
153 |
|
154 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
155 0, "This is the second sentence. ", 16, 45); |
|
156 |
|
157 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
158 15, "This is the second sentence. ", 16, 45); |
|
159 |
|
160 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
161 16, "This is a test. ", 0, 16); |
|
162 |
|
163 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
164 44, "This is a test. ", 0, 16); |
|
165 |
|
166 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START, |
|
167 15, "", 0, 0); |
|
168 |
|
169 /* ATK_TEXT_BOUNDARY_SENTENCE_END */ |
|
170 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
171 0, "This is a test.", 0, 15); |
|
172 |
|
173 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
174 15, " This is the second sentence.", 15, 44); |
|
175 |
|
176 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
177 16, " This is the second sentence.", 15, 44); |
|
178 |
|
179 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
180 17, " This is the second sentence.", 15, 44); |
|
181 |
|
182 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
183 0, " This is the second sentence.", 15, 44); |
|
184 |
|
185 test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
186 15, " And this the third.", 44, 64); |
|
187 |
|
188 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
189 16, "This is a test.", 0, 15); |
|
190 |
|
191 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
192 15, "This is a test.", 0, 15); |
|
193 |
|
194 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
195 14, "", 0, 0); |
|
196 |
|
197 test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END, |
|
198 44, " This is the second sentence.", 15, 44); |
|
199 |
|
200 /* It's trick to test these properly right now, since our a11y |
|
201 implementation splits different lines in different a11y |
|
202 items */ |
|
203 /* ATK_TEXT_BOUNDARY_LINE_START */ |
|
204 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START, |
|
205 0, "This is a test. This is the second sentence. And this the third.", 0, 64); |
|
206 |
|
207 /* ATK_TEXT_BOUNDARY_LINE_END */ |
|
208 test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END, |
|
209 0, "This is a test. This is the second sentence. And this the third.", 0, 64); |
|
210 } |
|
211 |
|
212 static void test_webkit_atk_get_text_at_offset_forms(void) |
|
213 { |
|
214 WebKitWebView* webView; |
|
215 AtkObject* obj; |
|
216 GMainLoop* loop; |
|
217 AtkText* text_obj; |
|
218 |
|
219 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
220 g_object_ref_sink(webView); |
|
221 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
222 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
223 webkit_web_view_load_string(webView, contents, NULL, NULL, NULL); |
|
224 loop = g_main_loop_new(NULL, TRUE); |
|
225 |
|
226 g_idle_add((GSourceFunc)bail_out, loop); |
|
227 g_main_loop_run(loop); |
|
228 |
|
229 /* Get to the inner AtkText object */ |
|
230 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
231 g_assert(obj); |
|
232 obj = atk_object_ref_accessible_child(obj, 0); |
|
233 g_assert(obj); |
|
234 |
|
235 text_obj = ATK_TEXT(obj); |
|
236 g_assert(ATK_IS_TEXT(text_obj)); |
|
237 |
|
238 run_get_text_tests(text_obj); |
|
239 |
|
240 g_object_unref(webView); |
|
241 } |
|
242 |
|
243 static void test_webkit_atk_get_text_at_offset(void) |
|
244 { |
|
245 WebKitWebView* webView; |
|
246 AtkObject* obj; |
|
247 GMainLoop* loop; |
|
248 AtkText* text_obj; |
|
249 |
|
250 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
251 g_object_ref_sink(webView); |
|
252 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
253 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
254 webkit_web_view_load_string(webView, contents, NULL, NULL, NULL); |
|
255 loop = g_main_loop_new(NULL, TRUE); |
|
256 |
|
257 g_idle_add((GSourceFunc)bail_out, loop); |
|
258 g_main_loop_run(loop); |
|
259 |
|
260 /* Get to the inner AtkText object */ |
|
261 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
262 g_assert(obj); |
|
263 obj = atk_object_ref_accessible_child(obj, 0); |
|
264 g_assert(obj); |
|
265 |
|
266 text_obj = ATK_TEXT(obj); |
|
267 g_assert(ATK_IS_TEXT(text_obj)); |
|
268 |
|
269 run_get_text_tests(text_obj); |
|
270 |
|
271 g_object_unref(webView); |
|
272 } |
|
273 |
|
274 static void test_webkit_atk_get_text_at_offset_newlines(void) |
|
275 { |
|
276 WebKitWebView* webView; |
|
277 AtkObject* obj; |
|
278 GMainLoop* loop; |
|
279 AtkText* text_obj; |
|
280 |
|
281 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
282 g_object_ref_sink(webView); |
|
283 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
284 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
285 webkit_web_view_load_string(webView, contentsWithNewlines, NULL, NULL, NULL); |
|
286 loop = g_main_loop_new(NULL, TRUE); |
|
287 |
|
288 g_idle_add((GSourceFunc)bail_out, loop); |
|
289 g_main_loop_run(loop); |
|
290 |
|
291 /* Get to the inner AtkText object */ |
|
292 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
293 g_assert(obj); |
|
294 obj = atk_object_ref_accessible_child(obj, 0); |
|
295 g_assert(obj); |
|
296 |
|
297 text_obj = ATK_TEXT(obj); |
|
298 g_assert(ATK_IS_TEXT(text_obj)); |
|
299 |
|
300 run_get_text_tests(text_obj); |
|
301 |
|
302 g_object_unref(webView); |
|
303 } |
|
304 |
|
305 static void test_webkit_atk_get_text_at_offset_textarea(void) |
|
306 { |
|
307 WebKitWebView* webView; |
|
308 AtkObject* obj; |
|
309 GMainLoop* loop; |
|
310 AtkText* text_obj; |
|
311 |
|
312 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
313 g_object_ref_sink(webView); |
|
314 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
315 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
316 webkit_web_view_load_string(webView, contentsInTextarea, NULL, NULL, NULL); |
|
317 loop = g_main_loop_new(NULL, TRUE); |
|
318 |
|
319 g_idle_add((GSourceFunc)bail_out, loop); |
|
320 g_main_loop_run(loop); |
|
321 |
|
322 /* Get to the inner AtkText object */ |
|
323 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
324 g_assert(obj); |
|
325 obj = atk_object_ref_accessible_child(obj, 0); |
|
326 g_assert(obj); |
|
327 obj = atk_object_ref_accessible_child(obj, 0); |
|
328 g_assert(obj); |
|
329 |
|
330 text_obj = ATK_TEXT(obj); |
|
331 g_assert(ATK_IS_TEXT(text_obj)); |
|
332 |
|
333 run_get_text_tests(text_obj); |
|
334 |
|
335 g_object_unref(webView); |
|
336 } |
|
337 |
|
338 static void test_webkit_atk_get_text_at_offset_text_input(void) |
|
339 { |
|
340 WebKitWebView* webView; |
|
341 AtkObject* obj; |
|
342 GMainLoop* loop; |
|
343 AtkText* text_obj; |
|
344 |
|
345 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
346 g_object_ref_sink(webView); |
|
347 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
348 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
349 webkit_web_view_load_string(webView, contentsInTextInput, NULL, NULL, NULL); |
|
350 loop = g_main_loop_new(NULL, TRUE); |
|
351 |
|
352 g_idle_add((GSourceFunc)bail_out, loop); |
|
353 g_main_loop_run(loop); |
|
354 |
|
355 /* Get to the inner AtkText object */ |
|
356 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
357 g_assert(obj); |
|
358 obj = atk_object_ref_accessible_child(obj, 0); |
|
359 g_assert(obj); |
|
360 obj = atk_object_ref_accessible_child(obj, 0); |
|
361 g_assert(obj); |
|
362 |
|
363 text_obj = ATK_TEXT(obj); |
|
364 g_assert(ATK_IS_TEXT(text_obj)); |
|
365 |
|
366 run_get_text_tests(text_obj); |
|
367 |
|
368 g_object_unref(webView); |
|
369 } |
|
370 |
|
371 static void testWebkitAtkGetTextInParagraphAndBodySimple(void) |
|
372 { |
|
373 WebKitWebView* webView; |
|
374 AtkObject* obj; |
|
375 AtkObject* obj1; |
|
376 AtkObject* obj2; |
|
377 GMainLoop* loop; |
|
378 AtkText* textObj1; |
|
379 AtkText* textObj2; |
|
380 |
|
381 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
382 g_object_ref_sink(webView); |
|
383 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
384 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
385 webkit_web_view_load_string(webView, contentsInParagraphAndBodySimple, NULL, NULL, NULL); |
|
386 loop = g_main_loop_new(NULL, TRUE); |
|
387 |
|
388 g_idle_add((GSourceFunc)bail_out, loop); |
|
389 g_main_loop_run(loop); |
|
390 |
|
391 /* Get to the inner AtkText object */ |
|
392 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
393 g_assert(obj); |
|
394 obj1 = atk_object_ref_accessible_child(obj, 0); |
|
395 g_assert(obj1); |
|
396 obj2 = atk_object_ref_accessible_child(obj, 1); |
|
397 g_assert(obj2); |
|
398 |
|
399 textObj1 = ATK_TEXT(obj1); |
|
400 g_assert(ATK_IS_TEXT(textObj1)); |
|
401 textObj2 = ATK_TEXT(obj2); |
|
402 g_assert(ATK_IS_TEXT(textObj2)); |
|
403 |
|
404 char *text = atk_text_get_text(textObj1, 0, -1); |
|
405 g_assert_cmpstr(text, ==, "This is a test."); |
|
406 |
|
407 text = atk_text_get_text(textObj2, 0, 12); |
|
408 g_assert_cmpstr(text, ==, "Hello world."); |
|
409 |
|
410 g_object_unref(obj1); |
|
411 g_object_unref(obj2); |
|
412 g_object_unref(webView); |
|
413 } |
|
414 |
|
415 static void testWebkitAtkGetTextInParagraphAndBodyModerate(void) |
|
416 { |
|
417 WebKitWebView* webView; |
|
418 AtkObject* obj; |
|
419 AtkObject* obj1; |
|
420 AtkObject* obj2; |
|
421 GMainLoop* loop; |
|
422 AtkText* textObj1; |
|
423 AtkText* textObj2; |
|
424 |
|
425 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
426 g_object_ref_sink(webView); |
|
427 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
428 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
429 webkit_web_view_load_string(webView, contentsInParagraphAndBodyModerate, NULL, NULL, NULL); |
|
430 loop = g_main_loop_new(NULL, TRUE); |
|
431 |
|
432 g_idle_add((GSourceFunc)bail_out, loop); |
|
433 g_main_loop_run(loop); |
|
434 |
|
435 /* Get to the inner AtkText object */ |
|
436 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
437 g_assert(obj); |
|
438 obj1 = atk_object_ref_accessible_child(obj, 0); |
|
439 g_assert(obj1); |
|
440 obj2 = atk_object_ref_accessible_child(obj, 1); |
|
441 g_assert(obj2); |
|
442 |
|
443 textObj1 = ATK_TEXT(obj1); |
|
444 g_assert(ATK_IS_TEXT(textObj1)); |
|
445 textObj2 = ATK_TEXT(obj2); |
|
446 g_assert(ATK_IS_TEXT(textObj2)); |
|
447 |
|
448 char *text = atk_text_get_text(textObj1, 0, -1); |
|
449 g_assert_cmpstr(text, ==, "This is a test."); |
|
450 |
|
451 text = atk_text_get_text(textObj2, 0, 53); |
|
452 g_assert_cmpstr(text, ==, "Hello world.\nThis sentence is green.\nThis one is not."); |
|
453 |
|
454 g_object_unref(obj1); |
|
455 g_object_unref(obj2); |
|
456 g_object_unref(webView); |
|
457 } |
|
458 |
|
459 static void testWebkitAtkGetTextInTable(void) |
|
460 { |
|
461 WebKitWebView* webView; |
|
462 AtkObject* obj; |
|
463 GMainLoop* loop; |
|
464 |
|
465 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
466 g_object_ref_sink(webView); |
|
467 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
468 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
469 webkit_web_view_load_string(webView, contentsInTable, NULL, NULL, NULL); |
|
470 loop = g_main_loop_new(NULL, TRUE); |
|
471 |
|
472 g_idle_add((GSourceFunc)bail_out, loop); |
|
473 g_main_loop_run(loop); |
|
474 |
|
475 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
476 g_assert(obj); |
|
477 obj = atk_object_ref_accessible_child(obj, 0); |
|
478 g_assert(obj); |
|
479 |
|
480 /* Tables should not implement AtkText */ |
|
481 g_assert(G_TYPE_INSTANCE_GET_INTERFACE(obj, ATK_TYPE_TEXT, AtkTextIface) == NULL); |
|
482 |
|
483 g_object_unref(obj); |
|
484 g_object_unref(webView); |
|
485 } |
|
486 |
|
487 static void testWebkitAtkGetHeadersInTable(void) |
|
488 { |
|
489 WebKitWebView* webView; |
|
490 AtkObject* axWebView; |
|
491 AtkObject* table; |
|
492 AtkObject* colHeader; |
|
493 AtkObject* rowHeader; |
|
494 GMainLoop* loop; |
|
495 |
|
496 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
497 g_object_ref_sink(webView); |
|
498 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
499 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
500 webkit_web_view_load_string(webView, contentsInTableWithHeaders, NULL, NULL, NULL); |
|
501 loop = g_main_loop_new(NULL, TRUE); |
|
502 |
|
503 g_idle_add((GSourceFunc)bail_out, loop); |
|
504 g_main_loop_run(loop); |
|
505 |
|
506 axWebView = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
507 g_assert(axWebView); |
|
508 |
|
509 // Check table with both column and row headers |
|
510 table = atk_object_ref_accessible_child(axWebView, 0); |
|
511 g_assert(table); |
|
512 g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); |
|
513 |
|
514 colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); |
|
515 g_assert(colHeader); |
|
516 g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); |
|
517 g_assert(atk_object_get_index_in_parent(colHeader) == 0); |
|
518 |
|
519 colHeader = atk_table_get_column_header(ATK_TABLE(table), 1); |
|
520 g_assert(colHeader); |
|
521 g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); |
|
522 g_assert(atk_object_get_index_in_parent(colHeader) == 1); |
|
523 |
|
524 colHeader = atk_table_get_column_header(ATK_TABLE(table), 2); |
|
525 g_assert(colHeader); |
|
526 g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); |
|
527 g_assert(atk_object_get_index_in_parent(colHeader) == 2); |
|
528 |
|
529 colHeader = atk_table_get_column_header(ATK_TABLE(table), 3); |
|
530 g_assert(colHeader); |
|
531 g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL); |
|
532 g_assert(atk_object_get_index_in_parent(colHeader) == 2); |
|
533 |
|
534 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); |
|
535 g_assert(rowHeader); |
|
536 g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); |
|
537 g_assert(atk_object_get_index_in_parent(rowHeader) == 0); |
|
538 |
|
539 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1); |
|
540 g_assert(rowHeader); |
|
541 g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); |
|
542 g_assert(atk_object_get_index_in_parent(rowHeader) == 3); |
|
543 |
|
544 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 2); |
|
545 g_assert(rowHeader); |
|
546 g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); |
|
547 g_assert(atk_object_get_index_in_parent(rowHeader) == 7); |
|
548 |
|
549 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 3); |
|
550 g_assert(rowHeader); |
|
551 g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL); |
|
552 g_assert(atk_object_get_index_in_parent(rowHeader) == 7); |
|
553 |
|
554 g_object_unref(table); |
|
555 |
|
556 // Check table with no headers at all |
|
557 table = atk_object_ref_accessible_child(axWebView, 1); |
|
558 g_assert(table); |
|
559 g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE); |
|
560 |
|
561 colHeader = atk_table_get_column_header(ATK_TABLE(table), 0); |
|
562 g_assert(colHeader == 0); |
|
563 |
|
564 colHeader = atk_table_get_column_header(ATK_TABLE(table), 1); |
|
565 g_assert(colHeader == 0); |
|
566 |
|
567 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0); |
|
568 g_assert(rowHeader == 0); |
|
569 |
|
570 rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1); |
|
571 g_assert(rowHeader == 0); |
|
572 |
|
573 g_object_unref(table); |
|
574 g_object_unref(webView); |
|
575 } |
|
576 |
|
577 static gint compAtkAttribute(AtkAttribute* a1, AtkAttribute* a2) |
|
578 { |
|
579 gint strcmpVal; |
|
580 strcmpVal = g_strcmp0(a1->name, a2->name); |
|
581 if (strcmpVal) |
|
582 return strcmpVal; |
|
583 return g_strcmp0(a1->value, a2->value); |
|
584 } |
|
585 |
|
586 static gint compAtkAttributeName(AtkAttribute* a1, AtkAttribute* a2) |
|
587 { |
|
588 return g_strcmp0(a1->name, a2->name); |
|
589 } |
|
590 |
|
591 static gboolean atkAttributeSetAttributeHasValue(AtkAttributeSet* set, AtkTextAttribute attribute, const gchar* value) |
|
592 { |
|
593 GSList *element; |
|
594 AtkAttribute at; |
|
595 gboolean result; |
|
596 at.name = (gchar *)atk_text_attribute_get_name(attribute); |
|
597 element = g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName); |
|
598 result = element && !g_strcmp0(((AtkAttribute*)(element->data))->value, value); |
|
599 return result; |
|
600 } |
|
601 |
|
602 static gboolean atkAttributeSetAreEqual(AtkAttributeSet* set1, AtkAttributeSet* set2) |
|
603 { |
|
604 if (!set1) |
|
605 return !set2; |
|
606 |
|
607 set1 = g_slist_sort(set1, (GCompareFunc)compAtkAttribute); |
|
608 set2 = g_slist_sort(set2, (GCompareFunc)compAtkAttribute); |
|
609 |
|
610 while (set1) { |
|
611 if (!set2 || compAtkAttribute(set1->data, set2->data)) |
|
612 return FALSE; |
|
613 |
|
614 set1 = set1->next; |
|
615 set2 = set2->next; |
|
616 } |
|
617 |
|
618 return (!set2); |
|
619 } |
|
620 |
|
621 static void testWebkitAtkTextAttributes(void) |
|
622 { |
|
623 WebKitWebView* webView; |
|
624 AtkObject* obj; |
|
625 AtkObject* child; |
|
626 GMainLoop* loop; |
|
627 AtkText* childText; |
|
628 AtkAttributeSet* set1; |
|
629 AtkAttributeSet* set2; |
|
630 AtkAttributeSet* set3; |
|
631 AtkAttributeSet* set4; |
|
632 gint startOffset, endOffset; |
|
633 |
|
634 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); |
|
635 g_object_ref_sink(webView); |
|
636 GtkAllocation alloc = { 0, 0, 800, 600 }; |
|
637 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); |
|
638 |
|
639 webkit_web_view_load_string(webView, textWithAttributes, NULL, NULL, NULL); |
|
640 loop = g_main_loop_new(NULL, TRUE); |
|
641 |
|
642 g_idle_add((GSourceFunc)bail_out, loop); |
|
643 g_main_loop_run(loop); |
|
644 |
|
645 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); |
|
646 g_assert(obj); |
|
647 |
|
648 child = atk_object_ref_accessible_child(obj, 0); |
|
649 g_assert(child && ATK_IS_TEXT(child)); |
|
650 childText = ATK_TEXT(child); |
|
651 set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); |
|
652 g_assert_cmpint(startOffset, ==, 0); |
|
653 g_assert_cmpint(endOffset, ==, 12); |
|
654 g_assert(atkAttributeSetAreEqual(set1, NULL)); |
|
655 |
|
656 set2 = atk_text_get_run_attributes(childText, 15, &startOffset, &endOffset); |
|
657 g_assert_cmpint(startOffset, ==, 12); |
|
658 g_assert_cmpint(endOffset, ==, 17); |
|
659 g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_STYLE, "italic")); |
|
660 |
|
661 set3 = atk_text_get_run_attributes(childText, 17, &startOffset, &endOffset); |
|
662 g_assert_cmpint(startOffset, ==, 17); |
|
663 g_assert_cmpint(endOffset, ==, 40); |
|
664 g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_WEIGHT, "700")); |
|
665 |
|
666 set4 = atk_text_get_default_attributes(childText); |
|
667 g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_STYLE, "normal")); |
|
668 g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_JUSTIFICATION, "right")); |
|
669 g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_SIZE, "14")); |
|
670 atk_attribute_set_free(set1); |
|
671 atk_attribute_set_free(set2); |
|
672 atk_attribute_set_free(set3); |
|
673 atk_attribute_set_free(set4); |
|
674 |
|
675 child = atk_object_ref_accessible_child(obj, 1); |
|
676 g_assert(child && ATK_IS_TEXT(child)); |
|
677 childText = ATK_TEXT(child); |
|
678 |
|
679 set1 = atk_text_get_default_attributes(childText); |
|
680 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FAMILY_NAME, "monospace")); |
|
681 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STYLE, "normal")); |
|
682 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "false")); |
|
683 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_WEIGHT, "400")); |
|
684 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FG_COLOR, "120,121,122")); |
|
685 |
|
686 set2 = atk_text_get_run_attributes(childText, 43, &startOffset, &endOffset); |
|
687 g_assert_cmpint(startOffset, ==, 43); |
|
688 g_assert_cmpint(endOffset, ==, 80); |
|
689 // Checks that default attributes of text are not returned when called to atk_text_get_run_attributes |
|
690 g_assert(!atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_FG_COLOR, "120,121,122")); |
|
691 g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_UNDERLINE, "single")); |
|
692 g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_BG_COLOR, "80,81,82")); |
|
693 atk_attribute_set_free(set1); |
|
694 atk_attribute_set_free(set2); |
|
695 |
|
696 child = atk_object_ref_accessible_child(obj, 2); |
|
697 g_assert(child && ATK_IS_TEXT(child)); |
|
698 childText = ATK_TEXT(child); |
|
699 |
|
700 set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset); |
|
701 set2 = atk_text_get_run_attributes(childText, 3, &startOffset, &endOffset); |
|
702 g_assert(atkAttributeSetAreEqual(set1, set2)); |
|
703 atk_attribute_set_free(set2); |
|
704 |
|
705 set2 = atk_text_get_run_attributes(childText, 1, &startOffset, &endOffset); |
|
706 set3 = atk_text_get_run_attributes(childText, 5, &startOffset, &endOffset); |
|
707 g_assert(atkAttributeSetAreEqual(set2, set3)); |
|
708 g_assert(!atkAttributeSetAreEqual(set1, set2)); |
|
709 atk_attribute_set_free(set3); |
|
710 |
|
711 set3 = atk_text_get_run_attributes(childText, 2, &startOffset, &endOffset); |
|
712 set4 = atk_text_get_run_attributes(childText, 6, &startOffset, &endOffset); |
|
713 g_assert(atkAttributeSetAreEqual(set3, set4)); |
|
714 g_assert(!atkAttributeSetAreEqual(set1, set3)); |
|
715 g_assert(!atkAttributeSetAreEqual(set2, set3)); |
|
716 atk_attribute_set_free(set1); |
|
717 atk_attribute_set_free(set2); |
|
718 atk_attribute_set_free(set3); |
|
719 atk_attribute_set_free(set4); |
|
720 |
|
721 child = atk_object_ref_accessible_child(obj, 3); |
|
722 g_assert(child && ATK_IS_TEXT(child)); |
|
723 childText = ATK_TEXT(child); |
|
724 set1 = atk_text_get_run_attributes(childText, 24, &startOffset, &endOffset); |
|
725 g_assert_cmpint(startOffset, ==, 21); |
|
726 g_assert_cmpint(endOffset, ==, 25); |
|
727 g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "true")); |
|
728 |
|
729 set2 = atk_text_get_run_attributes(childText, 25, &startOffset, &endOffset); |
|
730 g_assert_cmpint(startOffset, ==, 25); |
|
731 g_assert_cmpint(endOffset, ==, 30); |
|
732 g_assert(atkAttributeSetAreEqual(set2, NULL)); |
|
733 |
|
734 set3 = atk_text_get_default_attributes(childText); |
|
735 g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_JUSTIFICATION, "center")); |
|
736 atk_attribute_set_free(set1); |
|
737 atk_attribute_set_free(set2); |
|
738 atk_attribute_set_free(set3); |
|
739 } |
|
740 |
|
741 int main(int argc, char** argv) |
|
742 { |
|
743 g_thread_init(NULL); |
|
744 gtk_test_init(&argc, &argv, NULL); |
|
745 |
|
746 g_test_bug_base("https://bugs.webkit.org/"); |
|
747 g_test_add_func("/webkit/atk/get_text_at_offset", test_webkit_atk_get_text_at_offset); |
|
748 g_test_add_func("/webkit/atk/get_text_at_offset_forms", test_webkit_atk_get_text_at_offset_forms); |
|
749 g_test_add_func("/webkit/atk/get_text_at_offset_newlines", test_webkit_atk_get_text_at_offset_newlines); |
|
750 g_test_add_func("/webkit/atk/get_text_at_offset_textarea", test_webkit_atk_get_text_at_offset_textarea); |
|
751 g_test_add_func("/webkit/atk/get_text_at_offset_text_input", test_webkit_atk_get_text_at_offset_text_input); |
|
752 g_test_add_func("/webkit/atk/getTextInParagraphAndBodySimple", testWebkitAtkGetTextInParagraphAndBodySimple); |
|
753 g_test_add_func("/webkit/atk/getTextInParagraphAndBodyModerate", testWebkitAtkGetTextInParagraphAndBodyModerate); |
|
754 g_test_add_func("/webkit/atk/getTextInTable", testWebkitAtkGetTextInTable); |
|
755 g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable); |
|
756 g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes); |
|
757 return g_test_run (); |
|
758 } |
|
759 |
|
760 #else |
|
761 int main(int argc, char** argv) |
|
762 { |
|
763 g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now."); |
|
764 return 0; |
|
765 } |
|
766 |
|
767 #endif |